[tz] [PATCH 1/2] zdump: remove unportable assumption about sscanf and overflow
Paul Eggert
eggert at cs.ucla.edu
Mon Oct 21 05:43:42 UTC 2013
* zdump.c (strtoimax) [!INTMAX_MAX]: Define like private.h does.
(SCNdMAX): Remove; no longer used.
(main): Use strtoimax, not sscanf with SCNdMAX, as strtoimax has
well-defined behavior when the input number is out of numeric range.
---
zdump.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/zdump.c b/zdump.c
index 2a9860c..209b79d 100644
--- a/zdump.c
+++ b/zdump.c
@@ -59,6 +59,7 @@ typedef int int_fast32_t;
#ifndef INTMAX_MAX
# if defined LLONG_MAX || defined __LONG_LONG_MAX__
typedef long long intmax_t;
+# define strtoimax strtoll
# define PRIdMAX "lld"
# ifdef LLONG_MAX
# define INTMAX_MAX LLONG_MAX
@@ -67,13 +68,11 @@ typedef long long intmax_t;
# endif
# else
typedef long intmax_t;
+# define strtoimax strtol
# define PRIdMAX "ld"
# define INTMAX_MAX LONG_MAX
# endif
#endif
-#ifndef SCNdMAX
-# define SCNdMAX PRIdMAX
-#endif
#ifndef ZDUMP_LO_YEAR
@@ -368,16 +367,19 @@ main(int argc, char *argv[])
if (vflag | Vflag) {
intmax_t lo;
intmax_t hi;
- char dummy;
+ char *loend, *hiend;
register intmax_t cutloyear = ZDUMP_LO_YEAR;
register intmax_t cuthiyear = ZDUMP_HI_YEAR;
if (cutarg != NULL) {
- if (sscanf(cutarg, "%"SCNdMAX"%c", &hi, &dummy) == 1) {
+ lo = strtoimax(cutarg, &loend, 10);
+ if (cutarg != loend && !*loend) {
+ hi = lo;
+ cuthiyear = hi;
+ } else if (cutarg != loend && *loend == ','
+ && (hi = strtoimax(loend + 1, &hiend, 10),
+ loend + 1 != hiend && !*hiend)) {
+ cutloyear = lo;
cuthiyear = hi;
- } else if (sscanf(cutarg, "%"SCNdMAX",%"SCNdMAX"%c",
- &lo, &hi, &dummy) == 2) {
- cutloyear = lo;
- cuthiyear = hi;
} else {
(void) fprintf(stderr, _("%s: wild -c argument %s\n"),
progname, cutarg);
@@ -389,14 +391,17 @@ main(int argc, char *argv[])
cuthitime = yeartot(cuthiyear);
}
if (cuttimes != NULL) {
- if (sscanf(cuttimes, "%"SCNdMAX"%c", &hi, &dummy) == 1) {
+ lo = strtoimax(cuttimes, &loend, 10);
+ if (cuttimes != loend && !*loend) {
+ hi = lo;
if (hi < cuthitime) {
if (hi < absolute_min_time)
hi = absolute_min_time;
cuthitime = hi;
}
- } else if (sscanf(cuttimes, "%"SCNdMAX",%"SCNdMAX"%c",
- &lo, &hi, &dummy) == 2) {
+ } else if (cuttimes != loend && *loend == ','
+ && (hi = strtoimax(loend + 1, &hiend, 10),
+ loend + 1 != hiend && !*hiend)) {
if (cutlotime < lo) {
if (absolute_max_time < lo)
lo = absolute_max_time;
--
1.8.3.2
More information about the tz
mailing list