OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import "package:expect/expect.dart"; |
| 6 import "dart:convert"; |
| 7 import "dart:typed_data"; |
| 8 |
| 9 main() { |
| 10 testMediaType(); |
| 11 |
| 12 testRoundTrip(""); |
| 13 testRoundTrip("a"); |
| 14 testRoundTrip("ab"); |
| 15 testRoundTrip("abc"); |
| 16 testRoundTrip("abcd"); |
| 17 testRoundTrip("Content with special%25 characters: # ? = % # ? = %"); |
| 18 testRoundTrip("blåbærgrød", UTF8); |
| 19 testRoundTrip("blåbærgrød", LATIN1); |
| 20 |
| 21 testUtf8Encoding("\u1000\uffff"); |
| 22 testBytes(); |
| 23 testInvalidCharacters(); |
| 24 testErrors(); |
| 25 } |
| 26 |
| 27 void testMediaType() { |
| 28 for (var mimeType in ["", "text/plain", "text/javascript"]) { |
| 29 for (var charset in ["", ";charset=US-ASCII", ";charset=UTF-8"]) { |
| 30 for (var base64 in ["", ";base64"]) { |
| 31 bool isBase64 = base64.isNotEmpty; |
| 32 var text = "data:$mimeType$charset$base64,"; |
| 33 var uri = UriData.parse(text); |
| 34 |
| 35 String expectedCharset = |
| 36 charset.isEmpty ? "US-ASCII" : charset.substring(9); |
| 37 String expectedMimeType = |
| 38 mimeType.isEmpty ? "text/plain" : mimeType; |
| 39 |
| 40 Expect.equals(text, "$uri"); |
| 41 Expect.equals(expectedMimeType, uri.mimeType); |
| 42 Expect.equals(expectedCharset, uri.charset); |
| 43 Expect.equals(isBase64, uri.isBase64); |
| 44 } |
| 45 } |
| 46 } |
| 47 } |
| 48 |
| 49 void testRoundTrip(String content, [Encoding encoding]) { |
| 50 UriData dataUri = |
| 51 new UriData.fromString(content, encoding: encoding); |
| 52 Expect.isFalse(dataUri.isBase64); |
| 53 Uri uri = dataUri.uri; |
| 54 expectUriEquals(new Uri.dataFromString(content, encoding: encoding), uri); |
| 55 |
| 56 if (encoding != null) { |
| 57 UriData dataUriParams = new UriData.fromString( |
| 58 content, parameters: {"charset" : encoding.name}); |
| 59 Expect.equals("$dataUri", "$dataUriParams"); |
| 60 } |
| 61 |
| 62 Expect.equals(encoding ?? ASCII, Encoding.getByName(dataUri.charset)); |
| 63 Expect.equals(content, dataUri.contentAsString(encoding: encoding)); |
| 64 Expect.equals(content, dataUri.contentAsString()); |
| 65 Expect.equals(content, (encoding ?? ASCII).decode(dataUri.contentAsBytes())); |
| 66 |
| 67 uri = dataUri.uri; |
| 68 Expect.equals(uri.toString(), dataUri.toString()); |
| 69 Expect.equals(dataUri.toString(), new UriData.fromUri(uri).toString()); |
| 70 |
| 71 dataUri = new UriData.fromBytes(content.codeUnits); |
| 72 Expect.listEquals(content.codeUnits, dataUri.contentAsBytes()); |
| 73 Expect.equals(content, dataUri.contentAsString(encoding: LATIN1)); |
| 74 |
| 75 uri = dataUri.uri; |
| 76 Expect.equals(uri.toString(), dataUri.toString()); |
| 77 Expect.equals(dataUri.toString(), new UriData.fromUri(uri).toString()); |
| 78 // Check that the URI is properly normalized. |
| 79 expectUriEquals(uri, Uri.parse("$uri")); |
| 80 } |
| 81 |
| 82 void testUtf8Encoding(String content) { |
| 83 UriData uri = new UriData.fromString(content, encoding: UTF8); |
| 84 Expect.equals(content, uri.contentAsString(encoding: UTF8)); |
| 85 Expect.listEquals(UTF8.encode(content), uri.contentAsBytes()); |
| 86 } |
| 87 |
| 88 void testInvalidCharacters() { |
| 89 // SPACE, CTL and tspecial, plus '%' and '#' (URI gen-delim) |
| 90 // This contains all ASCII character that are not valid in attribute/value |
| 91 // parts. |
| 92 var invalid = |
| 93 '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x7f' |
| 94 ' ()<>@,;:"/[]?=%#\x80\u{1000}\u{10000}'; |
| 95 var invalidNoSlash = invalid.replaceAll('/', ''); |
| 96 var dataUri = new UriData.fromString( |
| 97 invalid, |
| 98 encoding: UTF8, |
| 99 mimeType: "$invalidNoSlash/$invalidNoSlash", |
| 100 parameters: {invalid: invalid}); |
| 101 |
| 102 Expect.equals(invalid, dataUri.contentAsString()); |
| 103 Expect.equals("$invalidNoSlash/$invalidNoSlash", dataUri.mimeType); |
| 104 Expect.equals(invalid, dataUri.parameters[invalid]); |
| 105 |
| 106 var uri = dataUri.uri; |
| 107 Expect.equals("$uri", "$dataUri"); |
| 108 expectUriEquals(uri, Uri.parse("$uri")); // Check that it's canonicalized. |
| 109 Expect.equals("$dataUri", new UriData.fromUri(uri).toString()); |
| 110 } |
| 111 |
| 112 void testBytes() { |
| 113 void testList(List<int> list) { |
| 114 var dataUri = new UriData.fromBytes(list); |
| 115 Expect.equals("application/octet-stream", dataUri.mimeType); |
| 116 Expect.isTrue(dataUri.isBase64); |
| 117 Expect.listEquals(list, dataUri.contentAsBytes()); |
| 118 |
| 119 dataUri = new UriData.fromBytes(list, percentEncoded: true); |
| 120 Expect.equals("application/octet-stream", dataUri.mimeType); |
| 121 Expect.isFalse(dataUri.isBase64); |
| 122 Expect.listEquals(list, dataUri.contentAsBytes()); |
| 123 |
| 124 var string = new String.fromCharCodes(list); |
| 125 |
| 126 dataUri = new UriData.fromString(string, encoding: LATIN1); |
| 127 Expect.equals("text/plain", dataUri.mimeType); |
| 128 Expect.isFalse(dataUri.isBase64); |
| 129 Expect.listEquals(list, dataUri.contentAsBytes()); |
| 130 |
| 131 dataUri = |
| 132 new UriData.fromString(string, encoding: LATIN1, base64: true); |
| 133 Expect.equals("text/plain", dataUri.mimeType); |
| 134 Expect.isTrue(dataUri.isBase64); |
| 135 Expect.listEquals(list, dataUri.contentAsBytes()); |
| 136 } |
| 137 |
| 138 void testLists(List<int> list) { |
| 139 testList(list); |
| 140 for (int i = 0; i < 27; i++) { |
| 141 testList(list.sublist(i, i + i)); // All lengths from 0 to 27. |
| 142 } |
| 143 } |
| 144 |
| 145 var bytes = new Uint8List(512); |
| 146 for (int i = 0; i < bytes.length; i++) { |
| 147 bytes[i] = i; |
| 148 } |
| 149 testLists(bytes); |
| 150 testLists(new List.from(bytes)); |
| 151 testLists(new List.unmodifiable(bytes)); |
| 152 } |
| 153 |
| 154 bool badArgument(e) => e is ArgumentError; |
| 155 bool badFormat(e) => e is FormatException; |
| 156 |
| 157 void testErrors() { |
| 158 // Invalid constructor parameters. |
| 159 Expect.throws(() { new UriData.fromBytes([], mimeType: "noslash"); }, |
| 160 badArgument); |
| 161 Expect.throws(() { new UriData.fromBytes([257]); }, |
| 162 badArgument); |
| 163 Expect.throws(() { new UriData.fromBytes([-1]); }, |
| 164 badArgument); |
| 165 Expect.throws(() { new UriData.fromBytes([0x10000000]); }, |
| 166 badArgument); |
| 167 Expect.throws(() { new UriData.fromString("", mimeType: "noslash"); }, |
| 168 badArgument); |
| 169 |
| 170 Expect.throws(() { new Uri.dataFromBytes([], mimeType: "noslash"); }, |
| 171 badArgument); |
| 172 Expect.throws(() { new Uri.dataFromBytes([257]); }, |
| 173 badArgument); |
| 174 Expect.throws(() { new Uri.dataFromBytes([-1]); }, |
| 175 badArgument); |
| 176 Expect.throws(() { new Uri.dataFromBytes([0x10000000]); }, |
| 177 badArgument); |
| 178 Expect.throws(() { new Uri.dataFromString("", mimeType: "noslash"); }, |
| 179 badArgument); |
| 180 |
| 181 // Empty parameters allowed, not an error. |
| 182 var uri = new UriData.fromString("", mimeType: "", parameters: {}); |
| 183 Expect.equals("data:,", "$uri"); |
| 184 // Empty parameter key or value is an error. |
| 185 Expect.throws(() => new UriData.fromString("", parameters: {"": "X"}), |
| 186 badArgument); |
| 187 Expect.throws(() => new UriData.fromString("", parameters: {"X": ""}), |
| 188 badArgument); |
| 189 |
| 190 // Not recognizing charset is an error. |
| 191 uri = UriData.parse("data:;charset=arglebargle,X"); |
| 192 Expect.throws(() { |
| 193 uri.contentAsString(); |
| 194 }); |
| 195 // Doesn't throw if we specify the encoding. |
| 196 Expect.equals("X", uri.contentAsString(encoding: ASCII)); |
| 197 |
| 198 // Parse format. |
| 199 Expect.throws(() { UriData.parse("notdata:,");}, badFormat); |
| 200 Expect.throws(() { UriData.parse("text/plain,noscheme");}, badFormat); |
| 201 Expect.throws(() { UriData.parse("data:noseparator");}, badFormat); |
| 202 Expect.throws(() { UriData.parse("data:noslash,text");}, badFormat); |
| 203 Expect.throws(() { UriData.parse("data:type/sub;noequals,text");}, |
| 204 badFormat); |
| 205 Expect.throws(() { UriData.parse("data:type/sub;knocomma=");}, |
| 206 badFormat); |
| 207 Expect.throws(() { UriData.parse("data:type/sub;k=v;nocomma");}, |
| 208 badFormat); |
| 209 Expect.throws(() { UriData.parse("data:type/sub;k=nocomma");}, |
| 210 badFormat); |
| 211 Expect.throws(() { UriData.parse("data:type/sub;k=v;base64");}, |
| 212 badFormat); |
| 213 |
| 214 // Invalid base64 format (only detected when decodeing). |
| 215 for (var a = 0; a <= 4; a++) { |
| 216 for (var p = 0; p <= 4; p++) { |
| 217 // Base-64 encoding must have length divisible by four and no more |
| 218 // than two padding characters at the end. |
| 219 if (p < 3 && (a + p) % 4 == 0) continue; |
| 220 uri = UriData.parse("data:;base64," + "A" * a + "=" * p); |
| 221 Expect.throws(uri.contentAsBytes, badFormat); |
| 222 } |
| 223 } |
| 224 // Invalid base64 encoding: padding not at end. |
| 225 uri = UriData.parse("data:;base64,AA=A"); |
| 226 Expect.throws(uri.contentAsBytes, badFormat); |
| 227 uri = UriData.parse("data:;base64,A=AA"); |
| 228 Expect.throws(uri.contentAsBytes, badFormat); |
| 229 uri = UriData.parse("data:;base64,=AAA"); |
| 230 Expect.throws(uri.contentAsBytes, badFormat); |
| 231 uri = UriData.parse("data:;base64,A==A"); |
| 232 Expect.throws(uri.contentAsBytes, badFormat); |
| 233 uri = UriData.parse("data:;base64,==AA"); |
| 234 Expect.throws(uri.contentAsBytes, badFormat); |
| 235 uri = UriData.parse("data:;base64,===A"); |
| 236 Expect.throws(uri.contentAsBytes, badFormat); |
| 237 } |
| 238 |
| 239 /// Checks that two [Uri]s are exactly the same. |
| 240 expectUriEquals(Uri expect, Uri actual) { |
| 241 Expect.equals(expect.scheme, actual.scheme, "scheme"); |
| 242 Expect.equals(expect.hasAuthority, actual.hasAuthority, "hasAuthority"); |
| 243 Expect.equals(expect.userInfo, actual.userInfo, "userInfo"); |
| 244 Expect.equals(expect.host, actual.host, "host"); |
| 245 Expect.equals(expect.hasPort, actual.hasPort, "hasPort"); |
| 246 Expect.equals(expect.port, actual.port, "port"); |
| 247 Expect.equals(expect.port, actual.port, "port"); |
| 248 Expect.equals(expect.hasQuery, actual.hasQuery, "hasQuery"); |
| 249 Expect.equals(expect.query, actual.query, "query"); |
| 250 Expect.equals(expect.hasFragment, actual.hasFragment, "hasFragment"); |
| 251 Expect.equals(expect.fragment, actual.fragment, "fragment"); |
| 252 } |
OLD | NEW |