| 330 | } |
| 331 | |
| 332 | static bool parse_server_options_json(FOREIGN_SERVER *server, char *ptr) |
| 333 | { |
| 334 | enum json_types vt; |
| 335 | const char *keyname, *keyname_end, *v; |
| 336 | int v_len, nkey= 0; |
| 337 | engine_option_value *option_list_last; |
| 338 | DBUG_ENTER("parse_server_options_json"); |
| 339 | while ((vt= json_get_object_nkey(ptr, ptr+strlen(ptr), nkey++, |
| 340 | &keyname, &keyname_end, &v, &v_len)) != JSV_NOTHING) |
| 341 | { |
| 342 | if (vt != JSV_STRING) |
| 343 | DBUG_RETURN(TRUE); |
| 344 | /* |
| 345 | We have to make copies here to create "clean" strings and |
| 346 | avoid mutating ptr. |
| 347 | */ |
| 348 | Lex_cstring name= {keyname, keyname_end}, value= {v, v + v_len}, |
| 349 | name_copy= safe_lexcstrdup_root(&mem, name), |
| 350 | value_copy= safe_lexcstrdup_root(&mem, value); |
| 351 | engine_option_value *option= new (&mem) engine_option_value( |
| 352 | engine_option_value::Name(name_copy), |
| 353 | engine_option_value::Value(value_copy), true); |
| 354 | option->link(&server->option_list, &option_list_last); |
| 355 | if (option->value.length) |
| 356 | { |
| 357 | LEX_CSTRING *optval= &option->value; |
| 358 | char *unescaped= (char *) alloca(optval->length); |
| 359 | int len= json_unescape_json(optval->str, optval->str + optval->length, |
| 360 | unescaped, unescaped + optval->length); |
| 361 | if (len < 0) |
| 362 | DBUG_RETURN(TRUE); |
| 363 | DBUG_ASSERT(len <= (int) optval->length); |
| 364 | if (len < (int) optval->length) |
| 365 | strncpy((char *) optval->str, unescaped, len); |
| 366 | optval->length= len; |
| 367 | } |
| 368 | } |
| 369 | DBUG_RETURN(FALSE); |
| 370 | } |
| 371 | |
| 372 | /* |
| 373 | Initialize structures responsible for servers used in federated |
no test coverage detected