diff options
-rw-r--r-- | core/io/http_client.cpp | 22 | ||||
-rw-r--r-- | core/ustring.cpp | 74 | ||||
-rw-r--r-- | core/ustring.h | 7 | ||||
-rw-r--r-- | doc/classes/HTTPClient.xml | 6 | ||||
-rw-r--r-- | editor/plugins/asset_library_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | modules/gdnative/gdnative/string.cpp | 18 | ||||
-rw-r--r-- | modules/gdnative/gdnative_api.json | 14 | ||||
-rw-r--r-- | modules/gdnative/include/gdnative/string.h | 7 |
8 files changed, 38 insertions, 112 deletions
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 4d72f744e1..c787b7ec4c 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -618,7 +618,27 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { String query = ""; Array keys = p_dict.keys(); for (int i = 0; i < keys.size(); ++i) { - query += "&" + String(keys[i]).http_escape() + "=" + String(p_dict[keys[i]]).http_escape(); + String encoded_key = String(keys[i]).percent_encode(); + Variant value = p_dict[keys[i]]; + switch (value.get_type()) { + case Variant::ARRAY: { + // Repeat the key with every values + Array values = value; + for (int j = 0; j < values.size(); ++j) { + query += "&" + encoded_key + "=" + String(values[j]).percent_encode(); + } + break; + } + case Variant::NIL: { + // Add the key with no value + query += "&" + encoded_key; + break; + } + default: { + // Add the key-value pair + query += "&" + encoded_key + "=" + String(value).percent_encode(); + } + } } query.erase(0, 1); return query; diff --git a/core/ustring.cpp b/core/ustring.cpp index a7a7810837..d749146998 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3165,11 +3165,11 @@ String String::word_wrap(int p_chars_per_line) const { return ret; } -String String::http_escape() const { +String String::percent_encode() const { const CharString temp = utf8(); String res; - for (int i = 0; i < length(); ++i) { - CharType ord = temp[i]; + for (int i = 0; i < temp.length(); ++i) { + char ord = temp[i]; if (ord == '.' || ord == '-' || ord == '_' || ord == '~' || (ord >= 'a' && ord <= 'z') || (ord >= 'A' && ord <= 'Z') || @@ -3178,9 +3178,9 @@ String String::http_escape() const { } else { char h_Val[3]; #if defined(__GNUC__) || defined(_MSC_VER) - snprintf(h_Val, 3, "%.2X", ord); + snprintf(h_Val, 3, "%hhX", ord); #else - sprintf(h_Val, "%.2X", ord); + sprintf(h_Val, "%hhX", ord); #endif res += "%"; res += h_Val; @@ -3189,7 +3189,7 @@ String String::http_escape() const { return res; } -String String::http_unescape() const { +String String::percent_decode() const { String res; for (int i = 0; i < length(); ++i) { if (ord_at(i) == '%' && i + 2 < length()) { @@ -3727,68 +3727,6 @@ String String::plus_file(const String &p_file) const { return *this + "/" + p_file; } -String String::percent_encode() const { - - CharString cs = utf8(); - String encoded; - for (int i = 0; i < cs.length(); i++) { - uint8_t c = cs[i]; - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '~' || c == '.') { - - char p[2] = { (char)c, 0 }; - encoded += p; - } else { - char p[4] = { '%', 0, 0, 0 }; - static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - - p[1] = hex[c >> 4]; - p[2] = hex[c & 0xF]; - encoded += p; - } - } - - return encoded; -} -String String::percent_decode() const { - - CharString pe; - - CharString cs = utf8(); - for (int i = 0; i < cs.length(); i++) { - - uint8_t c = cs[i]; - if (c == '%' && i < length() - 2) { - - uint8_t a = LOWERCASE(cs[i + 1]); - uint8_t b = LOWERCASE(cs[i + 2]); - - c = 0; - if (a >= '0' && a <= '9') - c = (a - '0') << 4; - else if (a >= 'a' && a <= 'f') - c = (a - 'a' + 10) << 4; - else - continue; - - uint8_t d = 0; - - if (b >= '0' && b <= '9') - d = (b - '0'); - else if (b >= 'a' && b <= 'f') - d = (b - 'a' + 10); - else - continue; - c += d; - i += 2; - } - pe.push_back(c); - } - - pe.push_back(0); - - return String::utf8(pe.ptr()); -} - String String::get_basename() const { int pos = find_last("."); diff --git a/core/ustring.h b/core/ustring.h index bb676ce623..8023c9b95d 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -226,17 +226,14 @@ public: String xml_escape(bool p_escape_quotes = false) const; String xml_unescape() const; - String http_escape() const; - String http_unescape() const; + String percent_encode() const; + String percent_decode() const; String c_escape() const; String c_escape_multiline() const; String c_unescape() const; String json_escape() const; String word_wrap(int p_chars_per_line) const; - String percent_encode() const; - String percent_decode() const; - bool is_valid_identifier() const; bool is_valid_integer() const; bool is_valid_float() const; diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml index 5bd7c4cd3e..018b548ef1 100644 --- a/doc/classes/HTTPClient.xml +++ b/doc/classes/HTTPClient.xml @@ -111,6 +111,12 @@ String queryString = httpClient.query_string_from_dict(fields) returns:= "username=user&password=pass" [/codeblock] + Furthermore, if a key has a null value, only the key itself is added, without equal sign and value. If the value is an array, for each value in it a pair with the same key is added. + [codeblock] + var fields = {"single": 123, "not_valued": null, "multiple": [22, 33, 44]} + String queryString = httpClient.query_string_from_dict(fields) + returns:= "single=123&not_valued&multiple=22&multiple=33&multiple=44" + [/codeblock] </description> </method> <method name="read_response_body_chunk"> diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index c203b4b81e..b72c9b25be 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -902,7 +902,7 @@ void EditorAssetLibrary::_search(int p_page) { } if (filter->get_text() != String()) { - args += "&filter=" + filter->get_text().http_escape(); + args += "&filter=" + filter->get_text().percent_encode(); } if (p_page > 0) { diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 7f5dbc12be..ab0f0e0a50 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -1168,24 +1168,6 @@ godot_string GDAPI godot_string_c_unescape(const godot_string *p_self) { return result; } -godot_string GDAPI godot_string_http_escape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->http_escape(); - memnew_placement(&result, String(return_value)); - - return result; -} - -godot_string GDAPI godot_string_http_unescape(const godot_string *p_self) { - const String *self = (const String *)p_self; - godot_string result; - String return_value = self->http_unescape(); - memnew_placement(&result, String(return_value)); - - return result; -} - godot_string GDAPI godot_string_json_escape(const godot_string *p_self) { const String *self = (const String *)p_self; godot_string result; diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index f41c3859bd..9da2a69360 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -5468,20 +5468,6 @@ ] }, { - "name": "godot_string_http_escape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { - "name": "godot_string_http_unescape", - "return_type": "godot_string", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { "name": "godot_string_json_escape", "return_type": "godot_string", "arguments": [ diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h index 73245160c1..8fc59e21da 100644 --- a/modules/gdnative/include/gdnative/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -228,17 +228,14 @@ godot_string GDAPI godot_string_simplify_path(const godot_string *p_self); godot_string GDAPI godot_string_c_escape(const godot_string *p_self); godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self); godot_string GDAPI godot_string_c_unescape(const godot_string *p_self); -godot_string GDAPI godot_string_http_escape(const godot_string *p_self); -godot_string GDAPI godot_string_http_unescape(const godot_string *p_self); +godot_string GDAPI godot_string_percent_decode(const godot_string *p_self); +godot_string GDAPI godot_string_percent_encode(const godot_string *p_self); godot_string GDAPI godot_string_json_escape(const godot_string *p_self); godot_string GDAPI godot_string_word_wrap(const godot_string *p_self, godot_int p_chars_per_line); godot_string GDAPI godot_string_xml_escape(const godot_string *p_self); godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self); godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self); -godot_string GDAPI godot_string_percent_decode(const godot_string *p_self); -godot_string GDAPI godot_string_percent_encode(const godot_string *p_self); - godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self); godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix); godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self); |