mirror of
https://github.com/godotengine/godot.git
synced 2025-10-20 00:13:30 +00:00
Add uri_file_decode
to handle +
in file names.
This commit is contained in:
parent
af2c713971
commit
9abe2e5294
13 changed files with 52 additions and 10 deletions
|
@ -4707,6 +4707,29 @@ String String::uri_decode() const {
|
|||
return String::utf8(res);
|
||||
}
|
||||
|
||||
String String::uri_file_decode() const {
|
||||
CharString src = utf8();
|
||||
CharString res;
|
||||
for (int i = 0; i < src.length(); ++i) {
|
||||
if (src[i] == '%' && i + 2 < src.length()) {
|
||||
char ord1 = src[i + 1];
|
||||
if (is_digit(ord1) || is_ascii_upper_case(ord1)) {
|
||||
char ord2 = src[i + 2];
|
||||
if (is_digit(ord2) || is_ascii_upper_case(ord2)) {
|
||||
char bytes[3] = { (char)ord1, (char)ord2, 0 };
|
||||
res += (char)strtol(bytes, nullptr, 16);
|
||||
i += 2;
|
||||
}
|
||||
} else {
|
||||
res += src[i];
|
||||
}
|
||||
} else {
|
||||
res += src[i];
|
||||
}
|
||||
}
|
||||
return String::utf8(res);
|
||||
}
|
||||
|
||||
String String::c_unescape() const {
|
||||
String escaped = *this;
|
||||
escaped = escaped.replace("\\a", "\a");
|
||||
|
|
|
@ -572,6 +572,7 @@ public:
|
|||
String xml_unescape() const;
|
||||
String uri_encode() const;
|
||||
String uri_decode() const;
|
||||
String uri_file_decode() const;
|
||||
String c_escape() const;
|
||||
String c_escape_multiline() const;
|
||||
String c_unescape() const;
|
||||
|
|
|
@ -1790,6 +1790,7 @@ static void _register_variant_builtin_methods_string() {
|
|||
bind_string_method(xml_unescape, sarray(), varray());
|
||||
bind_string_method(uri_encode, sarray(), varray());
|
||||
bind_string_method(uri_decode, sarray(), varray());
|
||||
bind_string_method(uri_file_decode, sarray(), varray());
|
||||
bind_string_method(c_escape, sarray(), varray());
|
||||
bind_string_method(c_unescape, sarray(), varray());
|
||||
bind_string_method(json_escape, sarray(), varray());
|
||||
|
|
|
@ -1130,6 +1130,7 @@
|
|||
GD.Print(url.URIDecode()) // Prints "$DOCS_URL/?highlight=Godot Engine:docs"
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
[b]Note:[/b] This method decodes [code]+[/code] as space.
|
||||
</description>
|
||||
</method>
|
||||
<method name="uri_encode" qualifiers="const">
|
||||
|
@ -1152,6 +1153,12 @@
|
|||
[/codeblocks]
|
||||
</description>
|
||||
</method>
|
||||
<method name="uri_file_decode" qualifiers="const">
|
||||
<return type="String" />
|
||||
<description>
|
||||
Decodes the file path from its URL-encoded format. Unlike [method uri_decode] this method leaves [code]+[/code] as is.
|
||||
</description>
|
||||
</method>
|
||||
<method name="validate_filename" qualifiers="const">
|
||||
<return type="String" />
|
||||
<description>
|
||||
|
|
|
@ -1038,6 +1038,7 @@
|
|||
GD.Print(url.URIDecode()) // Prints "$DOCS_URL/?highlight=Godot Engine:docs"
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
[b]Note:[/b] This method decodes [code]+[/code] as space.
|
||||
</description>
|
||||
</method>
|
||||
<method name="uri_encode" qualifiers="const">
|
||||
|
@ -1060,6 +1061,12 @@
|
|||
[/codeblocks]
|
||||
</description>
|
||||
</method>
|
||||
<method name="uri_file_decode" qualifiers="const">
|
||||
<return type="String" />
|
||||
<description>
|
||||
Decodes the file path from its URL-encoded format. Unlike [method uri_decode] this method leaves [code]+[/code] as is.
|
||||
</description>
|
||||
</method>
|
||||
<method name="validate_filename" qualifiers="const">
|
||||
<return type="String" />
|
||||
<description>
|
||||
|
|
|
@ -257,7 +257,7 @@ static void _get_drives(List<String> *list) {
|
|||
// Parse only file:// links
|
||||
if (strncmp(string, "file://", 7) == 0) {
|
||||
// Strip any unwanted edges on the strings and push_back if it's not a duplicate.
|
||||
String fpath = String::utf8(string + 7).strip_edges().split_spaces()[0].uri_decode();
|
||||
String fpath = String::utf8(string + 7).strip_edges().split_spaces()[0].uri_file_decode();
|
||||
if (!list->find(fpath)) {
|
||||
list->push_back(fpath);
|
||||
}
|
||||
|
|
|
@ -288,7 +288,7 @@ void Collada::_parse_image(XMLParser &p_parser) {
|
|||
String path = p_parser.get_named_attribute_value("source").strip_edges();
|
||||
if (!path.contains("://") && path.is_relative_path()) {
|
||||
// path is relative to file being loaded, so convert to a resource path
|
||||
image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().path_join(path.uri_decode()));
|
||||
image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().path_join(path.uri_file_decode()));
|
||||
}
|
||||
} else {
|
||||
while (p_parser.read() == OK) {
|
||||
|
@ -297,7 +297,7 @@ void Collada::_parse_image(XMLParser &p_parser) {
|
|||
|
||||
if (name == "init_from") {
|
||||
p_parser.read();
|
||||
String path = p_parser.get_node_data().strip_edges().uri_decode();
|
||||
String path = p_parser.get_node_data().strip_edges().uri_file_decode();
|
||||
|
||||
if (!path.contains("://") && path.is_relative_path()) {
|
||||
// path is relative to file being loaded, so convert to a resource path
|
||||
|
|
|
@ -559,8 +559,8 @@ Error GDScriptWorkspace::parse_local_script(const String &p_path) {
|
|||
}
|
||||
|
||||
String GDScriptWorkspace::get_file_path(const String &p_uri) const {
|
||||
String path = p_uri.uri_decode();
|
||||
String base_uri = root_uri.uri_decode();
|
||||
String path = p_uri.uri_file_decode();
|
||||
String base_uri = root_uri.uri_file_decode();
|
||||
path = path.replacen(base_uri + "/", "res://");
|
||||
return path;
|
||||
}
|
||||
|
|
|
@ -812,7 +812,7 @@ Error GLTFDocument::_parse_buffers(Ref<GLTFState> p_state, const String &p_base_
|
|||
buffer_data = _parse_base64_uri(uri);
|
||||
} else { // Relative path to an external image file.
|
||||
ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER);
|
||||
uri = uri.uri_decode();
|
||||
uri = uri.uri_file_decode();
|
||||
uri = p_base_path.path_join(uri).replace("\\", "/"); // Fix for Windows.
|
||||
ERR_FAIL_COND_V_MSG(!FileAccess::exists(uri), ERR_FILE_NOT_FOUND, "glTF: Binary file not found: " + uri);
|
||||
buffer_data = FileAccess::get_file_as_bytes(uri);
|
||||
|
@ -4123,7 +4123,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p
|
|||
}
|
||||
} else { // Relative path to an external image file.
|
||||
ERR_FAIL_COND_V(p_base_path.is_empty(), ERR_INVALID_PARAMETER);
|
||||
uri = uri.uri_decode();
|
||||
uri = uri.uri_file_decode();
|
||||
uri = p_base_path.path_join(uri).replace("\\", "/"); // Fix for Windows.
|
||||
resource_uri = uri.simplify_path();
|
||||
// ResourceLoader will rely on the file extension to use the relevant loader.
|
||||
|
|
|
@ -473,7 +473,7 @@ bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_it
|
|||
while (dbus_message_iter_get_arg_type(&uri_iter) == DBUS_TYPE_STRING) {
|
||||
const char *value;
|
||||
dbus_message_iter_get_basic(&uri_iter, &value);
|
||||
r_urls.push_back(String::utf8(value).trim_prefix("file://").uri_decode());
|
||||
r_urls.push_back(String::utf8(value).trim_prefix("file://").uri_file_decode());
|
||||
if (!dbus_message_iter_next(&uri_iter)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2147,7 +2147,7 @@ void WaylandThread::_wl_data_device_on_drop(void *data, struct wl_data_device *w
|
|||
|
||||
msg->files = String::utf8((const char *)list_data.ptr(), list_data.size()).split("\r\n", false);
|
||||
for (int i = 0; i < msg->files.size(); i++) {
|
||||
msg->files.write[i] = msg->files[i].replace("file://", "").uri_decode();
|
||||
msg->files.write[i] = msg->files[i].replace("file://", "").uri_file_decode();
|
||||
}
|
||||
|
||||
wayland_thread->push_message(msg);
|
||||
|
|
|
@ -5321,7 +5321,7 @@ void DisplayServerX11::process_events() {
|
|||
Vector<String> files = String((char *)p.data).split("\r\n", false);
|
||||
XFree(p.data);
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
files.write[i] = files[i].replace("file://", "").uri_decode();
|
||||
files.write[i] = files[i].replace("file://", "").uri_file_decode();
|
||||
}
|
||||
|
||||
if (windows[window_id].drop_files_callback.is_valid()) {
|
||||
|
|
|
@ -1774,6 +1774,7 @@ TEST_CASE("[String] uri_encode/unescape") {
|
|||
static const uint8_t u8str[] = { 0x54, 0xC4, 0x93, 0xC5, 0xA1, 0x74, 0x00 };
|
||||
String x2 = String::utf8((const char *)u8str);
|
||||
String x3 = U"Tēšt";
|
||||
String x4 = U"file+name";
|
||||
|
||||
CHECK(x1.uri_decode() == x2);
|
||||
CHECK(x1.uri_decode() == x3);
|
||||
|
@ -1783,6 +1784,8 @@ TEST_CASE("[String] uri_encode/unescape") {
|
|||
|
||||
CHECK(s.uri_encode() == t);
|
||||
CHECK(t.uri_decode() == s);
|
||||
CHECK(x4.uri_file_decode() == x4);
|
||||
CHECK(x4.uri_decode() == U"file name");
|
||||
}
|
||||
|
||||
TEST_CASE("[String] xml_escape/unescape") {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue