[ruby/cgi] Fix unescapeHTML

67610e6ca8
This commit is contained in:
flosacca 2023-11-23 01:49:42 +08:00 committed by git
parent 0daa0589a9
commit 30e4778020

View file

@ -83,7 +83,7 @@ optimized_unescape_html(VALUE str)
unsigned long charlimit = (strcasecmp(rb_enc_name(enc), "UTF-8") == 0 ? UNICODE_MAX : unsigned long charlimit = (strcasecmp(rb_enc_name(enc), "UTF-8") == 0 ? UNICODE_MAX :
strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 : strcasecmp(rb_enc_name(enc), "ISO-8859-1") == 0 ? 256 :
128); 128);
long i, len, beg = 0; long i, j, len, beg = 0;
size_t clen, plen; size_t clen, plen;
int overflow; int overflow;
const char *cstr; const char *cstr;
@ -100,6 +100,7 @@ optimized_unescape_html(VALUE str)
plen = i - beg; plen = i - beg;
if (++i >= len) break; if (++i >= len) break;
c = (unsigned char)cstr[i]; c = (unsigned char)cstr[i];
j = i;
#define MATCH(s) (len - i >= (int)rb_strlen_lit(s) && \ #define MATCH(s) (len - i >= (int)rb_strlen_lit(s) && \
memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \ memcmp(&cstr[i], s, rb_strlen_lit(s)) == 0 && \
(i += rb_strlen_lit(s) - 1, 1)) (i += rb_strlen_lit(s) - 1, 1))
@ -112,28 +113,40 @@ optimized_unescape_html(VALUE str)
else if (MATCH("mp;")) { else if (MATCH("mp;")) {
c = '&'; c = '&';
} }
else continue; else {
i = j;
continue;
}
break; break;
case 'q': case 'q':
++i; ++i;
if (MATCH("uot;")) { if (MATCH("uot;")) {
c = '"'; c = '"';
} }
else continue; else {
i = j;
continue;
}
break; break;
case 'g': case 'g':
++i; ++i;
if (MATCH("t;")) { if (MATCH("t;")) {
c = '>'; c = '>';
} }
else continue; else {
i = j;
continue;
}
break; break;
case 'l': case 'l':
++i; ++i;
if (MATCH("t;")) { if (MATCH("t;")) {
c = '<'; c = '<';
} }
else continue; else {
i = j;
continue;
}
break; break;
case '#': case '#':
if (len - ++i >= 2 && ISDIGIT(cstr[i])) { if (len - ++i >= 2 && ISDIGIT(cstr[i])) {
@ -142,9 +155,15 @@ optimized_unescape_html(VALUE str)
else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) { else if ((cstr[i] == 'x' || cstr[i] == 'X') && len - ++i >= 2 && ISXDIGIT(cstr[i])) {
cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow); cc = ruby_scan_digits(&cstr[i], len-i, 16, &clen, &overflow);
} }
else continue; else {
i = j;
continue;
}
i += clen; i += clen;
if (overflow || cc >= charlimit || cstr[i] != ';') continue; if (overflow || cc >= charlimit || cstr[i] != ';') {
i = j;
continue;
}
if (!dest) { if (!dest) {
dest = rb_str_buf_new(len); dest = rb_str_buf_new(len);
} }