From owner-svn-src-head@freebsd.org Sun Jan 12 20:25:12 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id A00911E9647; Sun, 12 Jan 2020 20:25:12 +0000 (UTC) (envelope-from gad@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47wpB03ht0z4nCV; Sun, 12 Jan 2020 20:25:12 +0000 (UTC) (envelope-from gad@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7A2A521323; Sun, 12 Jan 2020 20:25:12 +0000 (UTC) (envelope-from gad@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 00CKPCk4071373; Sun, 12 Jan 2020 20:25:12 GMT (envelope-from gad@FreeBSD.org) Received: (from gad@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 00CKPBSW071370; Sun, 12 Jan 2020 20:25:11 GMT (envelope-from gad@FreeBSD.org) Message-Id: <202001122025.00CKPBSW071370@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: gad set sender to gad@FreeBSD.org using -f From: Garance A Drosehn Date: Sun, 12 Jan 2020 20:25:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356666 - in head/usr.bin: factor primes X-SVN-Group: head X-SVN-Commit-Author: gad X-SVN-Commit-Paths: in head/usr.bin: factor primes X-SVN-Commit-Revision: 356666 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Jan 2020 20:25:12 -0000 Author: gad Date: Sun Jan 12 20:25:11 2020 New Revision: 356666 URL: https://svnweb.freebsd.org/changeset/base/356666 Log: Fix the way 'factor' behaves when using OpenSSL to match the description of how it works when not compiled with OpenSSL. Also, allow users to specify a hexadecimal number by using a prefix of '0x'. Before this, users could only specify a hexadecimal value if that value included a hex digit ('a'-'f') in the value. PR: 243136 Submitted by: Steve Kargl Reviewed by: gad MFC after: 3 weeks Modified: head/usr.bin/factor/factor.6 head/usr.bin/factor/factor.c head/usr.bin/primes/primes.c Modified: head/usr.bin/factor/factor.6 ============================================================================== --- head/usr.bin/factor/factor.6 Sun Jan 12 20:19:00 2020 (r356665) +++ head/usr.bin/factor/factor.6 Sun Jan 12 20:25:11 2020 (r356666) @@ -36,7 +36,7 @@ .\" .\" chongo /\oo/\ .\" -.Dd October 10, 2002 +.Dd January 12, 2020 .Dt FACTOR 6 .Os .Sh NAME @@ -67,11 +67,22 @@ When .Nm is invoked with no arguments, .Nm -reads numbers, one per line, from standard input, until end of file or error. +reads numbers, one per line, from standard input until end of file or 0 +is entered or an error occurs. Leading white-space and empty lines are ignored. +.Pp Numbers may be preceded by a single .Ql + . +Numbers can be either decimal or hexadecimal strings where the longest +leading substring is used. Numbers are terminated by a non-digit character (such as a newline). +If the string contains only decimal digits, it is treated as a +decimal representation for a number. +A hexadecimal string can contain an optional +.Em 0x +or +.Em 0X +prefix. After a number is read, it is factored. .Pp The @@ -89,7 +100,7 @@ The value must not be greater than the maximum. The default and maximum value of .Ar stop -is 3825123056546413050. +is 18446744073709551615. .Pp When the .Nm primes Modified: head/usr.bin/factor/factor.c ============================================================================== --- head/usr.bin/factor/factor.c Sun Jan 12 20:19:00 2020 (r356665) +++ head/usr.bin/factor/factor.c Sun Jan 12 20:25:11 2020 (r356666) @@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -97,15 +98,16 @@ typedef u_long BN_ULONG; #define BN_is_one(v) (*(v) == 1) #define BN_mod_word(a, b) (*(a) % (b)) -static int BN_dec2bn(BIGNUM **a, const char *str); -static int BN_hex2bn(BIGNUM **a, const char *str); +static int BN_dec2bn(BIGNUM **, const char *); +static int BN_hex2bn(BIGNUM **, const char *); static BN_ULONG BN_div_word(BIGNUM *, BN_ULONG); static void BN_print_fp(FILE *, const BIGNUM *); #endif static void BN_print_dec_fp(FILE *, const BIGNUM *); - +static void convert_str2bn(BIGNUM **, char *); +static bool is_hex_str(char *); static void pr_fact(BIGNUM *); /* print factors of a value */ static void pr_print(BIGNUM *); /* print a prime */ static void usage(void); @@ -148,21 +150,13 @@ main(int argc, char *argv[]) for (p = buf; isblank(*p); ++p); if (*p == '\n' || *p == '\0') continue; - if (*p == '-') - errx(1, "negative numbers aren't permitted."); - if (BN_dec2bn(&val, buf) == 0 && - BN_hex2bn(&val, buf) == 0) - errx(1, "%s: illegal numeric format.", buf); + convert_str2bn(&val, p); pr_fact(val); } /* Factor the arguments. */ else - for (; *argv != NULL; ++argv) { - if (argv[0][0] == '-') - errx(1, "negative numbers aren't permitted."); - if (BN_dec2bn(&val, argv[0]) == 0 && - BN_hex2bn(&val, argv[0]) == 0) - errx(1, "%s: illegal numeric format.", argv[0]); + for (p = *argv; p != NULL; p = *++argv) { + convert_str2bn(&val, p); pr_fact(val); } exit(0); @@ -346,7 +340,7 @@ BN_dec2bn(BIGNUM **a, const char *str) errno = 0; **a = strtoul(str, &p, 10); - return (errno == 0 && (*p == '\n' || *p == '\0')); + return (errno == 0 ? 1 : 0); /* OpenSSL returns 0 on error! */ } static int @@ -356,7 +350,7 @@ BN_hex2bn(BIGNUM **a, const char *str) errno = 0; **a = strtoul(str, &p, 16); - return (errno == 0 && (*p == '\n' || *p == '\0')); + return (errno == 0 ? 1 : 0); /* OpenSSL returns 0 on error! */ } static BN_ULONG @@ -370,3 +364,46 @@ BN_div_word(BIGNUM *a, BN_ULONG b) } #endif + +/* + * Scan the string from left-to-right to see if the longest substring + * is a valid hexadecimal number. + */ +static bool +is_hex_str(char *str) +{ + char c, *p; + bool saw_hex = false; + + for (p = str; *p; p++) { + if (isdigit(*p)) + continue; + c = tolower(*p); + if (c >= 'a' && c <= 'f') { + saw_hex = true; + continue; + } + break; /* Not a hexadecimal digit. */ + } + return saw_hex; +} + +/* Convert string pointed to by *str to a bignum. */ +static void +convert_str2bn(BIGNUM **val, char *p) +{ + int n = 0; + + if (*p == '+') p++; + if (*p == '-') + errx(1, "negative numbers aren't permitted."); + if (*p == '0') { + p++; + if (*p == 'x' || *p == 'X') + n = BN_hex2bn(val, ++p); + } else { + n = is_hex_str(p) ? BN_hex2bn(val, p) : BN_dec2bn(val, p); + } + if (n == 0) + errx(1, "%s: illegal numeric format.", p); +} Modified: head/usr.bin/primes/primes.c ============================================================================== --- head/usr.bin/primes/primes.c Sun Jan 12 20:19:00 2020 (r356665) +++ head/usr.bin/primes/primes.c Sun Jan 12 20:25:11 2020 (r356666) @@ -55,8 +55,8 @@ static const char rcsid[] = * primes [-h] [start [stop]] * * Print primes >= start and < stop. If stop is omitted, - * the value 4294967295 (2^32-1) is assumed. If start is - * omitted, start is read from standard input. + * the value 18446744073709551615 (2^64-1) is assumed. If + * start is omitted, start is read from standard input. * * validation check: there are 664579 primes between 0 and 10^7 */