aboutsummaryrefslogtreecommitdiffstats
path: root/node.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2017-04-12 12:16:41 +0300
committerArnold D. Robbins <arnold@skeeve.com>2017-04-12 12:16:41 +0300
commit3006a420c22133e40e6a0aeaeb9bcd402b0754bd (patch)
treef9700b1703106dd56cb392da6380611c4917cf99 /node.c
parent4b68f4ebe7381644e5652a88a5104a10f10f66a7 (diff)
parent8f83ab76a1d8861d9a992290f2691443d5169c89 (diff)
downloadegawk-3006a420c22133e40e6a0aeaeb9bcd402b0754bd.tar.gz
egawk-3006a420c22133e40e6a0aeaeb9bcd402b0754bd.tar.bz2
egawk-3006a420c22133e40e6a0aeaeb9bcd402b0754bd.zip
Merge branch 'master' into feature/api-mpfr
Diffstat (limited to 'node.c')
-rw-r--r--node.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/node.c b/node.c
index 2e05814c..3e5c934b 100644
--- a/node.c
+++ b/node.c
@@ -41,12 +41,13 @@ int (*cmp_numbers)(const NODE *, const NODE *) = cmp_awknums;
/* is_hex --- return true if a string looks like a hex value */
static bool
-is_hex(const char *str)
+is_hex(const char *str, const char *cpend)
{
+ /* on entry, we know the string length is >= 1 */
if (*str == '-' || *str == '+')
str++;
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+ if (str + 1 < cpend && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
return true;
return false;
@@ -113,7 +114,7 @@ r_force_number(NODE *n)
if ( (! do_posix /* not POSIXLY paranoid and */
&& (is_alpha((unsigned char) *cp) /* letter, or */
/* CANNOT do non-decimal and saw 0x */
- || (! do_non_decimal_data && is_hex(cp))))) {
+ || (! do_non_decimal_data && is_hex(cp, cpend))))) {
goto badnum;
}
@@ -129,7 +130,7 @@ r_force_number(NODE *n)
errno = 0;
if (do_non_decimal_data /* main.c assures false if do_posix */
- && ! do_traditional && get_numbase(cp, true) != 10) {
+ && ! do_traditional && get_numbase(cp, cpend - cp, true) != 10) {
/* nondec2awknum() saves and restores the byte after the string itself */
n->numbr = nondec2awknum(cp, cpend - cp, &ptr);
} else {
@@ -248,7 +249,7 @@ r_format_val(const char *format, int index, NODE *s)
}
s->flags = oflags;
s->stlen = r->stlen;
- if ((s->flags & STRCUR) != 0)
+ if ((s->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR))
efree(s->stptr);
s->stptr = r->stptr;
freenode(r); /* Do not unref(r)! We want to keep s->stptr == r->stpr. */
@@ -273,7 +274,7 @@ r_format_val(const char *format, int index, NODE *s)
s->flags |= STRING;
}
}
- if ((s->flags & STRCUR) != 0)
+ if ((s->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR))
efree(s->stptr);
emalloc(s->stptr, char *, s->stlen + 1, "format_val");
memcpy(s->stptr, sp, s->stlen + 1);
@@ -623,7 +624,7 @@ parse_escape(const char **string_ptr)
/* get_numbase --- return the base to use for the number in 's' */
int
-get_numbase(const char *s, bool use_locale)
+get_numbase(const char *s, size_t len, bool use_locale)
{
int dec_point = '.';
const char *str = s;
@@ -637,7 +638,7 @@ get_numbase(const char *s, bool use_locale)
dec_point = loc.decimal_point[0]; /* XXX --- assumes one char */
#endif
- if (str[0] != '0')
+ if (len < 2 || str[0] != '0')
return 10;
/* leading 0x or 0X */
@@ -650,7 +651,7 @@ get_numbase(const char *s, bool use_locale)
*
* These beasts can have trailing whitespace. Deal with that too.
*/
- for (; *str != '\0'; str++) {
+ for (; len > 0; len--, str++) {
if (*str == 'e' || *str == 'E' || *str == dec_point)
return 10;
else if (! isdigit((unsigned char) *str))
@@ -836,6 +837,7 @@ wstr2str(NODE *n)
}
*cp = '\0';
+ /* N.B. caller just created n with make_string, so this free is safe */
efree(n->stptr);
n->stptr = newval;
n->stlen = cp - newval;