-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
When attempting to create a Uri with a base64 encoded path segment value that is NOT URL safe (i.e containing illegal characters), it does not encode it (or double-encodes it when encoding it prior to creating the instance), when either creating a URI from scratch, or when replacing an existing one.
In other words, when encoding the base64 value using Uri.encodeComponent and creating the Uri using Uri.parse, it properly converts the unsafe == into properly encoded %3D%3D characters.
However, when creating the Uri either from its constructor, or when calling replace on an existing one, when placing an unencoded base64 value as a path segment, it returns == when calling toString on the resulting instance. Furthermore, when encoding the value using Uri.encodeComponent and placing it as a path segment, it double-encodes the already encoded %3D%3D value to %253D%253D instead.
Here is code that highlights this issue:
void main() {
final baseUri = Uri(
scheme: "https",
host: "www.something.com",
pathSegments: ["share"],
);
// Given an unsafe base64 URL value
const unsafeBase64UrlValue = "c29tZSB2YWx1ZQ==";
// When encoding it for use in a URL.
final encoded = Uri.encodeComponent(unsafeBase64UrlValue);
// Properly retains the parsed URL's encoded path segments.
final properlyEncoded =
Uri.parse("https://www.something.com/share/$encoded").replace(
queryParameters: {
"foo": "bar",
},
);
print("Properly encoded base64 path URI: ${properlyEncoded.toString()}");
// Does not encode the unsafe base64 path segment
final unencodedBase64PathUri = baseUri.replace(
pathSegments: [
"share",
unsafeBase64UrlValue,
],
queryParameters: {
"foo": "bar",
},
);
print("Unencoded base64 path URI: ${unencodedBase64PathUri.toString()}");
// Double encodes the encoded base64 path segment
final doubleEncodedBase64PathUri = baseUri.replace(
pathSegments: [
"share",
encoded,
],
queryParameters: {
"foo": "bar",
},
);
print(
"Double encoded base64 path URI: ${doubleEncodedBase64PathUri.toString()}");
}Also available as a DartPad.
Currently running the following Dart version on macOS 14.5:
Dart SDK version: 3.5.3 (stable) (Wed Sep 11 16:22:47 2024 +0000) on "macos_arm64"