/* * Parse char by char QUERY_STRING request and return an array key/value * (key are all lowercase) */ array *cgi_parse_kvp(ows * o, char *query) { int i; bool in_key; buffer *key; buffer *val; array *arr; char string[2]; assert(o); assert(query); key = buffer_init(); val = buffer_init(); arr = array_init(); in_key = true; cgi_unescape_url(query); cgi_remove_crlf(query); cgi_plustospace(query); for (i = 0; i < CGI_QUERY_MAX && query[i] ; i++) { if (query[i] == '&') { in_key = true; array_add(arr, key, val); key = buffer_init(); val = buffer_init(); } else if (query[i] == '=') { /* char '=' inside filter key mustn't be taken into account */ if ((!buffer_case_cmp(key, "filter") || !buffer_case_cmp(key, "outputformat")) && buffer_cmp(val, "")) in_key = false; else buffer_add(val, query[i]); } /* Check characters'CGI request */ else { /* to check the regular expression, argument must be a string, not a char */ string[0] = query[i]; string[1] = '\0'; if (in_key) { /* if word is key, only letters are allowed */ if (check_regexp(string, "[A-Za-zà-ÿ]")) buffer_add(key, tolower(query[i])); else { buffer_free(key); buffer_free(val); array_free(arr); ows_error(o, OWS_ERROR_MISSING_PARAMETER_VALUE, "QUERY_STRING contains forbidden characters", "request"); return NULL; } } else { /* if word is filter key, more characters are allowed */ if ( check_regexp(string, "[A-Za-zà-ÿ0-9.\\=;,():/\\*_ \\-]") || (buffer_cmp(key, "filter") && check_regexp(string, "[A-Za-zà-ÿ0-9.#\\,():/_<> %\"\'=\\*!\\-]|\\[|\\]"))) buffer_add(val, query[i]); else { buffer_free(key); buffer_free(val); array_free(arr); ows_error(o, OWS_ERROR_MISSING_PARAMETER_VALUE, "QUERY_STRING contains forbidden characters", "request"); return NULL; } } } } if (i == CGI_QUERY_MAX) { buffer_free(key); buffer_free(val); array_free(arr); ows_error(o, OWS_ERROR_REQUEST_HTTP, "QUERY_STRING too long", "request"); return NULL; } array_add(arr, key, val); return arr; }
static void cgi_store_data_urlencoded(MCExecPoint& ep, MCVariable *p_variable, const char *p_data_start, const char *p_data_end, bool p_native_encoding, char p_delimiter, bool p_remove_whitespace) { const char *t_data; t_data = p_data_start; while(t_data < p_data_end) { const char *t_encoded_key; t_encoded_key = t_data; if (p_remove_whitespace) while (t_encoded_key[0] == ' ') t_encoded_key++; const char *t_end; t_end = strchr_limit(t_encoded_key, p_data_end, p_delimiter); const char *t_encoded_key_end; t_encoded_key_end = strchr_limit(t_encoded_key, t_end, '='); const char *t_encoded_value; if (t_encoded_key_end != t_end) t_encoded_value = t_encoded_key_end + 1; else t_encoded_value = t_encoded_key_end; char *t_key_start, *t_key_finish; cgi_unescape_url(t_encoded_key, t_encoded_key_end, t_key_start, t_key_finish); const char *t_encoded_value_end; t_encoded_value_end = t_end; if (p_remove_whitespace) while (t_encoded_value_end > t_encoded_value && *(t_encoded_value - 1) == ' ') t_encoded_value_end--; char *t_value_start, *t_value_finish; cgi_unescape_url(t_encoded_value, t_encoded_value_end, t_value_start, t_value_finish); // MM-2011-07-13: Added p_native_encoding flag that specifies if the text should // be converted from the outputTextEncoding to the native character set. // IM-2011-07-13 convert from MCserveroutputtextencoding to native if (!p_native_encoding || MCserveroutputtextencoding == kMCSOutputTextEncodingNative) ep . grabbuffer(t_value_start, t_value_finish - t_value_start); else { uint32_t t_native_length; char *t_native = NULL; if (cgi_native_from_encoding(MCserveroutputtextencoding, t_value_start, t_value_finish - t_value_start, t_native, t_native_length)) ep . grabbuffer(t_native, t_native_length); MCCStringFree(t_value_start); } cgi_store_control_value(p_variable, t_key_start, t_key_finish - t_key_start, ep); delete t_key_start; if (t_end != p_data_end) t_end += 1; t_data = t_end; } }