Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(614)

Unified Diff: sdk/lib/core/uri.dart

Issue 94733003: Add encodimg argument to Uri.encodeQueryString (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review commetns Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/core/core.dart ('k') | tests/corelib/uri_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/core/uri.dart
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index f645d2c003eab2830697bf5bb8c07b63d6704473..d2e2a7ad865ae6238d9a6128da9e8557654a490d 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -681,7 +681,7 @@ class Uri {
while (index < length) {
- // Normalize percent encoding to uppercase and don't encode
+ // Normalize percent-encoding to uppercase and don't encode
// unreserved characters.
if (component.codeUnitAt(index) == _PERCENT) {
if (length < index + 2) {
@@ -1114,11 +1114,23 @@ class Uri {
* for encoding the posting of a HTML form as a query string
* component.
*
- * Spaces will be replaced with plus and all characters except for
- * uppercase and lowercase letters, decimal digits and the
- * characters `-._~`. Note that the set of characters encoded is a
- * superset of what HTML 4.01 says as it refers to RFC 1738 for
- * reserved characters.
+ * Encode the string [component] according to the HTML 4.01 rules
+ * for encoding the posting of a HTML form as a query string
+ * component.
+
+ * The component is first encoded to bytes using [encoding].
+ * The default is to use [UTF8] encoding, which preserves all
+ * the characters that don't need encoding.
+
+ * Then the resulting bytes are "percent-encoded". This transforms
+ * spaces (U+0020) to a plus sign ('+') and all bytes that are not
+ * the ASCII decimal digits, letters or one of '-._~' are written as
+ * a percent sign '%' followed by the two-digit hexadecimal
+ * representation of the byte.
+
+ * Note that the set of characters which are percent-encoded is a
+ * superset of what HTML 4.01 requires, since it refers to RFC 1738
+ * for reserved characters.
*
* When manually encoding query components remember to encode each
* part separately before building the query string.
@@ -1130,8 +1142,10 @@ class Uri {
* See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more
* details.
*/
- static String encodeQueryComponent(String component) {
- return _uriEncode(_unreservedTable, component, spaceToPlus: true);
+ static String encodeQueryComponent(String component,
+ {Encoding encoding: UTF8}) {
+ return _uriEncode(
+ _unreservedTable, component, encoding: encoding, spaceToPlus: true);
}
/**
@@ -1353,6 +1367,7 @@ class Uri {
}
// Frequently used character codes.
+ static const int _SPACE = 0x20;
static const int _DOUBLE_QUOTE = 0x22;
static const int _PERCENT = 0x25;
static const int _ASTERISK = 0x2A;
@@ -1382,36 +1397,29 @@ class Uri {
* that appear in [canonicalTable], and returns the escaped string.
*/
static String _uriEncode(List<int> canonicalTable,
- String text,
- {bool spaceToPlus: false}) {
- byteToHex(int v) {
- final String hex = '0123456789ABCDEF';
- return '%${hex[v >> 4]}${hex[v & 0x0f]}';
+ String text,
+ {Encoding encoding: UTF8,
+ bool spaceToPlus: false}) {
+ byteToHex(byte, buffer) {
+ const String hex = '0123456789ABCDEF';
+ buffer.writeCharCode(hex.codeUnitAt(byte >> 4));
+ buffer.writeCharCode(hex.codeUnitAt(byte & 0x0f));
}
+ // Encode the string into bytes then generate an ASCII only string
+ // by percent encoding selected bytes.
StringBuffer result = new StringBuffer();
- for (int i = 0; i < text.length; i++) {
- int ch = text.codeUnitAt(i);
- if (ch < 128 && ((canonicalTable[ch >> 4] & (1 << (ch & 0x0f))) != 0)) {
- result.write(text[i]);
- } else if (spaceToPlus && text[i] == " ") {
- result.write("+");
+ var bytes = encoding.encode(text);
+ for (int i = 0; i < bytes.length; i++) {
+ int byte = bytes[i];
+ if (byte < 128 &&
+ ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+ result.writeCharCode(byte);
+ } else if (spaceToPlus && byte == _SPACE) {
+ result.writeCharCode(_PLUS);
} else {
- if (ch >= 0xD800 && ch < 0xDC00) {
- // Low surrogate. We expect a next char high surrogate.
- ++i;
- int nextCh = text.length == i ? 0 : text.codeUnitAt(i);
- if (nextCh >= 0xDC00 && nextCh < 0xE000) {
- // convert the pair to a U+10000 codepoint
- ch = 0x10000 + ((ch - 0xD800) << 10) + (nextCh - 0xDC00);
- } else {
- throw new ArgumentError('Malformed URI');
- }
- }
- // TODO(floitsch): don't allocate a new string.
- for (int codepoint in UTF8.encode(new String.fromCharCode(ch))) {
- result.write(byteToHex(codepoint));
- }
+ result.writeCharCode(_PERCENT);
+ byteToHex(byte, result);
}
}
return result.toString();
@@ -1455,32 +1463,40 @@ class Uri {
static String _uriDecode(String text,
{bool plusToSpace: false,
Encoding encoding: UTF8}) {
- StringBuffer result = new StringBuffer();
- List<int> codepoints = new List<int>();
- for (int i = 0; i < text.length;) {
- int ch = text.codeUnitAt(i);
- if (ch != _PERCENT) {
- if (plusToSpace && ch == _PLUS) {
- result.write(" ");
- } else {
- result.writeCharCode(ch);
- }
- i++;
+ // First check whether there is any characters which need special handling.
+ bool simple = true;
+ for (int i = 0; i < text.length && simple; i++) {
+ var codeUnit = text.codeUnitAt(i);
+ simple = codeUnit != _PERCENT && codeUnit != _PLUS;
+ }
+ List<int> bytes;
+ if (simple) {
+ if (encoding == UTF8 || encoding == LATIN1) {
+ return text;
} else {
- codepoints.clear();
- while (ch == _PERCENT) {
- if (++i > text.length - 2) {
+ bytes = text.codeUnits;
+ }
+ } else {
+ bytes = new List();
+ for (int i = 0; i < text.length; i++) {
+ var codeUnit = text.codeUnitAt(i);
+ if (codeUnit > 127) {
+ throw new ArgumentError("Illegal percent encoding in URI");
+ }
+ if (codeUnit == _PERCENT) {
+ if (i + 3 > text.length) {
throw new ArgumentError('Truncated URI');
}
- codepoints.add(_hexCharPairToByte(text, i));
+ bytes.add(_hexCharPairToByte(text, i + 1));
i += 2;
- if (i == text.length) break;
- ch = text.codeUnitAt(i);
+ } else if (plusToSpace && codeUnit == _PLUS) {
+ bytes.add(_SPACE);
+ } else {
+ bytes.add(codeUnit);
}
- result.write(encoding.decode(codepoints));
}
}
- return result.toString();
+ return encoding.decode(bytes);
}
static bool _isAlphabeticCharacter(int codeUnit)
« no previous file with comments | « sdk/lib/core/core.dart ('k') | tests/corelib/uri_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698