return 0;
}
+/* Print NUMBER followed by EOLBYTE to standard output.
+ Return false on failure, true on success. */
+static bool
+print_number (unsigned long int number, char eolbyte)
+{
+ char buf[INT_BUFSIZE_BOUND (unsigned long int)];
+ char *p = buf + INT_STRLEN_BOUND (unsigned long int);
+ *p = eolbyte;
+ do
+ *--p = '0' + number % 10;
+ while ((number /= 10) != 0);
+ idx_t len = buf + sizeof buf - p;
+ return fwrite (p, 1, len, stdout) == len;
+}
+
/* Output N_LINES of numbers to stdout, from PERMUTATION array.
PERMUTATION must have at least N_LINES elements. */
static int
for (size_t i = 0; i < n_lines; i++)
{
unsigned long int n = lo_input + permutation[i];
- char buf[INT_BUFSIZE_BOUND (uintmax_t)];
- if (fputs (umaxtostr (n, buf), stdout) < 0
- || fputc (eolbyte, stdout) < 0)
+ if (! print_number (n, eolbyte))
return -1;
}
for (size_t i = 0; i < count; i++)
{
unsigned long int j = lo_input + randint_choose (s, range);
- char buf[INT_BUFSIZE_BOUND (uintmax_t)];
- if (fputs (umaxtostr (j, buf), stdout) < 0
- || fputc (eolbyte, stdout) < 0)
+ if (! print_number (j, eolbyte))
return -1;
}
c=$(wc -l < exp) || framework_failure_
test "$c" -eq 3 || { fail=1; echo "Multiple -n failed">&2 ; }
+# Test that the conversion from integer to string doesn't write past a buffer.
+# Note that the value is too large for shell arithmetic.
+v=$ULONG_MAX
+while :; do
+ v=$(echo $v | sed 's/^0/1/')
+ test -z "$v" && break
+ echo $v > exp
+ shuf -i $v-$v > out || fail=1
+ compare exp out || fail=1
+ v=$(echo $v | cut -b2-)
+done
+
# Test error conditions
# -i and -e must not be used together