You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

217 lines
5.8 KiB

// XXX: util
/* Trivial string checksum used to summarize brute force output lines
* (minimizes test case size).
*/
function checkSumString(x) {
var i, n;
var res = 0;
var mult = [ 1, 3, 5, 7, 11, 13, 17, 19, 23 ];
n = x.length;
for (i = 0; i < n; i++) {
res += x.charCodeAt(i) * mult[i % mult.length];
res = res >>> 0; // coerce to 32 bits
}
return res;
}
// XXX: util
function getCodePoints(x) {
var res = [];
var i, n;
n = x.length;
for (i = 0; i < n; i++) {
res.push(x.charCodeAt(i));
}
return res.join(' ');
}
// indirect eval -> this is bound to the global object, E5 Section 10.4.2, step 1.a.
var g = (function () { var e = eval; return e('this'); } )();
var ucnybbles = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ];
var lcnybbles = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ];
/*===
basic
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
37 117 49 50 51
37 117 49 50 51 103
37 117 49 50 51 71
37 85 49 50 51 52
4671
4671
37 49
37 49 103
37 49 71
31
31
%x escapes
%u escapes
===*/
print('basic');
function basicTest() {
var i;
var tmp;
// simple test of the 8-bit range
tmp = [];
for (i = 0; i < 256; i++) {
tmp.push(String.fromCharCode(i));
}
tmp = tmp.join('');
print(getCodePoints(g.unescape(tmp)));
// % must be followed by 'u' and 4 hex digits to make a unicode escape
print(getCodePoints(g.unescape('%u123')));
print(getCodePoints(g.unescape('%u123g')));
print(getCodePoints(g.unescape('%u123G')));
print(getCodePoints(g.unescape('%U1234'))); // uppercase 'u' not accepted
print(getCodePoints(g.unescape('%u123f'))); // valid
print(getCodePoints(g.unescape('%u123F'))); // valid
// % must be followed by 'x' and 2 hex digits to make a short escape
print(getCodePoints(g.unescape('%1')));
print(getCodePoints(g.unescape('%1g')));
print(getCodePoints(g.unescape('%1G')));
print(getCodePoints(g.unescape('%1f'))); // valid
print(getCodePoints(g.unescape('%1F'))); // valid
// check that all 2-byte escapes work
print('%x escapes');
for (i = 0; i < 256; i++) {
tmp = '%' + ucnybbles[i >> 4] + ucnybbles[i & 0x0f];
res = g.unescape(tmp);
if (res.length !== 1 || res.charCodeAt(0) !== i) {
print('unescape error for %xx at index i:', i);
}
tmp = '%' + lcnybbles[i >> 4] + lcnybbles[i & 0x0f];
res = g.unescape(tmp);
if (res.length !== 1 || res.charCodeAt(0) !== i) {
print('unescape error for %xx at index i:', i);
}
}
// check that all 4-byte escapes work
print('%u escapes');
for (i = 0; i < 65536; i++) {
tmp = '%u' + ucnybbles[(i >> 12) & 0x0f] + ucnybbles[(i >> 8) & 0x0f] +
ucnybbles[(i >> 4) & 0x0f] + ucnybbles[i & 0x0f];
res = g.unescape(tmp);
if (res.length !== 1 || res.charCodeAt(0) !== i) {
print('unescape error for %uxxxx at index i:', i);
}
tmp = '%u' + lcnybbles[(i >> 12) & 0x0f] + lcnybbles[(i >> 8) & 0x0f] +
lcnybbles[(i >> 4) & 0x0f] + lcnybbles[i & 0x0f];
res = g.unescape(tmp);
if (res.length !== 1 || res.charCodeAt(0) !== i) {
print('unescape error for %uxxxx at index i:', i);
}
}
}
try {
basicTest();
} catch (e) {
print(e);
}
/*===
bruteforce
0 5759968
1024 17273824
2048 28787680
3072 40301536
4096 51815392
5120 63329248
6144 74843104
7168 86356960
8192 97870816
9216 109384672
10240 120898528
11264 132412384
12288 143926240
13312 155440096
14336 166953952
15360 178467808
16384 189981664
17408 201495520
18432 213009376
19456 224523232
20480 236037088
21504 247550944
22528 259064800
23552 270578656
24576 282092512
25600 293606368
26624 305120224
27648 316634080
28672 328147936
29696 339661792
30720 351175648
31744 362689504
32768 374203360
33792 385717216
34816 397231072
35840 408744928
36864 420258784
37888 431772640
38912 443286496
39936 454800352
40960 466314208
41984 477828064
43008 489341920
44032 500855776
45056 512369632
46080 523883488
47104 535397344
48128 546911200
49152 558425056
50176 569938912
51200 581452768
52224 592966624
53248 604480480
54272 615994336
55296 627508192
56320 639022048
57344 650535904
58368 662049760
59392 673563616
60416 685077472
61440 696591328
62464 708105184
63488 719619040
64512 731132896
===*/
print('bruteforce');
function bruteForceTest() {
var i;
var tmp;
// decode every character (including '%', because the characters
// following it won't make a valid escape, it will decode as itself)
for (i = 0; i < 65536; i += 1024) {
tmp = [];
for (j = 0; j < 1024; j++) {
tmp.push(String.fromCharCode(i + j));
}
tmp = tmp.join('');
print(i, checkSumString(g.unescape(tmp)));
}
}
try {
bruteForceTest();
} catch (e) {
print(e.name);
}