[flori/json] Refactor json_string_unescape
https://github.com/flori/json/commit/f398769332
This commit is contained in:
parent
8a974dc83c
commit
1d2b4ccaf2
File diff suppressed because it is too large
Load Diff
@ -63,7 +63,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|||||||
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
||||||
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
||||||
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
|
||||||
static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd);
|
static VALUE json_string_unescape(char *string, char *stringEnd);
|
||||||
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
|
||||||
static VALUE convert_encoding(VALUE source);
|
static VALUE convert_encoding(VALUE source);
|
||||||
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
|
||||||
|
@ -452,17 +452,30 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
static const size_t MAX_STACK_BUFFER_SIZE = 128;
|
||||||
|
static VALUE json_string_unescape(char *string, char *stringEnd)
|
||||||
{
|
{
|
||||||
char *p = string, *pe = string, *unescape;
|
VALUE result = Qnil;
|
||||||
|
size_t bufferSize = stringEnd - string;
|
||||||
|
char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
|
||||||
int unescape_len;
|
int unescape_len;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
|
||||||
|
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
||||||
|
buffer = xmalloc(bufferSize);
|
||||||
|
bufferStart = buffer;
|
||||||
|
} else {
|
||||||
|
bufferStart = buffer = alloca(bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
while (pe < stringEnd) {
|
while (pe < stringEnd) {
|
||||||
if (*pe == '\\') {
|
if (*pe == '\\') {
|
||||||
unescape = (char *) "?";
|
unescape = (char *) "?";
|
||||||
unescape_len = 1;
|
unescape_len = 1;
|
||||||
if (pe > p) rb_str_buf_cat(result, p, pe - p);
|
if (pe > p) {
|
||||||
|
MEMCPY(buffer, p, char, pe - p);
|
||||||
|
buffer += pe - p;
|
||||||
|
}
|
||||||
switch (*++pe) {
|
switch (*++pe) {
|
||||||
case 'n':
|
case 'n':
|
||||||
unescape = (char *) "\n";
|
unescape = (char *) "\n";
|
||||||
@ -487,6 +500,9 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
if (pe > stringEnd - 4) {
|
if (pe > stringEnd - 4) {
|
||||||
|
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
||||||
|
free(bufferStart);
|
||||||
|
}
|
||||||
rb_enc_raise(
|
rb_enc_raise(
|
||||||
EXC_ENCODING eParserError,
|
EXC_ENCODING eParserError,
|
||||||
"%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
|
"%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
|
||||||
@ -497,6 +513,9 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|||||||
if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
|
if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
|
||||||
pe++;
|
pe++;
|
||||||
if (pe > stringEnd - 6) {
|
if (pe > stringEnd - 6) {
|
||||||
|
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
||||||
|
free(bufferStart);
|
||||||
|
}
|
||||||
rb_enc_raise(
|
rb_enc_raise(
|
||||||
EXC_ENCODING eParserError,
|
EXC_ENCODING eParserError,
|
||||||
"%u: incomplete surrogate pair at '%s'", __LINE__, p
|
"%u: incomplete surrogate pair at '%s'", __LINE__, p
|
||||||
@ -520,13 +539,28 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|||||||
p = pe;
|
p = pe;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rb_str_buf_cat(result, unescape, unescape_len);
|
MEMCPY(buffer, unescape, char, unescape_len);
|
||||||
|
buffer += unescape_len;
|
||||||
p = ++pe;
|
p = ++pe;
|
||||||
} else {
|
} else {
|
||||||
pe++;
|
pe++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rb_str_buf_cat(result, p, pe - p);
|
|
||||||
|
if (pe > p) {
|
||||||
|
MEMCPY(buffer, p, char, pe - p);
|
||||||
|
buffer += pe - p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_RUBY_ENCODING_H
|
||||||
|
result = rb_utf8_str_new(bufferStart, buffer - bufferStart);
|
||||||
|
#else
|
||||||
|
result = rb_str_new(bufferStart, buffer - bufferStart);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (bufferSize > MAX_STACK_BUFFER_SIZE) {
|
||||||
|
free(bufferStart);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,12 +571,11 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|||||||
write data;
|
write data;
|
||||||
|
|
||||||
action parse_string {
|
action parse_string {
|
||||||
*result = json_string_unescape(*result, json->memo + 1, p);
|
*result = json_string_unescape(json->memo + 1, p);
|
||||||
if (NIL_P(*result)) {
|
if (NIL_P(*result)) {
|
||||||
fhold;
|
fhold;
|
||||||
fbreak;
|
fbreak;
|
||||||
} else {
|
} else {
|
||||||
FORCE_UTF8(*result);
|
|
||||||
fexec p + 1;
|
fexec p + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,7 +602,6 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|||||||
int cs = EVIL;
|
int cs = EVIL;
|
||||||
VALUE match_string;
|
VALUE match_string;
|
||||||
|
|
||||||
*result = rb_str_buf_new(0);
|
|
||||||
%% write init;
|
%% write init;
|
||||||
json->memo = p;
|
json->memo = p;
|
||||||
%% write exec;
|
%% write exec;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user