--- parser3/src/classes/json.C 2012/05/28 19:47:52 1.21 +++ parser3/src/classes/json.C 2012/06/04 13:46:18 1.23 @@ -18,7 +18,7 @@ #include "pa_vxdoc.h" #endif -volatile const char * IDENT_JSON_C="$Id: json.C,v 1.21 2012/05/28 19:47:52 moko Exp $"; +volatile const char * IDENT_JSON_C="$Id: json.C,v 1.23 2012/06/04 13:46:18 moko Exp $"; // class @@ -44,10 +44,13 @@ struct Json { Request* request; Charset *charset; + String::Language taint; + bool handle_double; enum Distinct { D_EXCEPTION, D_FIRST, D_LAST, D_ALL } distinct; - Json(Charset* acharset): stack(), key_stack(), key(NULL), result(NULL), hook_object(NULL), hook_array(NULL), request(NULL), charset(acharset), handle_double(true), distinct(D_EXCEPTION){} + Json(Charset* acharset): stack(), key_stack(), key(NULL), result(NULL), hook_object(NULL), hook_array(NULL), + request(NULL), charset(acharset), taint(String::L_TAINTED), handle_double(true), distinct(D_EXCEPTION){} bool set_distinct(const String &value){ if (value == "first") distinct = D_FIRST; @@ -90,9 +93,9 @@ static void set_json_value(Json *json, V String* json_string(Json *json, const JSON_value* value){ String::C result = json->charset !=NULL ? - Charset::transcode(String::C(value->vu.str.value, value->vu.str.length), UTF8_charset, *json->charset) : - String::C(pa_strdup(value->vu.str.value, value->vu.str.length), value->vu.str.length); - return new String(result.str, String::L_TAINTED, result.length); + Charset::transcode(String::C(value->vu.str.value, value->vu.str.length), UTF8_charset, *json->charset) : + String::C(pa_strdup(value->vu.str.value, value->vu.str.length), value->vu.str.length); + return new String(result.str, json->taint, result.length); } static Value *json_hook(Request &r, Junction *hook, String* key, Value* value){ @@ -202,6 +205,8 @@ static const char* json_error_message(in return error_messages[error_code]; } +extern String::Language get_untaint_lang(const String& lang_name); + static void _parse(Request& r, MethodParams& params) { const String& json_string=params.as_string(0, "json must be string"); @@ -233,6 +238,10 @@ static void _parse(Request& r, MethodPar throw Exception(PARSER_RUNTIME, &sdistinct, "must be 'first', 'last' or 'all'"); valid_options++; } + if(Value* value=options->get("taint")) { + json.taint=get_untaint_lang(value->as_string()); + valid_options++; + } if(Value* value=options->get("object")) { json.hook_object=value->get_junction(); json.request=&r; @@ -389,12 +398,6 @@ static void _string(Request& r, MethodPa json.xdoc_options=new XDocOutputOptions(r, vvalue); valid_options++; #endif - } else if(key == "default"){ - Junction* junction=value->get_junction(); - if(!junction || !junction->method || !junction->method->params_names || junction->method->params_names->count() != 3) - throw Exception(PARSER_RUNTIME, 0, "$.%s must be parser method with 3 parameters", key.cstr()); - json.default_method=value; - valid_options++; } else if(Junction* junction=value->get_junction()){ if(!junction->method || !junction->method->params_names || junction->method->params_names->count() != 3) throw Exception(PARSER_RUNTIME, 0, "$.%s must be parser method with 3 parameters", key.cstr()); @@ -402,8 +405,19 @@ static void _string(Request& r, MethodPa valid_options++; } } + if(valid_options!=options->count()) throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION); + + // special handling for $._default + if(VHash* vhash=static_cast(params[1].as(VHASH_TYPE))) + if(Value* value=vhash->get_default()) { + Junction* junction=value->get_junction(); + if(!junction || !junction->method || !junction->method->params_names || junction->method->params_names->count() != 3) + throw Exception(PARSER_RUNTIME, 0, "$.%s must be parser method with 3 parameters", HASH_DEFAULT_ELEMENT_NAME); + json.default_method=value; + } + if(methods->count()) json.methods=methods; }