summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog48
-rw-r--r--array.c2
-rw-r--r--awkgram.c18
-rw-r--r--awkgram.y18
-rw-r--r--builtin.c119
-rw-r--r--command.c10
-rw-r--r--command.y10
-rw-r--r--debug.c16
-rw-r--r--eval.c4
-rw-r--r--extension/ChangeLog7
-rw-r--r--extension/readfile.c4
-rw-r--r--extension/rwarray.c4
-rw-r--r--extension/rwarray0.c4
-rw-r--r--field.c4
-rw-r--r--gawkapi.h2
-rw-r--r--helpers/ChangeLog8
-rw-r--r--helpers/testdfa.c21
-rw-r--r--interpret.h7
-rw-r--r--io.c11
-rw-r--r--node.c14
-rw-r--r--old-extension/ChangeLog9
-rw-r--r--old-extension/bindarr.c2
-rw-r--r--old-extension/fileop.c2
-rw-r--r--profile.c9
-rw-r--r--re.c4
25 files changed, 209 insertions, 148 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c85bdea..14da32db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -47,6 +47,18 @@
Unrelated:
* builtin.c (call_sub): Fix for indirect gensub, 3 args now works.
+ Unrelated:
+
+ * builtin.c (do_sub): Improve some variable names for readability
+ and add / expand some comments.
+
+2015-04-14 Andrew J. Schorr <aschorr@telemetry-investments.com>
+ Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_sub): Make computations smarter; initial len
+ to malloc, test for final amount after all matches done and
+ need to copy in the final part of the original string.
+
2015-04-13 Arnold D. Robbins <arnold@skeeve.com>
* regcomp.c (analyze): Prevent malloc(0).
@@ -68,6 +80,15 @@
* Makefile.am (efence): Make this link again.
Thanks to Michal Jaegermann for pointing out the problem.
+2015-04-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awkgram.y (yyerror): Rationalize buffer size computations. Remove
+ old valgrind workarounds.
+ * debug.c (gprintf): Rationalize buffer size computations.
+ (serialize_subscript): Ditto.
+ * io.c (iop_finish): Rationalize buffer size computations.
+ * profile.c (pp_string): Correct space allocation computation.
+
2015-04-08 John E. Malmberg <wb8tyw@qsl.net>
* custom.h: VMS shares some code paths with ZOS_USS in
@@ -441,6 +462,33 @@
* profile.c (pprint): Be sure to set ip2 in all paths
through the code. Thanks to GCC 4.9 for the warning.
+2014-12-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_sub): Do not waste a byte at the end of a string.
+
+2014-12-14 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awkgram.y (yyerror): Do not waste a byte at the end of a string.
+ * builtin.c (do_match): Ditto.
+ * command.y (append_statement): Ditto.
+ * debug.c (gprintf, serialize): Ditto.
+ * field.c (set_FIELDWIDTHS): Ditto.
+ * io.c.c (grow_iop_buffer): Ditto.
+ * profile.c (pp_string, pp_group3): Ditto.
+
+2014-12-14 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * array.c (concat_exp): Do not waste a byte at the end of a string.
+ * awkgram.y (common_exp): Ditto.
+ * builtin.c (do_substr): Ditto.
+ * eval.c (set_OFS): Ditto.
+ * field.c (rebuild_record): Ditto.
+ * gawkapi.h (r_make_string): Ditto.
+ * interpret.h (r_interpret): Ditto for Op_assign_concat.
+ * node.c (r_format_val, r_dupnode, make_str_node, str2wstr, wstr2str):
+ Ditto.
+ * re.c (make_regexp): Ditto.
+
2014-12-20 Arnold D. Robbins <arnold@skeeve.com>
Enable non-fatal output on per-file or global basis,
diff --git a/array.c b/array.c
index f7993624..59428ba2 100644
--- a/array.c
+++ b/array.c
@@ -414,7 +414,7 @@ concat_exp(int nargs, bool do_subsep)
}
len += (nargs - 1) * subseplen;
- emalloc(str, char *, len + 2, "concat_exp");
+ emalloc(str, char *, len + 1, "concat_exp");
r = args_array[nargs];
memcpy(str, r->stptr, r->stlen);
diff --git a/awkgram.c b/awkgram.c
index 799570e5..23213da5 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -3399,7 +3399,7 @@ regular_print:
n1 = force_string(n1);
n2 = force_string(n2);
nlen = n1->stlen + n2->stlen;
- erealloc(n1->stptr, char *, nlen + 2, "constant fold");
+ erealloc(n1->stptr, char *, nlen + 1, "constant fold");
memcpy(n1->stptr + n1->stlen, n2->stptr, n2->stlen);
n1->stlen = nlen;
n1->stptr[nlen] = '\0';
@@ -4516,7 +4516,6 @@ yyerror(const char *m, ...)
char *buf;
int count;
static char end_of_file_line[] = "(END OF FILE)";
- char save;
print_included_from();
@@ -4544,24 +4543,15 @@ yyerror(const char *m, ...)
bp = thisline + strlen(thisline);
}
- /*
- * Saving and restoring *bp keeps valgrind happy,
- * since the guts of glibc uses strlen, even though
- * we're passing an explict precision. Sigh.
- *
- * 8/2003: We may not need this anymore.
- */
- save = *bp;
- *bp = '\0';
-
msg("%.*s", (int) (bp - thisline), thisline);
- *bp = save;
va_start(args, m);
if (mesg == NULL)
mesg = m;
- count = (bp - thisline) + strlen(mesg) + 2 + 1;
+ count = strlen(mesg) + 1;
+ if (lexptr != NULL)
+ count += (lexeme - thisline) + 2;
emalloc(buf, char *, count, "yyerror");
bp = buf;
diff --git a/awkgram.y b/awkgram.y
index db0cf8cd..ecfab022 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -1443,7 +1443,7 @@ common_exp
n1 = force_string(n1);
n2 = force_string(n2);
nlen = n1->stlen + n2->stlen;
- erealloc(n1->stptr, char *, nlen + 2, "constant fold");
+ erealloc(n1->stptr, char *, nlen + 1, "constant fold");
memcpy(n1->stptr + n1->stlen, n2->stptr, n2->stlen);
n1->stlen = nlen;
n1->stptr[nlen] = '\0';
@@ -2178,7 +2178,6 @@ yyerror(const char *m, ...)
char *buf;
int count;
static char end_of_file_line[] = "(END OF FILE)";
- char save;
print_included_from();
@@ -2206,24 +2205,15 @@ yyerror(const char *m, ...)
bp = thisline + strlen(thisline);
}
- /*
- * Saving and restoring *bp keeps valgrind happy,
- * since the guts of glibc uses strlen, even though
- * we're passing an explict precision. Sigh.
- *
- * 8/2003: We may not need this anymore.
- */
- save = *bp;
- *bp = '\0';
-
msg("%.*s", (int) (bp - thisline), thisline);
- *bp = save;
va_start(args, m);
if (mesg == NULL)
mesg = m;
- count = (bp - thisline) + strlen(mesg) + 2 + 1;
+ count = strlen(mesg) + 1;
+ if (lexptr != NULL)
+ count += (lexeme - thisline) + 2;
emalloc(buf, char *, count, "yyerror");
bp = buf;
diff --git a/builtin.c b/builtin.c
index 6bd97e56..a9733597 100644
--- a/builtin.c
+++ b/builtin.c
@@ -1847,7 +1847,7 @@ do_substr(int nargs)
* way to do things.
*/
memset(& mbs, 0, sizeof(mbs));
- emalloc(substr, char *, (length * gawk_mb_cur_max) + 2, "do_substr");
+ emalloc(substr, char *, (length * gawk_mb_cur_max) + 1, "do_substr");
wp = t1->wstptr + indx;
for (cp = substr; length > 0; length--) {
result = wcrtomb(cp, *wp, & mbs);
@@ -2597,7 +2597,7 @@ do_match(int nargs)
sprintf(buff, "%d", ii);
ilen = strlen(buff);
- amt = ilen + subseplen + strlen("length") + 2;
+ amt = ilen + subseplen + strlen("length") + 1;
if (oldamt == 0) {
emalloc(buf, char *, amt, "do_match");
@@ -2771,42 +2771,42 @@ do_sub(int nargs, unsigned int flags)
int ampersands;
int matches = 0;
Regexp *rp;
- NODE *s; /* subst. pattern */
- NODE *t; /* string to make sub. in; $0 if none given */
+ NODE *rep_node; /* replacement text */
+ NODE *target; /* string to make sub. in; $0 if none given */
NODE *tmp;
NODE **lhs = NULL;
long how_many = 1; /* one substitution for sub, also gensub default */
- int global;
+ bool global;
long current;
bool lastmatchnonzero;
char *mb_indices = NULL;
if ((flags & GENSUB) != 0) {
double d;
- NODE *t1;
+ NODE *glob_flag;
tmp = PEEK(3);
rp = re_update(tmp);
- t = POP_STRING(); /* original string */
+ target = POP_STRING(); /* original string */
- t1 = POP_SCALAR(); /* value of global flag */
- if ((t1->flags & (STRCUR|STRING)) != 0) {
- if (t1->stlen > 0 && (t1->stptr[0] == 'g' || t1->stptr[0] == 'G'))
+ glob_flag = POP_SCALAR(); /* value of global flag */
+ if ((glob_flag->flags & (STRCUR|STRING)) != 0) {
+ if (glob_flag->stlen > 0 && (glob_flag->stptr[0] == 'g' || glob_flag->stptr[0] == 'G'))
how_many = -1;
else {
- (void) force_number(t1);
- d = get_number_d(t1);
- if ((t1->flags & NUMCUR) != 0)
+ (void) force_number(glob_flag);
+ d = get_number_d(glob_flag);
+ if ((glob_flag->flags & NUMCUR) != 0)
goto set_how_many;
warning(_("gensub: third argument `%.*s' treated as 1"),
- (int) t1->stlen, t1->stptr);
+ (int) glob_flag->stlen, glob_flag->stptr);
how_many = 1;
}
} else {
- (void) force_number(t1);
- d = get_number_d(t1);
+ (void) force_number(glob_flag);
+ d = get_number_d(glob_flag);
set_how_many:
if (d < 1)
how_many = 1;
@@ -2817,10 +2817,8 @@ set_how_many:
if (d <= 0)
warning(_("gensub: third argument %g treated as 1"), d);
}
- DEREF(t1);
-
+ DEREF(glob_flag);
} else {
-
/* take care of regexp early, in case re_update is fatal */
tmp = PEEK(2);
@@ -2832,30 +2830,30 @@ set_how_many:
/* original string */
if ((flags & LITERAL) != 0)
- t = POP_STRING();
+ target = POP_STRING();
else {
lhs = POP_ADDRESS();
- t = force_string(*lhs);
+ target = force_string(*lhs);
}
}
global = (how_many == -1);
- s = POP_STRING(); /* replacement text */
+ rep_node = POP_STRING(); /* replacement text */
decr_sp(); /* regexp, already updated above */
/* do the search early to avoid work on non-match */
- if (research(rp, t->stptr, 0, t->stlen, RE_NEED_START) == -1 ||
- RESTART(rp, t->stptr) > t->stlen)
+ if (research(rp, target->stptr, 0, target->stlen, RE_NEED_START) == -1 ||
+ RESTART(rp, target->stptr) > target->stlen)
goto done;
- t->flags |= STRING;
+ target->flags |= STRING;
- text = t->stptr;
- textlen = t->stlen;
+ text = target->stptr;
+ textlen = target->stlen;
- repl = s->stptr;
- replend = repl + s->stlen;
+ repl = rep_node->stptr;
+ replend = repl + rep_node->stlen;
repllen = replend - repl;
ampersands = 0;
@@ -2873,6 +2871,7 @@ set_how_many:
index_multibyte_buffer(repl, mb_indices, repllen);
}
+ /* compute length of replacement string, number of ampersands */
for (scan = repl; scan < replend; scan++) {
if ((gawk_mb_cur_max == 1 || (repllen > 0 && mb_indices[scan - repl] == 1))
&& (*scan == '&')) {
@@ -2917,24 +2916,32 @@ set_how_many:
lastmatchnonzero = false;
- /* guesstimate how much room to allocate; +2 forces > 0 */
- buflen = textlen + (ampersands + 1) * repllen + 2;
- emalloc(buf, char *, buflen + 2, "do_sub");
+ /* guesstimate how much room to allocate; +1 forces > 0 */
+ buflen = textlen + (ampersands + 1) * repllen + 1;
+ emalloc(buf, char *, buflen + 1, "do_sub");
buf[buflen] = '\0';
- buf[buflen + 1] = '\0';
bp = buf;
for (current = 1;; current++) {
matches++;
- matchstart = t->stptr + RESTART(rp, t->stptr);
- matchend = t->stptr + REEND(rp, t->stptr);
+ matchstart = target->stptr + RESTART(rp, target->stptr);
+ matchend = target->stptr + REEND(rp, target->stptr);
/*
* create the result, copying in parts of the original
- * string
+ * string. note that length of replacement string can
+ * vary since ampersand is actual text of regexp match.
+ */
+
+ /*
+ * add 1 to len to handle "empty" case where
+ * matchend == matchstart and we force a match on a single
+ * char. Use 'matchend - text' instead of 'matchstart - text'
+ * because we may not actually make any substitution depending
+ * on the 'global' and 'how_many' values.
*/
- len = matchstart - text + repllen
- + ampersands * (matchend - matchstart);
+ len = matchend - text + repllen
+ + ampersands * (matchend - matchstart) + 1;
sofar = bp - buf;
while (buflen < (sofar + len + 1)) {
buflen *= 2;
@@ -2981,13 +2988,13 @@ set_how_many:
if (flags & GENSUB) { /* gensub, behave sanely */
if (isdigit((unsigned char) scan[1])) {
int dig = scan[1] - '0';
- if (dig < NUMSUBPATS(rp, t->stptr) && SUBPATSTART(rp, tp->stptr, dig) != -1) {
+ if (dig < NUMSUBPATS(rp, target->stptr) && SUBPATSTART(rp, tp->stptr, dig) != -1) {
char *start, *end;
- start = t->stptr
- + SUBPATSTART(rp, t->stptr, dig);
- end = t->stptr
- + SUBPATEND(rp, t->stptr, dig);
+ start = target->stptr
+ + SUBPATSTART(rp, target->stptr, dig);
+ end = target->stptr
+ + SUBPATEND(rp, target->stptr, dig);
for (cp = start; cp < end; cp++)
*bp++ = *cp;
@@ -3041,19 +3048,29 @@ set_how_many:
textlen = text + textlen - matchend;
text = matchend;
+#if 0
+ if (bp - buf > sofar + len)
+ fprintf(stderr, "debug: len = %zu, but used %ld\n", len, (long)((bp - buf) - (long)sofar));
+#endif
+
if ((current >= how_many && ! global)
|| ((long) textlen <= 0 && matchstart == matchend)
- || research(rp, t->stptr, text - t->stptr, textlen, RE_NEED_START) == -1)
+ || research(rp, target->stptr, text - target->stptr, textlen, RE_NEED_START) == -1)
break;
}
sofar = bp - buf;
- if (buflen - sofar - textlen - 1) {
- buflen = sofar + textlen + 2;
+ if (buflen < (sofar + textlen + 1)) {
+ buflen = sofar + textlen + 1;
erealloc(buf, char *, buflen, "do_sub");
bp = buf + sofar;
}
- for (scan = matchend; scan < text + textlen; scan++)
+ /*
+ * Note that text == matchend, since that assignment is made before
+ * exiting the 'for' loop above. Thus we copy in the rest of the
+ * original string.
+ */
+ for (scan = text; scan < text + textlen; scan++)
*bp++ = *scan;
*bp = '\0';
textlen = bp - buf;
@@ -3062,7 +3079,7 @@ set_how_many:
efree(mb_indices);
done:
- DEREF(s);
+ DEREF(rep_node);
if ((matches == 0 || (flags & LITERAL) != 0) && buf != NULL) {
efree(buf);
@@ -3072,18 +3089,18 @@ done:
if (flags & GENSUB) {
if (matches > 0) {
/* return the result string */
- DEREF(t);
+ DEREF(target);
assert(buf != NULL);
return make_str_node(buf, textlen, ALREADY_MALLOCED);
}
/* return the original string */
- return t;
+ return target;
}
/* For a string literal, must not change the original string. */
if ((flags & LITERAL) != 0)
- DEREF(t);
+ DEREF(target);
else if (matches > 0) {
unref(*lhs);
*lhs = make_str_node(buf, textlen, ALREADY_MALLOCED);
diff --git a/command.c b/command.c
index 04d5e5f3..b23b21c5 100644
--- a/command.c
+++ b/command.c
@@ -2515,7 +2515,7 @@ append_statement(CMDARG *stmt_list, char *stmt)
len += strlen(a->a_string) + 1; /* 1 for ',' */
len += EVALSIZE;
- emalloc(s, char *, (len + 2) * sizeof(char), "append_statement");
+ emalloc(s, char *, (len + 1) * sizeof(char), "append_statement");
arg = mk_cmdarg(D_string);
arg->a_string = s;
arg->a_count = len; /* kludge */
@@ -2542,7 +2542,7 @@ append_statement(CMDARG *stmt_list, char *stmt)
ssize = stmt_list->a_count;
if (len > ssize - slen) {
ssize = slen + len + EVALSIZE;
- erealloc(s, char *, (ssize + 2) * sizeof(char), "append_statement");
+ erealloc(s, char *, (ssize + 1) * sizeof(char), "append_statement");
stmt_list->a_string = s;
stmt_list->a_count = ssize;
}
@@ -2554,7 +2554,7 @@ append_statement(CMDARG *stmt_list, char *stmt)
}
if (stmt == end_EVAL)
- erealloc(stmt_list->a_string, char *, slen + 2, "append_statement");
+ erealloc(stmt_list->a_string, char *, slen + 1, "append_statement");
return stmt_list;
#undef EVALSIZE
@@ -2921,7 +2921,7 @@ again:
bool esc_seen = false;
toklen = lexend - lexptr;
- emalloc(str, char *, toklen + 2, "yylex");
+ emalloc(str, char *, toklen + 1, "yylex");
p = str;
while ((c = *++lexptr) != '"') {
@@ -3100,7 +3100,7 @@ concat_args(CMDARG *arg, int count)
arg = arg->next;
}
- emalloc(str, char *, len + 2, "concat_args");
+ emalloc(str, char *, len + 1, "concat_args");
n = tmp[0];
memcpy(str, n->stptr, n->stlen);
p = str + n->stlen;
diff --git a/command.y b/command.y
index 08893743..bd5b4870 100644
--- a/command.y
+++ b/command.y
@@ -764,7 +764,7 @@ append_statement(CMDARG *stmt_list, char *stmt)
len += strlen(a->a_string) + 1; /* 1 for ',' */
len += EVALSIZE;
- emalloc(s, char *, (len + 2) * sizeof(char), "append_statement");
+ emalloc(s, char *, (len + 1) * sizeof(char), "append_statement");
arg = mk_cmdarg(D_string);
arg->a_string = s;
arg->a_count = len; /* kludge */
@@ -791,7 +791,7 @@ append_statement(CMDARG *stmt_list, char *stmt)
ssize = stmt_list->a_count;
if (len > ssize - slen) {
ssize = slen + len + EVALSIZE;
- erealloc(s, char *, (ssize + 2) * sizeof(char), "append_statement");
+ erealloc(s, char *, (ssize + 1) * sizeof(char), "append_statement");
stmt_list->a_string = s;
stmt_list->a_count = ssize;
}
@@ -803,7 +803,7 @@ append_statement(CMDARG *stmt_list, char *stmt)
}
if (stmt == end_EVAL)
- erealloc(stmt_list->a_string, char *, slen + 2, "append_statement");
+ erealloc(stmt_list->a_string, char *, slen + 1, "append_statement");
return stmt_list;
#undef EVALSIZE
@@ -1170,7 +1170,7 @@ again:
bool esc_seen = false;
toklen = lexend - lexptr;
- emalloc(str, char *, toklen + 2, "yylex");
+ emalloc(str, char *, toklen + 1, "yylex");
p = str;
while ((c = *++lexptr) != '"') {
@@ -1349,7 +1349,7 @@ concat_args(CMDARG *arg, int count)
arg = arg->next;
}
- emalloc(str, char *, len + 2, "concat_args");
+ emalloc(str, char *, len + 1, "concat_args");
n = tmp[0];
memcpy(str, n->stptr, n->stlen);
p = str + n->stlen;
diff --git a/debug.c b/debug.c
index 58012b72..6aaba099 100644
--- a/debug.c
+++ b/debug.c
@@ -4205,10 +4205,10 @@ gprintf(FILE *fp, const char *format, ...)
#define GPRINTF_BUFSIZ 512
if (buf == NULL) {
buflen = GPRINTF_BUFSIZ;
- emalloc(buf, char *, (buflen + 2) * sizeof(char), "gprintf");
+ emalloc(buf, char *, buflen * sizeof(char), "gprintf");
} else if (buflen - bl < GPRINTF_BUFSIZ/2) {
buflen += GPRINTF_BUFSIZ;
- erealloc(buf, char *, (buflen + 2) * sizeof(char), "gprintf");
+ erealloc(buf, char *, buflen * sizeof(char), "gprintf");
}
#undef GPRINTF_BUFSIZ
@@ -4227,7 +4227,7 @@ gprintf(FILE *fp, const char *format, ...)
/* enlarge buffer, and try again */
buflen *= 2;
- erealloc(buf, char *, (buflen + 2) * sizeof(char), "gprintf");
+ erealloc(buf, char *, buflen * sizeof(char), "gprintf");
}
bl = 0;
@@ -4267,7 +4267,7 @@ gprintf(FILE *fp, const char *format, ...)
static int
serialize_subscript(char *buf, int buflen, struct list_item *item)
{
- int bl = 0, nchar, i;
+ int bl, nchar, i;
NODE *sub;
nchar = snprintf(buf, buflen, "%d%c%d%c%s%c%d%c",
@@ -4277,7 +4277,7 @@ serialize_subscript(char *buf, int buflen, struct list_item *item)
return 0;
else if (nchar >= buflen) /* need larger buffer */
return nchar;
- bl += nchar;
+ bl = nchar;
for (i = 0; i < item->num_subs; i++) {
sub = item->subs[i];
nchar = snprintf(buf + bl, buflen - bl, "%lu%c%s%c",
@@ -4356,7 +4356,7 @@ serialize(int type)
if (buf == NULL) { /* first time */
buflen = SERIALIZE_BUFSIZ;
- emalloc(buf, char *, buflen + 2, "serialize");
+ emalloc(buf, char *, buflen + 1, "serialize");
}
bl = 0;
@@ -4365,7 +4365,7 @@ serialize(int type)
if (buflen - bl < SERIALIZE_BUFSIZ/2) {
enlarge_buffer:
buflen *= 2;
- erealloc(buf, char *, buflen + 2, "serialize");
+ erealloc(buf, char *, buflen + 1, "serialize");
}
#undef SERIALIZE_BUFSIZ
@@ -4466,7 +4466,7 @@ enlarge_buffer:
}
if (nchar > 0) { /* non-empty commands list */
- nchar += (strlen("commands ") + 20 + strlen("end") + 2); /* 20 for cnum (an int) */
+ nchar += (strlen("commands ") + 20 + strlen("end") + 1); /* 20 for cnum (an int) */
if (nchar > buflen - bl) {
buflen = bl + nchar;
erealloc(buf, char *, buflen + 3, "serialize");
diff --git a/eval.c b/eval.c
index a3a6b2b6..2d820580 100644
--- a/eval.c
+++ b/eval.c
@@ -827,9 +827,9 @@ set_OFS()
new_ofs_len = OFS_node->var_value->stlen;
if (OFS == NULL)
- emalloc(OFS, char *, new_ofs_len + 2, "set_OFS");
+ emalloc(OFS, char *, new_ofs_len + 1, "set_OFS");
else if (OFSlen < new_ofs_len)
- erealloc(OFS, char *, new_ofs_len + 2, "set_OFS");
+ erealloc(OFS, char *, new_ofs_len + 1, "set_OFS");
memcpy(OFS, OFS_node->var_value->stptr, OFS_node->var_value->stlen);
OFSlen = new_ofs_len;
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 2769a350..9df8ae00 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -86,6 +86,13 @@
(errno_la_SOURCES, errno_la_LDFLAGS, errno_la_LIBADD): Remove.
(EXTRA_DIST): Remove errlist.h.
+2014-12-14 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * readfile.c (read_file_to_buffer): Do not waste a byte at the end of
+ a string.
+ * rwarray.c (read_value): Ditto.
+ * rwarray0.c (read_value): Ditto.
+
2014-11-23 Arnold D. Robbins <arnold@skeeve.com>
* inplace.c (do_inplace_begin): Jump through hoops to silence
diff --git a/extension/readfile.c b/extension/readfile.c
index d4b4aef9..7673589f 100644
--- a/extension/readfile.c
+++ b/extension/readfile.c
@@ -82,8 +82,8 @@ read_file_to_buffer(int fd, const struct stat *sbuf)
goto done;
}
- emalloc(text, char *, sbuf->st_size + 2, "do_readfile");
- memset(text, '\0', sbuf->st_size + 2);
+ emalloc(text, char *, sbuf->st_size + 1, "do_readfile");
+ memset(text, '\0', sbuf->st_size + 1);
if ((ret = read(fd, text, sbuf->st_size)) != sbuf->st_size) {
update_ERRNO_int(errno);
diff --git a/extension/rwarray.c b/extension/rwarray.c
index aa05a0d5..5bead973 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -468,8 +468,8 @@ read_value(FILE *fp, awk_value_t *value)
len = ntohl(len);
value->val_type = AWK_STRING;
value->str_value.len = len;
- value->str_value.str = gawk_malloc(len + 2);
- memset(value->str_value.str, '\0', len + 2);
+ value->str_value.str = gawk_malloc(len + 1);
+ memset(value->str_value.str, '\0', len + 1);
if (fread(value->str_value.str, 1, len, fp) != (ssize_t) len) {
gawk_free(value->str_value.str);
diff --git a/extension/rwarray0.c b/extension/rwarray0.c
index e2de3cf5..ec3663cc 100644
--- a/extension/rwarray0.c
+++ b/extension/rwarray0.c
@@ -452,8 +452,8 @@ read_value(int fd, awk_value_t *value)
len = ntohl(len);
value->val_type = AWK_STRING;
value->str_value.len = len;
- value->str_value.str = malloc(len + 2);
- memset(value->str_value.str, '\0', len + 2);
+ value->str_value.str = malloc(len + 1);
+ memset(value->str_value.str, '\0', len + 1);
if (read(fd, value->str_value.str, len) != (ssize_t) len) {
free(value->str_value.str);
diff --git a/field.c b/field.c
index 6a7c6b1d..13a5db6f 100644
--- a/field.c
+++ b/field.c
@@ -163,7 +163,7 @@ rebuild_record()
tlen += (NF - 1) * OFSlen;
if ((long) tlen < 0)
tlen = 0;
- emalloc(ops, char *, tlen + 2, "rebuild_record");
+ emalloc(ops, char *, tlen + 1, "rebuild_record");
cops = ops;
ops[0] = '\0';
for (i = 1; i <= NF; i++) {
@@ -1138,7 +1138,7 @@ set_FIELDWIDTHS()
FIELDWIDTHS[0] = 0;
for (i = 1; ; i++) {
unsigned long int tmp;
- if (i + 2 >= fw_alloc) {
+ if (i + 1 >= fw_alloc) {
fw_alloc *= 2;
erealloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int), "set_FIELDWIDTHS");
}
diff --git a/gawkapi.h b/gawkapi.h
index 8bf3a08d..c708db67 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -827,7 +827,7 @@ r_make_string(const gawk_api_t *api, /* needed for emalloc */
result->str_value.len = length;
if (duplicate) {
- emalloc(cp, char *, length + 2, "r_make_string");
+ emalloc(cp, char *, length + 1, "r_make_string");
memcpy(cp, string, length);
cp[length] = '\0';
result->str_value.str = cp;
diff --git a/helpers/ChangeLog b/helpers/ChangeLog
index a5bbafb1..5a3f2fe3 100644
--- a/helpers/ChangeLog
+++ b/helpers/ChangeLog
@@ -1,3 +1,11 @@
+2015-04-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * testdfa.c (setup_pattern): Rationalize buffer size computations.
+
+2014-12-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * testdfa.c (setup_pattern): Do not waste a byte at the end of a string.
+
2014-09-04 Arnold D. Robbins <arnold@skeeve.com>
* chlistref.awk: New file. Finds @ref{} to non-chapters.
diff --git a/helpers/testdfa.c b/helpers/testdfa.c
index 25a229a2..2b773467 100644
--- a/helpers/testdfa.c
+++ b/helpers/testdfa.c
@@ -372,10 +372,10 @@ setup_pattern(const char *pattern, size_t *len)
{
size_t is_multibyte = 0;
int c, c2;
- size_t buflen = 0;
+ size_t buflen;
mbstate_t mbs;
bool has_anchor = false;
- char *buf = NULL;
+ char *buf;
char *dest;
const char *src, *end;
@@ -391,21 +391,12 @@ setup_pattern(const char *pattern, size_t *len)
* escaped characters translated, and generate the regex
* from that.
*/
+ buf = (char *) malloc(*len + 1);
if (buf == NULL) {
- buf = (char *) malloc(*len + 2);
- if (buf == NULL) {
- fprintf(stderr, "%s: malloc failed\n", __func__);
- exit(EXIT_FAILURE);
- }
- buflen = *len;
- } else if (*len > buflen) {
- buf = (char *) realloc(buf, *len + 2);
- if (buf == NULL) {
- fprintf(stderr, "%s: realloc failed\n", __func__);
- exit(EXIT_FAILURE);
- }
- buflen = *len;
+ fprintf(stderr, "%s: malloc failed\n", __func__);
+ exit(EXIT_FAILURE);
}
+ buflen = *len;
dest = buf;
while (src < end) {
diff --git a/interpret.h b/interpret.h
index b76952f1..03532f43 100644
--- a/interpret.h
+++ b/interpret.h
@@ -709,7 +709,7 @@ mod:
if (t1 != t2 && t1->valref == 1 && (t1->flags & MPFN) == 0) {
size_t nlen = t1->stlen + t2->stlen;
- erealloc(t1->stptr, char *, nlen + 2, "r_interpret");
+ erealloc(t1->stptr, char *, nlen + 1, "r_interpret");
memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen);
t1->stlen = nlen;
t1->stptr[nlen] = '\0';
@@ -719,7 +719,7 @@ mod:
size_t wlen = t1->wstlen + t2->wstlen;
erealloc(t1->wstptr, wchar_t *,
- sizeof(wchar_t) * (wlen + 2), "r_interpret");
+ sizeof(wchar_t) * (wlen + 1), "r_interpret");
memcpy(t1->wstptr + t1->wstlen, t2->wstptr, t2->wstlen);
t1->wstlen = wlen;
t1->wstptr[wlen] = L'\0';
@@ -730,9 +730,10 @@ mod:
size_t nlen = t1->stlen + t2->stlen;
char *p;
- emalloc(p, char *, nlen + 2, "r_interpret");
+ emalloc(p, char *, nlen + 1, "r_interpret");
memcpy(p, t1->stptr, t1->stlen);
memcpy(p + t1->stlen, t2->stptr, t2->stlen);
+ /* N.B. No NUL-termination required, since make_str_node will do it. */
unref(*lhs);
t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED);
}
diff --git a/io.c b/io.c
index 50310ed2..50f0989b 100644
--- a/io.c
+++ b/io.c
@@ -2709,6 +2709,7 @@ init_awkpath(path_info *pi)
end++;
len = end - start;
if (len > 0) {
+ /* +2 is correct here; leave room for / */
emalloc(p, char *, len + 2, "init_awkpath");
memcpy(p, start, len);
@@ -3163,7 +3164,7 @@ iop_finish(IOBUF *iop)
lintwarn(_("data file `%s' is empty"), iop->public.name);
iop->errcode = errno = 0;
iop->count = iop->scanoff = 0;
- emalloc(iop->buf, char *, iop->size += 2, "iop_finish");
+ emalloc(iop->buf, char *, iop->size += 1, "iop_finish");
iop->off = iop->buf;
iop->dataend = NULL;
iop->end = iop->buf + iop->size;
@@ -3195,10 +3196,10 @@ grow_iop_buffer(IOBUF *iop)
size_t newsize;
/*
- * Lop off original extra two bytes, double the size,
- * add them back.
+ * Lop off original extra byte, double the size,
+ * add it back.
*/
- newsize = ((iop->size - 2) * 2) + 2;
+ newsize = ((iop->size - 1) * 2) + 1;
/* Check for overflow */
if (newsize <= iop->size)
@@ -3206,7 +3207,7 @@ grow_iop_buffer(IOBUF *iop)
/* Make sure there's room for a disk block */
if (newsize - valid < iop->readsize)
- newsize += iop->readsize + 2;
+ newsize += iop->readsize + 1;
/* Check for overflow, again */
if (newsize <= iop->size)
diff --git a/node.c b/node.c
index b9c751dd..b15159f0 100644
--- a/node.c
+++ b/node.c
@@ -261,7 +261,7 @@ r_format_val(const char *format, int index, NODE *s)
}
if (s->stptr != NULL)
efree(s->stptr);
- emalloc(s->stptr, char *, s->stlen + 2, "format_val");
+ emalloc(s->stptr, char *, s->stlen + 1, "format_val");
memcpy(s->stptr, sp, s->stlen + 1);
no_malloc:
s->flags |= STRCUR;
@@ -299,12 +299,12 @@ r_dupnode(NODE *n)
r->wstlen = 0;
if ((n->flags & STRCUR) != 0) {
- emalloc(r->stptr, char *, n->stlen + 2, "r_dupnode");
+ emalloc(r->stptr, char *, n->stlen + 1, "r_dupnode");
memcpy(r->stptr, n->stptr, n->stlen);
r->stptr[n->stlen] = '\0';
if ((n->flags & WSTRCUR) != 0) {
r->wstlen = n->wstlen;
- emalloc(r->wstptr, wchar_t *, sizeof(wchar_t) * (n->wstlen + 2), "r_dupnode");
+ emalloc(r->wstptr, wchar_t *, sizeof(wchar_t) * (n->wstlen + 1), "r_dupnode");
memcpy(r->wstptr, n->wstptr, n->wstlen * sizeof(wchar_t));
r->wstptr[n->wstlen] = L'\0';
r->flags |= WSTRCUR;
@@ -377,7 +377,7 @@ make_str_node(const char *s, size_t len, int flags)
if ((flags & ALREADY_MALLOCED) != 0)
r->stptr = (char *) s;
else {
- emalloc(r->stptr, char *, len + 2, "make_str_node");
+ emalloc(r->stptr, char *, len + 1, "make_str_node");
memcpy(r->stptr, s, len);
}
r->stptr[len] = '\0';
@@ -681,7 +681,7 @@ str2wstr(NODE *n, size_t **ptr)
* realloc the wide string down in size.
*/
- emalloc(n->wstptr, wchar_t *, sizeof(wchar_t) * (n->stlen + 2), "str2wstr");
+ emalloc(n->wstptr, wchar_t *, sizeof(wchar_t) * (n->stlen + 1), "str2wstr");
wsp = n->wstptr;
/*
@@ -755,7 +755,7 @@ str2wstr(NODE *n, size_t **ptr)
n->flags |= WSTRCUR;
#define ARBITRARY_AMOUNT_TO_GIVE_BACK 100
if (n->stlen - n->wstlen > ARBITRARY_AMOUNT_TO_GIVE_BACK)
- erealloc(n->wstptr, wchar_t *, sizeof(wchar_t) * (n->wstlen + 2), "str2wstr");
+ erealloc(n->wstptr, wchar_t *, sizeof(wchar_t) * (n->wstlen + 1), "str2wstr");
return n;
}
@@ -782,7 +782,7 @@ wstr2str(NODE *n)
memset(& mbs, 0, sizeof(mbs));
length = n->wstlen;
- emalloc(newval, char *, (length * gawk_mb_cur_max) + 2, "wstr2str");
+ emalloc(newval, char *, (length * gawk_mb_cur_max) + 1, "wstr2str");
wp = n->wstptr;
for (cp = newval; length > 0; length--) {
diff --git a/old-extension/ChangeLog b/old-extension/ChangeLog
index 55c8d31d..dad5c794 100644
--- a/old-extension/ChangeLog
+++ b/old-extension/ChangeLog
@@ -1,3 +1,12 @@
+2015-04-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * bindarr.c (do_bind_array): Undo Arnold's change of 2014-12-18.
+
+2014-12-18 Arnold D. Robbins <arnold@skeeve.com>
+
+ * bindarr.c (do_bind_array): Do not waste a byte at the end of a string.
+ * fileop.c (do_fread): Ditto.
+
2014-01-07 Arnold D. Robbins <arnold@skeeve.com>
* dbarray.awk: Use full name for lib to load in extenstion() call.
diff --git a/old-extension/bindarr.c b/old-extension/bindarr.c
index 60959903..41467425 100644
--- a/old-extension/bindarr.c
+++ b/old-extension/bindarr.c
@@ -235,7 +235,7 @@ do_bind_array(int nargs)
}
/* copy the array -- this is passed as the second argument to the functions */
- emalloc(aname, char *, strlen(t->vname) + 2, "do_bind_array");
+ emalloc(aname, char *, 1 + strlen(symbol->vname) + 1, "do_bind_array");
aname[0] = '~'; /* any illegal character */
strcpy(& aname[1], symbol->vname);
td = make_array();
diff --git a/old-extension/fileop.c b/old-extension/fileop.c
index 86f62576..d76a7ded 100644
--- a/old-extension/fileop.c
+++ b/old-extension/fileop.c
@@ -55,7 +55,7 @@ do_fread(int nargs)
force_number(arg);
rlen = get_number_ui(arg);
- emalloc(rbuf, char *, rlen + 2, "do_fread");
+ emalloc(rbuf, char *, rlen + 1, "do_fread");
if ((count = fread(rbuf, 1, rlen, f->fp)) < rlen) {
if (! feof(f->fp))
update_ERRNO_int(errno);
diff --git a/profile.c b/profile.c
index dc887e97..dcc2946c 100644
--- a/profile.c
+++ b/profile.c
@@ -1359,7 +1359,7 @@ pp_string(const char *in_str, size_t len, int delim)
osiz *= 2; \
} ofre -= (l)
- osiz = len + 3 + 2; /* initial size; 3 for delim + terminating null */
+ osiz = len + 3 + 1; /* initial size; 3 for delim + terminating null */
emalloc(obuf, char *, osiz, "pp_string");
obufout = obuf;
ofre = osiz - 1;
@@ -1371,10 +1371,9 @@ pp_string(const char *in_str, size_t len, int delim)
*obufout++ = '\\';
*obufout++ = delim;
} else if (*str == '\0') {
- chksize(4);
-
*obufout++ = '\\';
*obufout++ = '0';
+ chksize(2); /* need 2 more chars for this case */
*obufout++ = '0';
*obufout++ = '0';
} else if ((cp = strchr(escapes, *str)) != NULL) {
@@ -1384,7 +1383,7 @@ pp_string(const char *in_str, size_t len, int delim)
/* NB: Deliberate use of lower-case versions. */
} else if (isascii(*str) && isprint(*str)) {
*obufout++ = *str;
- ofre += 1;
+ ofre += 1; /* used 1 less than expected */
} else {
size_t len;
@@ -1607,7 +1606,7 @@ pp_group3(const char *s1, const char *s2, const char *s3)
len1 = strlen(s1);
len2 = strlen(s2);
len3 = strlen(s3);
- l = len1 + len2 + len3 + 2;
+ l = len1 + len2 + len3 + 1;
emalloc(str, char *, l, "pp_group3");
s = str;
if (len1 > 0) {
diff --git a/re.c b/re.c
index c0d2e90e..39453b1c 100644
--- a/re.c
+++ b/re.c
@@ -75,10 +75,10 @@ make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal)
* from that.
*/
if (buf == NULL) {
- emalloc(buf, char *, len + 2, "make_regexp");
+ emalloc(buf, char *, len + 1, "make_regexp");
buflen = len;
} else if (len > buflen) {
- erealloc(buf, char *, len + 2, "make_regexp");
+ erealloc(buf, char *, len + 1, "make_regexp");
buflen = len;
}
dest = buf;