mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-24909 JSON functions don't respect KILL QUERY / max_statement_time limit
pass the pointer to thd->killed down to the json library, check it while scanning, use thd->check_killed() to generate the proper error message
This commit is contained in:
@ -222,6 +222,7 @@ typedef struct st_json_engine_t
|
|||||||
|
|
||||||
int stack[JSON_DEPTH_LIMIT]; /* Keeps the stack of nested JSON structures. */
|
int stack[JSON_DEPTH_LIMIT]; /* Keeps the stack of nested JSON structures. */
|
||||||
int stack_p; /* The 'stack' pointer. */
|
int stack_p; /* The 'stack' pointer. */
|
||||||
|
volatile uchar *killed_ptr;
|
||||||
} json_engine_t;
|
} json_engine_t;
|
||||||
|
|
||||||
|
|
||||||
|
42
mysql-test/main/func_json_notembedded.result
Normal file
42
mysql-test/main/func_json_notembedded.result
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
set global max_allowed_packet=1073741824;
|
||||||
|
connect u,localhost,root;
|
||||||
|
#
|
||||||
|
# MDEV-24909 JSON functions don't respect KILL QUERY / max_statement_time limit
|
||||||
|
#
|
||||||
|
set group_concat_max_len= 4294967295;
|
||||||
|
set @obj=concat_ws('','{', repeat('"a":"b",', 125000000/2), '"c":"d"}');
|
||||||
|
set @arr=concat_ws('','[', repeat('1234567,', 125000000/2), '2345678]');
|
||||||
|
select length(@obj), length(@arr);
|
||||||
|
length(@obj) length(@arr)
|
||||||
|
500000009 500000009
|
||||||
|
set max_statement_time=0.0001;
|
||||||
|
select json_array_append(@arr, '$[0]', 1);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_array_insert(@arr, '$[0]', 1);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_insert(@obj, '$.meta', 1);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_compact(@arr);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_detailed(@arr);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_loose(@arr);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_merge(@obj, @arr);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_merge_patch(@obj, @obj);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_merge_preserve(@obj, @arr);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_remove(@obj,'$.foo');
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_replace(@obj,'$.foo',1);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
select json_set(@arr,'$[1000]',1);
|
||||||
|
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||||
|
disconnect u;
|
||||||
|
connection default;
|
||||||
|
set global max_allowed_packet=default;
|
||||||
|
#
|
||||||
|
# End of 10.6 tests
|
||||||
|
#
|
37
mysql-test/main/func_json_notembedded.test
Normal file
37
mysql-test/main/func_json_notembedded.test
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
source include/have_profiling.inc;
|
||||||
|
source include/not_embedded.inc;
|
||||||
|
|
||||||
|
set global max_allowed_packet=1073741824;
|
||||||
|
connect u,localhost,root;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24909 JSON functions don't respect KILL QUERY / max_statement_time limit
|
||||||
|
--echo #
|
||||||
|
set group_concat_max_len= 4294967295;
|
||||||
|
|
||||||
|
set @obj=concat_ws('','{', repeat('"a":"b",', 125000000/2), '"c":"d"}');
|
||||||
|
set @arr=concat_ws('','[', repeat('1234567,', 125000000/2), '2345678]');
|
||||||
|
select length(@obj), length(@arr);
|
||||||
|
|
||||||
|
set max_statement_time=0.0001;
|
||||||
|
disable_abort_on_error;
|
||||||
|
select json_array_append(@arr, '$[0]', 1);
|
||||||
|
select json_array_insert(@arr, '$[0]', 1);
|
||||||
|
select json_insert(@obj, '$.meta', 1);
|
||||||
|
select json_compact(@arr);
|
||||||
|
select json_detailed(@arr);
|
||||||
|
select json_loose(@arr);
|
||||||
|
select json_merge(@obj, @arr);
|
||||||
|
select json_merge_patch(@obj, @obj);
|
||||||
|
select json_merge_preserve(@obj, @arr);
|
||||||
|
select json_remove(@obj,'$.foo');
|
||||||
|
select json_replace(@obj,'$.foo',1);
|
||||||
|
select json_set(@arr,'$[1000]',1);
|
||||||
|
enable_abort_on_error;
|
||||||
|
disconnect u;
|
||||||
|
connection default;
|
||||||
|
set global max_allowed_packet=default;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.6 tests
|
||||||
|
--echo #
|
@ -240,7 +240,7 @@ handle_value:
|
|||||||
};
|
};
|
||||||
} while (json_scan_next(je) == 0);
|
} while (json_scan_next(je) == 0);
|
||||||
|
|
||||||
return je->s.error;
|
return je->s.error || *je->killed_ptr;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return 1;
|
return 1;
|
||||||
@ -1653,6 +1653,7 @@ String *Item_func_json_array_append::val_str(String *str)
|
|||||||
uint n_arg, n_path;
|
uint n_arg, n_path;
|
||||||
size_t str_rest_len;
|
size_t str_rest_len;
|
||||||
const uchar *ar_end;
|
const uchar *ar_end;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
DBUG_ASSERT(fixed());
|
DBUG_ASSERT(fixed());
|
||||||
|
|
||||||
@ -1680,6 +1681,7 @@ String *Item_func_json_array_append::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr() + js->length());
|
(const uchar *) js->ptr() + js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
c_path->cur_step= c_path->p.steps;
|
c_path->cur_step= c_path->p.steps;
|
||||||
|
|
||||||
@ -1760,6 +1762,7 @@ String *Item_func_json_array_append::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr() + js->length());
|
(const uchar *) js->ptr() + js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
if (json_nice(&je, str, Item_func_json_format::LOOSE))
|
if (json_nice(&je, str, Item_func_json_format::LOOSE))
|
||||||
goto js_error;
|
goto js_error;
|
||||||
|
|
||||||
@ -1769,6 +1772,7 @@ js_error:
|
|||||||
report_json_error(js, &je, 0);
|
report_json_error(js, &je, 0);
|
||||||
|
|
||||||
return_null:
|
return_null:
|
||||||
|
thd->check_killed(); // to get the error message right
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1779,6 +1783,7 @@ String *Item_func_json_array_insert::val_str(String *str)
|
|||||||
json_engine_t je;
|
json_engine_t je;
|
||||||
String *js= args[0]->val_json(&tmp_js);
|
String *js= args[0]->val_json(&tmp_js);
|
||||||
uint n_arg, n_path;
|
uint n_arg, n_path;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
DBUG_ASSERT(fixed());
|
DBUG_ASSERT(fixed());
|
||||||
|
|
||||||
@ -1816,6 +1821,7 @@ String *Item_func_json_array_insert::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr() + js->length());
|
(const uchar *) js->ptr() + js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
c_path->cur_step= c_path->p.steps;
|
c_path->cur_step= c_path->p.steps;
|
||||||
|
|
||||||
@ -1855,7 +1861,7 @@ String *Item_func_json_array_insert::val_str(String *str)
|
|||||||
goto js_error;
|
goto js_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(je.s.error))
|
if (unlikely(je.s.error || *je.killed_ptr))
|
||||||
goto js_error;
|
goto js_error;
|
||||||
|
|
||||||
str->length(0);
|
str->length(0);
|
||||||
@ -1899,6 +1905,7 @@ String *Item_func_json_array_insert::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr() + js->length());
|
(const uchar *) js->ptr() + js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
if (json_nice(&je, str, Item_func_json_format::LOOSE))
|
if (json_nice(&je, str, Item_func_json_format::LOOSE))
|
||||||
goto js_error;
|
goto js_error;
|
||||||
|
|
||||||
@ -1907,6 +1914,7 @@ String *Item_func_json_array_insert::val_str(String *str)
|
|||||||
js_error:
|
js_error:
|
||||||
report_json_error(js, &je, 0);
|
report_json_error(js, &je, 0);
|
||||||
return_null:
|
return_null:
|
||||||
|
thd->check_killed(); // to get the error message right
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2165,6 +2173,7 @@ String *Item_func_json_merge::val_str(String *str)
|
|||||||
json_engine_t je1, je2;
|
json_engine_t je1, je2;
|
||||||
String *js1= args[0]->val_json(&tmp_js1), *js2=NULL;
|
String *js1= args[0]->val_json(&tmp_js1), *js2=NULL;
|
||||||
uint n_arg;
|
uint n_arg;
|
||||||
|
THD *thd= current_thd;
|
||||||
LINT_INIT(js2);
|
LINT_INIT(js2);
|
||||||
|
|
||||||
if (args[0]->null_value)
|
if (args[0]->null_value)
|
||||||
@ -2181,9 +2190,11 @@ String *Item_func_json_merge::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
|
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
|
||||||
(const uchar *) js1->ptr() + js1->length());
|
(const uchar *) js1->ptr() + js1->length());
|
||||||
|
je1.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
|
json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
|
||||||
(const uchar *) js2->ptr() + js2->length());
|
(const uchar *) js2->ptr() + js2->length());
|
||||||
|
je2.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
if (do_merge(str, &je1, &je2))
|
if (do_merge(str, &je1, &je2))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
@ -2205,6 +2216,7 @@ String *Item_func_json_merge::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
|
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
|
||||||
(const uchar *) js1->ptr() + js1->length());
|
(const uchar *) js1->ptr() + js1->length());
|
||||||
|
je1.killed_ptr= (uchar*)&thd->killed;
|
||||||
if (json_nice(&je1, str, Item_func_json_format::LOOSE))
|
if (json_nice(&je1, str, Item_func_json_format::LOOSE))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
@ -2216,6 +2228,7 @@ error_return:
|
|||||||
report_json_error(js1, &je1, 0);
|
report_json_error(js1, &je1, 0);
|
||||||
if (je2.s.error)
|
if (je2.s.error)
|
||||||
report_json_error(js2, &je2, n_arg);
|
report_json_error(js2, &je2, n_arg);
|
||||||
|
thd->check_killed(); // to get the error message right
|
||||||
null_return:
|
null_return:
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2465,6 +2478,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
|
|||||||
String *js1= args[0]->val_json(&tmp_js1), *js2=NULL;
|
String *js1= args[0]->val_json(&tmp_js1), *js2=NULL;
|
||||||
uint n_arg;
|
uint n_arg;
|
||||||
bool empty_result, merge_to_null;
|
bool empty_result, merge_to_null;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
/* To report errors properly if some JSON is invalid. */
|
/* To report errors properly if some JSON is invalid. */
|
||||||
je1.s.error= je2.s.error= 0;
|
je1.s.error= je2.s.error= 0;
|
||||||
@ -2481,6 +2495,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
|
json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
|
||||||
(const uchar *) js2->ptr() + js2->length());
|
(const uchar *) js2->ptr() + js2->length());
|
||||||
|
je2.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
if (merge_to_null)
|
if (merge_to_null)
|
||||||
{
|
{
|
||||||
@ -2502,6 +2517,7 @@ String *Item_func_json_merge_patch::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
|
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
|
||||||
(const uchar *) js1->ptr() + js1->length());
|
(const uchar *) js1->ptr() + js1->length());
|
||||||
|
je1.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
if (do_merge_patch(str, &je1, &je2, &empty_result))
|
if (do_merge_patch(str, &je1, &je2, &empty_result))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
@ -2530,6 +2546,7 @@ cont_point:
|
|||||||
|
|
||||||
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
|
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
|
||||||
(const uchar *) js1->ptr() + js1->length());
|
(const uchar *) js1->ptr() + js1->length());
|
||||||
|
je1.killed_ptr= (uchar*)&thd->killed;
|
||||||
if (json_nice(&je1, str, Item_func_json_format::LOOSE))
|
if (json_nice(&je1, str, Item_func_json_format::LOOSE))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
@ -2541,6 +2558,7 @@ error_return:
|
|||||||
report_json_error(js1, &je1, 0);
|
report_json_error(js1, &je1, 0);
|
||||||
if (je2.s.error)
|
if (je2.s.error)
|
||||||
report_json_error(js2, &je2, n_arg);
|
report_json_error(js2, &je2, n_arg);
|
||||||
|
thd->check_killed(); // to get the error message right
|
||||||
null_return:
|
null_return:
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2777,6 +2795,7 @@ String *Item_func_json_insert::val_str(String *str)
|
|||||||
String *js= args[0]->val_json(&tmp_js);
|
String *js= args[0]->val_json(&tmp_js);
|
||||||
uint n_arg, n_path;
|
uint n_arg, n_path;
|
||||||
json_string_t key_name;
|
json_string_t key_name;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
DBUG_ASSERT(fixed());
|
DBUG_ASSERT(fixed());
|
||||||
|
|
||||||
@ -2817,6 +2836,7 @@ String *Item_func_json_insert::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr() + js->length());
|
(const uchar *) js->ptr() + js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
if (c_path->p.last_step < c_path->p.steps)
|
if (c_path->p.last_step < c_path->p.steps)
|
||||||
goto v_found;
|
goto v_found;
|
||||||
@ -2998,6 +3018,7 @@ continue_point:
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr() + js->length());
|
(const uchar *) js->ptr() + js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
if (json_nice(&je, str, Item_func_json_format::LOOSE))
|
if (json_nice(&je, str, Item_func_json_format::LOOSE))
|
||||||
goto js_error;
|
goto js_error;
|
||||||
|
|
||||||
@ -3005,6 +3026,7 @@ continue_point:
|
|||||||
|
|
||||||
js_error:
|
js_error:
|
||||||
report_json_error(js, &je, 0);
|
report_json_error(js, &je, 0);
|
||||||
|
thd->check_killed(); // to get the error message right
|
||||||
return_null:
|
return_null:
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -3028,6 +3050,7 @@ String *Item_func_json_remove::val_str(String *str)
|
|||||||
String *js= args[0]->val_json(&tmp_js);
|
String *js= args[0]->val_json(&tmp_js);
|
||||||
uint n_arg, n_path;
|
uint n_arg, n_path;
|
||||||
json_string_t key_name;
|
json_string_t key_name;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
DBUG_ASSERT(fixed());
|
DBUG_ASSERT(fixed());
|
||||||
|
|
||||||
@ -3074,6 +3097,7 @@ String *Item_func_json_remove::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr() + js->length());
|
(const uchar *) js->ptr() + js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
c_path->cur_step= c_path->p.steps;
|
c_path->cur_step= c_path->p.steps;
|
||||||
|
|
||||||
@ -3182,6 +3206,7 @@ v_found:
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr() + js->length());
|
(const uchar *) js->ptr() + js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
if (json_nice(&je, str, Item_func_json_format::LOOSE))
|
if (json_nice(&je, str, Item_func_json_format::LOOSE))
|
||||||
goto js_error;
|
goto js_error;
|
||||||
|
|
||||||
@ -3189,6 +3214,7 @@ v_found:
|
|||||||
return str;
|
return str;
|
||||||
|
|
||||||
js_error:
|
js_error:
|
||||||
|
thd->check_killed(); // to get the error message right
|
||||||
report_json_error(js, &je, 0);
|
report_json_error(js, &je, 0);
|
||||||
null_return:
|
null_return:
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
@ -3579,6 +3605,7 @@ String *Item_func_json_format::val_str(String *str)
|
|||||||
String *js= args[0]->val_json(&tmp_js);
|
String *js= args[0]->val_json(&tmp_js);
|
||||||
json_engine_t je;
|
json_engine_t je;
|
||||||
int tab_size= 4;
|
int tab_size= 4;
|
||||||
|
THD *thd= current_thd;
|
||||||
|
|
||||||
if ((null_value= args[0]->null_value))
|
if ((null_value= args[0]->null_value))
|
||||||
return 0;
|
return 0;
|
||||||
@ -3602,11 +3629,13 @@ String *Item_func_json_format::val_str(String *str)
|
|||||||
|
|
||||||
json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
|
json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
|
||||||
(const uchar *) js->ptr()+js->length());
|
(const uchar *) js->ptr()+js->length());
|
||||||
|
je.killed_ptr= (uchar*)&thd->killed;
|
||||||
|
|
||||||
if (json_nice(&je, str, fmt, tab_size))
|
if (json_nice(&je, str, fmt, tab_size))
|
||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
report_json_error(js, &je, 0);
|
report_json_error(js, &je, 0);
|
||||||
|
thd->check_killed(); // to get the error message right
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -807,10 +807,13 @@ static json_state_handler json_actions[NR_JSON_STATES][NR_C_CLASSES]=
|
|||||||
int json_scan_start(json_engine_t *je,
|
int json_scan_start(json_engine_t *je,
|
||||||
CHARSET_INFO *i_cs, const uchar *str, const uchar *end)
|
CHARSET_INFO *i_cs, const uchar *str, const uchar *end)
|
||||||
{
|
{
|
||||||
|
static const uchar no_time_to_die= 0;
|
||||||
|
|
||||||
json_string_setup(&je->s, i_cs, str, end);
|
json_string_setup(&je->s, i_cs, str, end);
|
||||||
je->stack[0]= JST_DONE;
|
je->stack[0]= JST_DONE;
|
||||||
je->stack_p= 0;
|
je->stack_p= 0;
|
||||||
je->state= JST_VALUE;
|
je->state= JST_VALUE;
|
||||||
|
je->killed_ptr = (uchar*)&no_time_to_die;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,7 +974,7 @@ int json_scan_next(json_engine_t *j)
|
|||||||
int t_next;
|
int t_next;
|
||||||
|
|
||||||
get_first_nonspace(&j->s, &t_next, &j->sav_c_len);
|
get_first_nonspace(&j->s, &t_next, &j->sav_c_len);
|
||||||
return json_actions[j->state][t_next](j);
|
return *j->killed_ptr || json_actions[j->state][t_next](j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user