diff --git a/libc/intrin/demangle.c b/libc/intrin/demangle.c index ad21c1eb15b..9cea291cc9d 100644 --- a/libc/intrin/demangle.c +++ b/libc/intrin/demangle.c @@ -380,13 +380,16 @@ demangle_free(struct demangle_data *h, void *ptr) } static privileged returnspointerwithnoaliases returnsnonnull void * -demangle_malloc(struct demangle_data *h, int a, int n) +demangle_malloc(struct demangle_data *h, long a, long n) { - int rem; + long rem; uintptr_t ptr; index_t next, next2; index_t *link, *link2; - int b = sizeof(index_t); + long b = sizeof(index_t); + + if (n < 0 || n >= 32768) + __builtin_longjmp(h->jmpbuf, 1); /* Roundup size. */ n += a - 1; @@ -2098,10 +2101,11 @@ demangle_read_tmpl_param(struct demangle_data *ddata) /* T_ is first */ ++nth; - while (*ddata->cur != '_') + while (*ddata->cur && *ddata->cur != '_') ++ddata->cur; - ASSERT(nth > 0); + if (nth <= 0) + return 0; return demangle_get_tmpl_param(ddata, nth); } @@ -2752,7 +2756,7 @@ demangle_read_offset_number(struct demangle_data *ddata) start = ddata->cur; } - while (*ddata->cur != '_') + while (*ddata->cur && *ddata->cur != '_') ++ddata->cur; if (negative && !DEM_PUSH_STR(ddata, "-")) @@ -2859,13 +2863,12 @@ demangle_read_number(struct demangle_data *ddata, long *rtn) return 0; len = demangle_strtol(ddata->cur, 10); + if (len < 0) + __builtin_longjmp(ddata->jmpbuf, 1); while (ELFTC_ISDIGIT(*ddata->cur)) ++ddata->cur; - ASSERT(len >= 0); - ASSERT(negative_factor == 1 || negative_factor == -1); - *rtn = len * negative_factor; return 1; @@ -3419,6 +3422,7 @@ demangle_read_pointer_to_member(struct demangle_data *ddata, static privileged int demangle_read_sname(struct demangle_data *ddata) { + size_t lim; long len; int err; @@ -3438,6 +3442,9 @@ demangle_read_sname(struct demangle_data *ddata) ddata->last_sname = VEC_STR(ddata, ddata->cur_output, ddata->cur_output->size - 1); + lim = demangle_strlen(ddata->cur); + if (len > lim) + len = lim; ddata->cur += len; return 1; @@ -3647,10 +3654,11 @@ demangle_read_subst(struct demangle_data *ddata) /* first was '_', so increase one */ ++nth; - while (*ddata->cur != '_') + while (*ddata->cur && *ddata->cur != '_') ++ddata->cur; - ASSERT(nth > 0); + if (nth <= 0) + return 0; return demangle_get_subst(ddata, nth); } @@ -3881,7 +3889,7 @@ demangle_read_type(struct demangle_data *ddata, struct type_delimit *td) case 'E': /* unexpected end (except some things) */ - if (ddata->is_guard_variable) + if (td && ddata->is_guard_variable) td->paren = false; if (ddata->is_guard_variable || (ddata->ref_qualifier && ddata->is_functype)) { @@ -4102,6 +4110,8 @@ demangle_read_type(struct demangle_data *ddata, struct type_delimit *td) if (!demangle_vector_str_push(ddata, &v.ext_name, ddata->cur, len)) return 0; + if (len > demangle_strlen(ddata->cur)) + len = demangle_strlen(ddata->cur); ddata->cur += len; if (!demangle_vector_type_qualifier_push(ddata, &v, TYPE_EXT)) return 0;