+2025-03-21 Bruno Haible <bruno@clisp.org>
+
+ parse-duration: Work around an strtoul() misfeature.
+ * lib/parse-duration.c (str_const_to_ul): Reject a + or - sign between
+ the optional whitespace and the digits.
+ * tests/test-parse-duration.sh: Add some tests with expected failure.
+ * tests/test-parse-duration.c (main): Fix usage message.
+
2025-03-21 Bruno Haible <bruno@clisp.org>
mountlist: Add specification comment in .h file.
#undef MAX_DURATION
#define MAX_DURATION TYPE_MAXIMUM(time_t)
-/* Wrapper around strtoul that does not require a cast. */
+/* Wrapper around strtoul that does not allow a sign. */
static unsigned long
str_const_to_ul (cch_t * str, cch_t ** ppz, int base)
{
- return strtoul (str, (char **)ppz, base);
+ cch_t * orig_str = str;
+ while (isspace ((unsigned char) *str))
+ str++;
+ if (isdigit ((unsigned char) *str))
+ {
+ unsigned long ret = strtoul (str, (char **)ppz, base);
+ if (*ppz == str)
+ *ppz = orig_str;
+ return ret;
+ }
+ else
+ {
+ *ppz = orig_str;
+ return 0;
+ }
}
/* Wrapper around strtol that does not require a cast. */
{
if (--argc <= 0)
{
- fprintf (stderr, "USAGE: %s <time-spec> [...]", argv[0]);
+ fprintf (stderr, "USAGE: %s <time-spec> [...]\n", argv[0]);
return 1;
}
trap 'rm -rf "${tmp}"' EXIT
tmpf="${tmp}/tests.txt"
+# Tests where we expect success.
cat > "${tmpf}" <<- _EOF_
1 Y 2 M 3 W 4 d 5 h 6 m 7 s
P 00010225 T 05:06:07
test $v -eq 38898367 || die $v is not 38898367
done
exec 3>&-
+
+# Tests where we expect failure.
+cat > "${tmpf}" <<- _EOF_
+ T-00302
+ T-0:3:2
+ T-0 H 3 M 2 S
+ P+04 Y 03 M 02 D
+ P04 Y +03 M 02 D
+ P04 Y 03 M +02 D
+ _EOF_
+
+fail=0
+exec 3< "${tmpf}"
+while read line <&3
+do
+ if ${CHECKER} ${exe} "${line}"; then
+ echo "Succeeded: ${exe} '${line}'" 1>&2
+ fail=1
+ fi
+done
+exec 3>&-
+
+exit $fail