OpenSSL breaks factor(6)
Steve Kargl
sgk at troutmask.apl.washington.edu
Sun Dec 29 07:29:09 UTC 2019
On Sat, Dec 28, 2019 at 11:17:31PM -0800, Steve Kargl wrote:
> On Sun, Dec 29, 2019 at 01:34:28AM -0500, Garance A Drosehn wrote:
> > On 29 Dec 2019, at 0:10, Steve Kargl wrote:
> >
> > > On Sat, Dec 28, 2019 at 10:46:52PM -0500, Garance A Drosehn wrote:
> > >>
> > >> What if the user wants to factor a hexadecimal value which does not
> > >> happen to include [a...f]?
> > >>
> > >> How about recognizing a prefix of '0x' as a way to indicate the value
> > >> is hexadecimal?
Here you go. '0x' support is undocumented.
Index: usr.bin/factor/factor.6
===================================================================
--- usr.bin/factor/factor.6 (revision 355983)
+++ usr.bin/factor/factor.6 (working copy)
@@ -36,7 +36,7 @@
.\"
.\" chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
.\"
-.Dd October 10, 2002
+.Dd December 27, 2019
.Dt FACTOR 6
.Os
.Sh NAME
@@ -67,11 +67,20 @@
.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.
Numbers may be preceded by a single
.Ql + .
Numbers are terminated by a non-digit character (such as a newline).
+Numbers can be either decimal or hexadecimal strings.
+If the string contains only decimal digits, it is treated as a
+decimal representation for a number.
+A hexadecimal string should not contain a
+.Em 0x
+or
+.Em 0X
+prefix.
After a number is read, it is factored.
.Pp
The
@@ -89,7 +98,7 @@
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
Index: usr.bin/factor/factor.c
===================================================================
--- usr.bin/factor/factor.c (revision 355983)
+++ usr.bin/factor/factor.c (working copy)
@@ -71,6 +71,7 @@
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -104,6 +105,7 @@
#endif
+static bool contains_hex_alpha_digits(char *str);
static void BN_print_dec_fp(FILE *, const BIGNUM *);
static void pr_fact(BIGNUM *); /* print factors of a value */
@@ -148,21 +150,37 @@
for (p = buf; isblank(*p); ++p);
if (*p == '\n' || *p == '\0')
continue;
+ if (*p == '+') p++;
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);
+ if (*p == '0') {
+ p++;
+ if (*p == 'x' || *p == 'X')
+ ch = BN_hex2bn(&val, ++p);
+ } else {
+ ch = contains_hex_alpha_digits(p) ?
+ BN_hex2bn(&val, p) : BN_dec2bn(&val, p);
+ }
+ if (ch == 0)
+ errx(1, "%s: illegal numeric format.", p);
pr_fact(val);
}
/* Factor the arguments. */
else
- for (; *argv != NULL; ++argv) {
- if (argv[0][0] == '-')
+ for (p = *argv; p != NULL; p = *++argv) {
+ if (*p == '+') p++;
+ if (*p == '-')
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]);
+ if (*p == '0') {
+ p++;
+ if (*p == 'x' || *p == 'X')
+ ch = BN_hex2bn(&val, ++p);
+ } else {
+ ch = contains_hex_alpha_digits(p) ?
+ BN_hex2bn(&val, p) : BN_dec2bn(&val, p);
+ }
+ if (ch == 0)
+ errx(1, "%s: illegal numeric format.", p);
pr_fact(val);
}
exit(0);
@@ -346,7 +364,7 @@
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 +374,7 @@
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 +388,20 @@
}
#endif
+
+/*
+ * Check if the string contains one of 'abcdef' from the set of
+ * hexadecimal digits.
+ */
+static bool
+contains_hex_alpha_digits(char *str)
+{
+ char c, *p;
+
+ for (p = str; *p; p++) {
+ c = tolower(*p);
+ if (c >= 'a' && c <= 'f')
+ return true;
+ }
+ return false;
+}
Index: usr.bin/primes/primes.c
===================================================================
--- usr.bin/primes/primes.c (revision 355983)
+++ usr.bin/primes/primes.c (working copy)
@@ -55,7 +55,7 @@
* primes [-h] [start [stop]]
*
* Print primes >= start and < stop. If stop is omitted,
- * the value 4294967295 (2^32-1) is assumed. If start is
+ * 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
--
Steve
More information about the freebsd-current
mailing list