in src/couch_quickjs/quickjs/libregexp.c [786:872]
static int re_parse_char_class(REParseState *s, const uint8_t **pp)
{
const uint8_t *p;
uint32_t c1, c2;
CharRange cr_s, *cr = &cr_s;
CharRange cr1_s, *cr1 = &cr1_s;
BOOL invert;
cr_init(cr, s->opaque, lre_realloc);
p = *pp;
p++; /* skip '[' */
invert = FALSE;
if (*p == '^') {
p++;
invert = TRUE;
}
for(;;) {
if (*p == ']')
break;
c1 = get_class_atom(s, cr1, &p, TRUE);
if ((int)c1 < 0)
goto fail;
if (*p == '-' && p[1] != ']') {
const uint8_t *p0 = p + 1;
if (c1 >= CLASS_RANGE_BASE) {
if (s->is_unicode) {
cr_free(cr1);
goto invalid_class_range;
}
/* Annex B: match '-' character */
goto class_atom;
}
c2 = get_class_atom(s, cr1, &p0, TRUE);
if ((int)c2 < 0)
goto fail;
if (c2 >= CLASS_RANGE_BASE) {
cr_free(cr1);
if (s->is_unicode) {
goto invalid_class_range;
}
/* Annex B: match '-' character */
goto class_atom;
}
p = p0;
if (c2 < c1) {
invalid_class_range:
re_parse_error(s, "invalid class range");
goto fail;
}
if (cr_union_interval(cr, c1, c2))
goto memory_error;
} else {
class_atom:
if (c1 >= CLASS_RANGE_BASE) {
int ret;
ret = cr_union1(cr, cr1->points, cr1->len);
cr_free(cr1);
if (ret)
goto memory_error;
} else {
if (cr_union_interval(cr, c1, c1))
goto memory_error;
}
}
}
if (s->ignore_case) {
if (cr_regexp_canonicalize(cr, s->is_unicode))
goto memory_error;
}
if (invert) {
if (cr_invert(cr))
goto memory_error;
}
if (re_emit_range(s, cr))
goto fail;
cr_free(cr);
p++; /* skip ']' */
*pp = p;
return 0;
memory_error:
re_parse_out_of_memory(s);
fail:
cr_free(cr);
return -1;
}