From 81e6440fe1febef9a1cc315ddecda395158d7009 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Tue, 10 Feb 2026 23:59:19 +0100 Subject: [PATCH] Core: UrlEncodePath, CtrlCore: Clipboard AppenFiles now using UrlEncodePath --- uppsrc/Core/Inet.h | 7 +++- uppsrc/Core/InetUtil.cpp | 32 ++++++++++++++++-- uppsrc/Core/src.tpp/Inet_en-us.tpp | 54 +++++++++++++++++++++++++----- uppsrc/CtrlCore/GtkClip.cpp | 2 +- 4 files changed, 82 insertions(+), 13 deletions(-) diff --git a/uppsrc/Core/Inet.h b/uppsrc/Core/Inet.h index 37084eea6..a43722bb8 100644 --- a/uppsrc/Core/Inet.h +++ b/uppsrc/Core/Inet.h @@ -4,9 +4,14 @@ Time ScanWwwTime(const char *s); String MIMECharsetName(byte charset); -String UrlEncode(const char *s, const char *end); +String UrlEncode(const char *p, const char *e); String UrlEncode(const char *s, int len); String UrlEncode(const String& s); + +String UrlEncodePath(const char *p, const char *e); +String UrlEncodePath(const char *s, int len); +String UrlEncodePath(const String& s); + String UrlDecode(const char *s, const char *end, bool plus_is_space = true); String UrlDecode(const char *s, int len, bool plus_is_space = true); String UrlDecode(const String& s, bool plus_is_space = true); diff --git a/uppsrc/Core/InetUtil.cpp b/uppsrc/Core/InetUtil.cpp index b3e97c382..c6e55976f 100644 --- a/uppsrc/Core/InetUtil.cpp +++ b/uppsrc/Core/InetUtil.cpp @@ -105,7 +105,8 @@ String MIMECharsetName(byte charset) static const char hex_digits[] = "0123456789ABCDEF"; -String UrlEncode(const char *p, const char *e) +static +String UrlEncode_(const char *p, const char *e, bool path) { StringBuffer out; out.Reserve((int)(e - p)); @@ -113,8 +114,12 @@ String UrlEncode(const char *p, const char *e) { const char *b = p; while(p < e && (byte)*p > ' ' && (byte)*p < 127 - && (IsAlNum(*p) || *p == '.' || *p == '-' || *p == '_')) + && (IsAlNum(*p) || *p == '.' || *p == '-' || *p == '_' || path && *p == '/')) p++; + if(*p == '?' && path) { + p++; + path = false; + } if(p > b) out.Cat(b, int(p - b)); if(p >= e) @@ -124,9 +129,14 @@ String UrlEncode(const char *p, const char *e) return String(out); } +String UrlEncode(const char *p, const char *e) +{ + return UrlEncode_(p, e, false); +} + String UrlEncode(const char *s, int len) { - return UrlEncode(s, s + len); + return UrlEncode_(s, s + len, false); } String UrlEncode(const String& s) @@ -134,6 +144,22 @@ String UrlEncode(const String& s) return UrlEncode(~s, s.GetLength()); } +String UrlEncodePath(const char *p, const char *e) +{ + return UrlEncode_(p, e, true); +} + +String UrlEncodePath(const char *s, int len) +{ + return UrlEncode_(s, s + len, true); +} + +String UrlEncodePath(const String& s) +{ + return UrlEncodePath(~s, s.GetLength()); +} + + String UrlDecode(const char *b, const char *e, bool plus_is_space) { StringBuffer out; diff --git a/uppsrc/Core/src.tpp/Inet_en-us.tpp b/uppsrc/Core/src.tpp/Inet_en-us.tpp index 4abb6cfec..645595d8d 100644 --- a/uppsrc/Core/src.tpp/Inet_en-us.tpp +++ b/uppsrc/Core/src.tpp/Inet_en-us.tpp @@ -33,18 +33,56 @@ set])&] [s2;%% Returns U`+`+ [%-*@3 charset] formatted as required by MIME.&] [s3;%% &] [s4; &] -[s5;:UrlEncode`(const char`*`,const char`*`): [_^String^ String]_[* UrlEncode]([@(0.0.255) c -onst]_[@(0.0.255) char]_`*[*@3 s], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 end])&] -[s5;:UrlEncode`(const char`*`,int`): [_^String^ String]_[* UrlEncode]([@(0.0.255) const]_[@(0.0.255) c -har]_`*[*@3 s], [@(0.0.255) int]_[*@3 len])&] -[s5;:UrlEncode`(const String`&`): [_^String^ String]_[* UrlEncode]([@(0.0.255) const]_[_^String^ S -tring][@(0.0.255) `&]_[*@3 s])&] +[s5;:Upp`:`:UrlEncode`(const char`*`,const char`*`): String [* UrlEncode]([@(0.0.255) con +st] [@(0.0.255) char] [@(0.0.255) `*][*@3 p], [@(0.0.255) const] [@(0.0.255) char] +[@(0.0.255) `*][*@3 e])&] +[s2;%% [%-*@3 p] [%-*@3 e] .&] +[s3; &] +[s4; &] +[s5;:Upp`:`:UrlEncode`(const char`*`,int`): String [* UrlEncode]([@(0.0.255) const] +[@(0.0.255) char] [@(0.0.255) `*][*@3 s], [@(0.0.255) int] [*@3 len])&] +[s2;%% [%-*@3 s] [%-*@3 len] .&] +[s3; &] +[s4; &] +[s5;:Upp`:`:UrlEncode`(const String`&`): String [* UrlEncode]([@(0.0.255) const] +String[@(0.0.255) `&] [*@3 s])&] +[s2;%% [%-*@3 s] .&] +[s3; &] +[s4; &] +[s5;:Upp`:`:UrlEncodePath`(const char`*`,const char`*`): String [* UrlEncodePath]([@(0.0.255) c +onst] [@(0.0.255) char] [@(0.0.255) `*][*@3 p], [@(0.0.255) const] [@(0.0.255) char] +[@(0.0.255) `*][*@3 e])&] +[s2;%% [%-*@3 p] [%-*@3 e] .&] +[s3; &] +[s4; &] +[s5;:Upp`:`:UrlEncodePath`(const char`*`,int`): String [* UrlEncodePath]([@(0.0.255) cons +t] [@(0.0.255) char] [@(0.0.255) `*][*@3 s], [@(0.0.255) int] [*@3 len])&] +[s2;%% [%-*@3 s] [%-*@3 len] .&] +[s3; &] +[s4; &] +[s5;:Upp`:`:UrlEncodePath`(const String`&`): String [* UrlEncodePath]([@(0.0.255) const] +String[@(0.0.255) `&] [*@3 s])&] +[s2;%% [%-*@3 s] .&] +[s3; &] +[s4; &] +[s5;:Upp`:`:UrlEncode`(const char`*`,const char`*`,bool`): String +[* UrlEncode]([@(0.0.255) const] [@(0.0.255) char] [@(0.0.255) `*][*@3 p], +[@(0.0.255) const] [@(0.0.255) char] [@(0.0.255) `*][*@3 e], [@(0.0.255) bool] +[*@3 keepslash] [@(0.0.255) `=] [@(0.0.255) false])&] +[s5;:Upp`:`:UrlEncode`(const char`*`,int`,bool`): String [* UrlEncode]([@(0.0.255) const] +[@(0.0.255) char] [@(0.0.255) `*][*@3 s], [@(0.0.255) int] [*@3 len], [@(0.0.255) bool] +[*@3 keepslash] [@(0.0.255) `=] [@(0.0.255) false])&] +[s5;:Upp`:`:UrlEncode`(const String`&`,bool`): String [* UrlEncode]([@(0.0.255) const] +String[@(0.0.255) `&] [*@3 s], [@(0.0.255) bool] [*@3 keepslash] [@(0.0.255) `=] +[@(0.0.255) false])&] [s2;%% Encodes data as required by [^http`:`/`/www`.w3`.org`/TR`/html401`/interact`/forms`.html`#h`-17`.13`.4`.1^ M IME type application/x`-www`-form`-urlencoded]. ASCII alphanumeric characters and characters `'.`', `'`-`', `'`_`' are passed directly, space is represented by `'`+`' and anything else as %HH, where -HH is two digit hexadecimal number.&] -[s3;%% &] +HH is two digit hexadecimal number. If [%-*@3 keepslash] is true, +`'/`' is also passed directly (this is usually required when +sanitizing path).&] +[s3; &] [s4; &] [s5;:Upp`:`:UrlDecode`(const char`*`,const char`*`,bool`): String [* UrlDecode]([@(0.0.255) const] [@(0.0.255) char] [@(0.0.255) `*][*@3 b], diff --git a/uppsrc/CtrlCore/GtkClip.cpp b/uppsrc/CtrlCore/GtkClip.cpp index 2419455d7..98af27ef8 100644 --- a/uppsrc/CtrlCore/GtkClip.cpp +++ b/uppsrc/CtrlCore/GtkClip.cpp @@ -385,7 +385,7 @@ void AppendFiles(VectorMap& data, const Vector& files) return; String h; for(String f : files) - h << "file://" << UrlEncode(f) << '\n'; + h << "file://" << UrlEncodePath(f) << '\n'; data.GetAdd("files") = h; }