From 820db14f26ad8d203f6c3de6b51ff7bc2ec3476f Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 26 Jan 2017 15:37:12 -0500 Subject: Fix bug in strftime when format argument is an unterminated field string. --- ChangeLog | 5 +++++ builtin.c | 14 +++++++++++--- test/ChangeLog | 5 +++++ test/Makefile.am | 5 ++++- test/Makefile.in | 10 +++++++++- test/Maketests | 5 +++++ test/strftfld.awk | 3 +++ test/strftfld.in | 1 + test/strftfld.ok | 1 + 9 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 test/strftfld.awk create mode 100644 test/strftfld.in create mode 100644 test/strftfld.ok diff --git a/ChangeLog b/ChangeLog index 12f0e5ca..6bc1b339 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-01-26 Andrew J. Schorr + + * builtin.c (do_strftime): If format argument is passed, we need + to terminate it in case it's a field variable. + 2017-01-26 Andrew J. Schorr * node.c (r_format_val): Before we free s->stptr, make sure that it diff --git a/builtin.c b/builtin.c index f71d71dd..0c6cbc01 100644 --- a/builtin.c +++ b/builtin.c @@ -1907,6 +1907,7 @@ do_strftime(int nargs) int do_gmt; NODE *val = NULL; NODE *sub = NULL; + char save; static const time_t time_t_min = TYPE_MINIMUM(time_t); static const time_t time_t_max = TYPE_MAXIMUM(time_t); @@ -1980,6 +1981,8 @@ do_strftime(int nargs) DEREF(t1); return make_string("", 0); } + save = format[formatlen]; + t1->stptr[formatlen] = '\0'; } if (do_gmt) @@ -1987,8 +1990,10 @@ do_strftime(int nargs) else tm = localtime(& fclock); - if (tm == NULL) - return make_string("", 0); + if (tm == NULL) { + ret = make_string("", 0); + goto done; + } bufp = buf; bufsize = sizeof(buf); @@ -2014,8 +2019,11 @@ do_strftime(int nargs) ret = make_string(bufp, buflen); if (bufp != buf) efree(bufp); - if (t1) +done: + if (t1) { + t1->stptr[formatlen] = save; DEREF(t1); + } return ret; } diff --git a/test/ChangeLog b/test/ChangeLog index 1b2d4022..badd21b4 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2017-01-26 Andrew J. Schorr + + * Makefile.am (strftfld): New test. + * strftfld.awk, strftfld.in, strftfld.ok: New files. + 2017-01-15 Andrew J. Schorr * Makefile.am (concat5): New test. diff --git a/test/Makefile.am b/test/Makefile.am index cc9f6d12..1a86825e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1023,6 +1023,9 @@ EXTRA_DIST = \ strftime.awk \ strftlng.awk \ strftlng.ok \ + strftfld.awk \ + strftfld.in \ + strftfld.ok \ strnum1.awk \ strnum1.ok \ strnum2.awk \ @@ -1228,7 +1231,7 @@ GAWK_EXT_TESTS = \ rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \ rsstart2 rsstart3 rstest6 shadow shadowbuiltin \ sortfor sortfor2 sortu split_after_fpat \ - splitarg4 strftime \ + splitarg4 strftime strftfld \ strtonum strtonum1 switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \ symtab7 symtab8 symtab9 symtab10 \ typedregex1 typedregex2 typedregex3 typeof1 typeof2 typeof3 typeof4 \ diff --git a/test/Makefile.in b/test/Makefile.in index a45e26ef..23aedf89 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1281,6 +1281,9 @@ EXTRA_DIST = \ strftime.awk \ strftlng.awk \ strftlng.ok \ + strftfld.awk \ + strftfld.in \ + strftfld.ok \ strnum1.awk \ strnum1.ok \ strnum2.awk \ @@ -1485,7 +1488,7 @@ GAWK_EXT_TESTS = \ rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \ rsstart2 rsstart3 rstest6 shadow shadowbuiltin \ sortfor sortfor2 sortu split_after_fpat \ - splitarg4 strftime \ + splitarg4 strftime strftfld \ strtonum strtonum1 switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \ symtab7 symtab8 symtab9 symtab10 \ typedregex1 typedregex2 typedregex3 typeof1 typeof2 typeof3 typeof4 \ @@ -4243,6 +4246,11 @@ splitarg4: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +strftfld: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + strtonum: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index 5b91af61..82e496de 100644 --- a/test/Maketests +++ b/test/Maketests @@ -1442,6 +1442,11 @@ splitarg4: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +strftfld: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + strtonum: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/strftfld.awk b/test/strftfld.awk new file mode 100644 index 00000000..26f75a5a --- /dev/null +++ b/test/strftfld.awk @@ -0,0 +1,3 @@ +{ + print split(strftime($1), f) +} diff --git a/test/strftfld.in b/test/strftfld.in new file mode 100644 index 00000000..c1175143 --- /dev/null +++ b/test/strftfld.in @@ -0,0 +1 @@ +%F %T diff --git a/test/strftfld.ok b/test/strftfld.ok new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/test/strftfld.ok @@ -0,0 +1 @@ +1 -- cgit v1.2.3