From cedd0829b0075533986fce1e699bc6ae511a891e Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 4 Jul 2016 11:20:07 -0400 Subject: Unify force_string handling of CONVFMT and OFMT. --- builtin.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 92ac9e49..a01018e3 100644 --- a/builtin.c +++ b/builtin.c @@ -2200,12 +2200,7 @@ do_print(int nargs, int redirtype) DEREF(args_array[i]); fatal(_("attempt to use array `%s' in a scalar context"), array_vname(tmp)); } - - if (tmp->type == Node_typedregex) - args_array[i] = force_string(tmp); - else if (!((tmp->flags & STRCUR) != 0 - && (tmp->stfmt == STFMT_UNUSED || tmp->stfmt == OFMTidx))) - args_array[i] = format_val(OFMT, OFMTidx, tmp); + args_array[i] = force_string_ofmt(tmp); } if (redir_exp != NULL) { -- cgit v1.2.3 From ce342a04922797cb53557178c54d32c4efafda16 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Wed, 6 Jul 2016 21:31:22 -0400 Subject: Document string termination in header files and remove no-longer-needed string termination logic in various places. --- builtin.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index a01018e3..a21df18e 100644 --- a/builtin.c +++ b/builtin.c @@ -2035,16 +2035,12 @@ do_mktime(int nargs) int month, day, hour, minute, second, count; int dst = -1; /* default is unknown */ time_t then_stamp; - char save; t1 = POP_SCALAR(); if (do_lint && (fixtype(t1)->flags & STRING) == 0) lintwarn(_("mktime: received non-string argument")); t1 = force_string(t1); - save = t1->stptr[t1->stlen]; - t1->stptr[t1->stlen] = '\0'; - count = sscanf(t1->stptr, "%ld %d %d %d %d %d %d", & year, & month, & day, & hour, & minute, & second, @@ -2058,7 +2054,6 @@ do_mktime(int nargs) || (month < 1 || month > 12) )) lintwarn(_("mktime: at least one of the values is out of the default range")); - t1->stptr[t1->stlen] = save; DEREF(t1); if (count < 6 @@ -2088,7 +2083,6 @@ do_system(int nargs) NODE *tmp; AWKNUM ret = 0; /* floating point on purpose, compat Unix awk */ char *cmd; - char save; int status; if (do_sandbox) @@ -2101,10 +2095,6 @@ do_system(int nargs) cmd = force_string(tmp)->stptr; if (cmd && *cmd) { - /* insure arg to system is zero-terminated */ - save = cmd[tmp->stlen]; - cmd[tmp->stlen] = '\0'; - os_restore_mode(fileno(stdin)); #ifdef SIGPIPE signal(SIGPIPE, SIG_DFL); @@ -2148,7 +2138,6 @@ do_system(int nargs) signal(SIGPIPE, SIG_IGN); #endif - cmd[tmp->stlen] = save; } DEREF(tmp); return make_number((AWKNUM) ret); @@ -3632,6 +3621,11 @@ nondec2awknum(char *str, size_t len, char **endptr) *endptr = str; } else { decimal: + /* + * Terminating is probably unnecessary, since the caller always + * passes a string ending with '\0' or white space, but it + * seems safest to leave this to avoid future problems. + */ save = str[len]; str[len] = '\0'; retval = strtod(str, endptr); -- cgit v1.2.3 From eb261daff5e9a96f294cd806d1fd3e68f06fdbaa Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Wed, 6 Jul 2016 22:29:58 -0400 Subject: Modify MAYBE_NUM usage and typeof function to return "strnum" only for actual numeric strings. --- builtin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index a21df18e..032f0ec7 100644 --- a/builtin.c +++ b/builtin.c @@ -3951,14 +3951,14 @@ do_typeof(int nargs) break; case Node_val: case Node_var: - switch (arg->flags & (STRING|NUMBER|MAYBE_NUM)) { + switch (fixtype(arg)->flags & (STRING|NUMBER|MAYBE_NUM)) { case STRING: res = "string"; break; case NUMBER: res = "number"; break; - case STRING|MAYBE_NUM: + case NUMBER|MAYBE_NUM: res = "strnum"; break; case NUMBER|STRING: -- cgit v1.2.3 From c86137f472fdf876c2c223c8d99f673f477b7554 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Fri, 8 Jul 2016 15:26:00 -0400 Subject: Optimization: support unterminated field strings inside gawk, but make terminated copies for the API. --- builtin.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 032f0ec7..da3c252f 100644 --- a/builtin.c +++ b/builtin.c @@ -2035,12 +2035,16 @@ do_mktime(int nargs) int month, day, hour, minute, second, count; int dst = -1; /* default is unknown */ time_t then_stamp; + char save; t1 = POP_SCALAR(); if (do_lint && (fixtype(t1)->flags & STRING) == 0) lintwarn(_("mktime: received non-string argument")); t1 = force_string(t1); + save = t1->stptr[t1->stlen]; + t1->stptr[t1->stlen] = '\0'; + count = sscanf(t1->stptr, "%ld %d %d %d %d %d %d", & year, & month, & day, & hour, & minute, & second, @@ -2054,6 +2058,7 @@ do_mktime(int nargs) || (month < 1 || month > 12) )) lintwarn(_("mktime: at least one of the values is out of the default range")); + t1->stptr[t1->stlen] = save; DEREF(t1); if (count < 6 @@ -2083,6 +2088,7 @@ do_system(int nargs) NODE *tmp; AWKNUM ret = 0; /* floating point on purpose, compat Unix awk */ char *cmd; + char save; int status; if (do_sandbox) @@ -2095,6 +2101,10 @@ do_system(int nargs) cmd = force_string(tmp)->stptr; if (cmd && *cmd) { + /* insure arg to system is zero-terminated */ + save = cmd[tmp->stlen]; + cmd[tmp->stlen] = '\0'; + os_restore_mode(fileno(stdin)); #ifdef SIGPIPE signal(SIGPIPE, SIG_DFL); @@ -2138,6 +2148,7 @@ do_system(int nargs) signal(SIGPIPE, SIG_IGN); #endif + cmd[tmp->stlen] = save; } DEREF(tmp); return make_number((AWKNUM) ret); @@ -3621,11 +3632,6 @@ nondec2awknum(char *str, size_t len, char **endptr) *endptr = str; } else { decimal: - /* - * Terminating is probably unnecessary, since the caller always - * passes a string ending with '\0' or white space, but it - * seems safest to leave this to avoid future problems. - */ save = str[len]; str[len] = '\0'; retval = strtod(str, endptr); -- cgit v1.2.3 From cc04afb329cea035d0d9b67cd3b677e06b2f3996 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sat, 12 Nov 2016 19:12:13 +0200 Subject: Further code improvements and doc changes as diff until merge. --- builtin.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 95e7f7dc..e6cfee3b 100644 --- a/builtin.c +++ b/builtin.c @@ -2647,7 +2647,7 @@ do_match(int nargs) } it = make_string(start, len); - it->flags |= MAYBE_NUM; /* user input */ + it->flags |= USER_INPUT; sub = make_number((AWKNUM) (ii)); lhs = assoc_lookup(dest, sub); @@ -3950,14 +3950,14 @@ do_typeof(int nargs) break; case Node_val: case Node_var: - switch (fixtype(arg)->flags & (STRING|NUMBER|MAYBE_NUM)) { + switch (fixtype(arg)->flags & (STRING|NUMBER|USER_INPUT)) { case STRING: res = "string"; break; case NUMBER: res = "number"; break; - case NUMBER|MAYBE_NUM: + case NUMBER|USER_INPUT: res = "strnum"; break; case NUMBER|STRING: -- cgit v1.2.3 From e8b0cf14d975304166c58a2d04a2943ab821367a Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 18 Nov 2016 06:00:17 +0200 Subject: Audit use of stptr for NUL termination. Update doc before merge to master. --- builtin.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index e6cfee3b..9a45e10f 100644 --- a/builtin.c +++ b/builtin.c @@ -135,7 +135,7 @@ wrerror: /* otherwise die verbosely */ - if ((rp != NULL) ? is_non_fatal_redirect(rp->value) : is_non_fatal_std(fp)) + if ((rp != NULL) ? is_non_fatal_redirect(rp->value, strlen(rp->value)) : is_non_fatal_std(fp)) update_ERRNO_int(errno); else fatal(_("%s to \"%s\" failed (%s)"), from, @@ -194,6 +194,7 @@ do_fflush(int nargs) FILE *fp; int status = 0; const char *file; + int len; /* * November, 2012. @@ -220,6 +221,7 @@ do_fflush(int nargs) tmp = POP_STRING(); file = tmp->stptr; + len = tmp->stlen; /* fflush("") */ if (tmp->stlen == 0) { @@ -234,11 +236,11 @@ do_fflush(int nargs) if (rp != NULL) { if ((rp->flag & (RED_WRITE|RED_APPEND)) == 0) { if ((rp->flag & RED_PIPE) != 0) - warning(_("fflush: cannot flush: pipe `%s' opened for reading, not writing"), - file); + warning(_("fflush: cannot flush: pipe `%.*s' opened for reading, not writing"), + len, file); else - warning(_("fflush: cannot flush: file `%s' opened for reading, not writing"), - file); + warning(_("fflush: cannot flush: file `%.*s' opened for reading, not writing"), + len, file); DEREF(tmp); return make_number((AWKNUM) status); } @@ -246,13 +248,13 @@ do_fflush(int nargs) if (fp != NULL) status = rp->output.gawk_fflush(fp, rp->output.opaque); else if ((rp->flag & RED_TWOWAY) != 0) - warning(_("fflush: cannot flush: two-way pipe `%s' has closed write end"), - file); + warning(_("fflush: cannot flush: two-way pipe `%.*s' has closed write end"), + len, file); } else if ((fp = stdfile(tmp->stptr, tmp->stlen)) != NULL) { status = fflush(fp); } else { status = -1; - warning(_("fflush: `%s' is not an open file, pipe or co-process"), file); + warning(_("fflush: `%.*s' is not an open file, pipe or co-process"), len, file); } DEREF(tmp); return make_number((AWKNUM) status); @@ -1685,7 +1687,7 @@ do_printf(int nargs, int redirtype) rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) { if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) { - if (is_non_fatal_redirect(redir_exp->stptr)) { + if (is_non_fatal_redirect(redir_exp->stptr, redir_exp->stlen)) { update_ERRNO_int(EBADF); return; } @@ -2169,7 +2171,7 @@ do_print(int nargs, int redirtype) rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) { if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) { - if (is_non_fatal_redirect(redir_exp->stptr)) { + if (is_non_fatal_redirect(redir_exp->stptr, redir_exp->stlen)) { update_ERRNO_int(EBADF); return; } @@ -2243,7 +2245,7 @@ do_print_rec(int nargs, int redirtype) rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) { if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) { - if (is_non_fatal_redirect(redir_exp->stptr)) { + if (is_non_fatal_redirect(redir_exp->stptr, redir_exp->stlen)) { update_ERRNO_int(EBADF); return; } @@ -3679,6 +3681,8 @@ localecategory_from_argument(NODE *t) char *category; int lc_cat = -1; + char save = t->stptr[t->stlen]; + t->stptr[t->stlen] = '\0'; category = t->stptr; /* binary search the table */ @@ -3697,6 +3701,7 @@ localecategory_from_argument(NODE *t) break; } } + t->stptr[t->stlen] = save; if (lc_cat == -1) /* not there */ fatal(_("dcgettext: `%s' is not a valid locale category"), category); @@ -3725,6 +3730,8 @@ do_dcgettext(int nargs) #if ENABLE_NLS && defined(LC_MESSAGES) && HAVE_DCGETTEXT int lc_cat; char *domain; + char save; + bool saved_end = false; if (nargs == 3) { /* third argument */ tmp = POP_STRING(); @@ -3736,6 +3743,9 @@ do_dcgettext(int nargs) if (nargs >= 2) { /* second argument */ t2 = POP_STRING(); domain = t2->stptr; + save = domain[t2->stlen]; + domain[t2->stlen] = '\0'; + saved_end = true; } else domain = TEXTDOMAIN; #else @@ -3754,6 +3764,8 @@ do_dcgettext(int nargs) #if ENABLE_NLS && defined(LC_MESSAGES) && HAVE_DCGETTEXT the_result = dcgettext(domain, string, lc_cat); + if (saved_end) + domain[t2->stlen] = save; if (t2 != NULL) DEREF(t2); #else @@ -3776,6 +3788,8 @@ do_dcngettext(int nargs) #if ENABLE_NLS && defined(LC_MESSAGES) && HAVE_DCGETTEXT int lc_cat; char *domain; + char save; + bool saved_end = false; if (nargs == 5) { /* fifth argument */ tmp = POP_STRING(); @@ -3788,6 +3802,9 @@ do_dcngettext(int nargs) if (nargs >= 4) { /* fourth argument */ t3 = POP_STRING(); domain = t3->stptr; + save = domain[t3->stlen]; + domain[t3->stlen] = '\0'; + saved_end = true; } else domain = TEXTDOMAIN; #else @@ -3814,6 +3831,8 @@ do_dcngettext(int nargs) #if ENABLE_NLS && defined(LC_MESSAGES) && HAVE_DCGETTEXT the_result = dcngettext(domain, string1, string2, number, lc_cat); + if (saved_end) + domain[t3->stlen] = save; if (t3 != NULL) DEREF(t3); #else @@ -3846,10 +3865,15 @@ do_bindtextdomain(int nargs) /* set defaults */ directory = NULL; domain = TEXTDOMAIN; + char save; + bool saved_end = false; if (nargs == 2) { /* second argument */ t2 = POP_STRING(); domain = (const char *) t2->stptr; + save = t2->stptr[t2->stlen]; + t2->stptr[t2->stlen] = '\0'; + saved_end = true; } /* first argument */ @@ -3860,6 +3884,8 @@ do_bindtextdomain(int nargs) the_result = bindtextdomain(domain, directory); DEREF(t1); + if (saved_end) + t2->stptr[t2->stlen] = save; if (t2 != NULL) DEREF(t2); -- cgit v1.2.3