|
157 | 157 | /* 7F DEL */ BIN_ERROR,
|
158 | 158 | };
|
159 | 159 |
|
| 160 | +/*********************************************************************** |
| 161 | +** |
| 162 | +*/ static const REBYTE Debase64URL[128] = |
| 163 | +/* |
| 164 | +** Base-64-URL binary decoder table. |
| 165 | +** See: https://tools.ietf.org/html/rfc4648#section-5 |
| 166 | +** |
| 167 | +***********************************************************************/ |
| 168 | +{ |
| 169 | + /* Control Chars */ |
| 170 | + BIN_ERROR,BIN_ERROR,BIN_ERROR,BIN_ERROR, /* 80 */ |
| 171 | + BIN_ERROR,BIN_ERROR,BIN_ERROR,BIN_ERROR, |
| 172 | + BIN_SPACE,BIN_SPACE,BIN_SPACE,BIN_ERROR, |
| 173 | + BIN_SPACE,BIN_SPACE,BIN_ERROR,BIN_ERROR, |
| 174 | + BIN_ERROR,BIN_ERROR,BIN_ERROR,BIN_ERROR, |
| 175 | + BIN_ERROR,BIN_ERROR,BIN_ERROR,BIN_ERROR, |
| 176 | + BIN_ERROR,BIN_ERROR,BIN_ERROR,BIN_ERROR, |
| 177 | + BIN_ERROR,BIN_ERROR,BIN_ERROR,BIN_ERROR, |
| 178 | + |
| 179 | + /* 20 */ BIN_SPACE, |
| 180 | + /* 21 ! */ BIN_ERROR, |
| 181 | + /* 22 " */ BIN_ERROR, |
| 182 | + /* 23 # */ BIN_ERROR, |
| 183 | + /* 24 $ */ BIN_ERROR, |
| 184 | + /* 25 % */ BIN_ERROR, |
| 185 | + /* 26 & */ BIN_ERROR, |
| 186 | + /* 27 ' */ BIN_SPACE, |
| 187 | + /* 28 ( */ BIN_ERROR, |
| 188 | + /* 29 ) */ BIN_ERROR, |
| 189 | + /* 2A * */ BIN_ERROR, |
| 190 | + /* 2B + */ BIN_ERROR, |
| 191 | + /* 2C , */ BIN_ERROR, |
| 192 | + /* 2D - */ 62, |
| 193 | + /* 2E . */ BIN_ERROR, |
| 194 | + /* 2F / */ BIN_ERROR, |
| 195 | + |
| 196 | + /* 30 0 */ 52, |
| 197 | + /* 31 1 */ 53, |
| 198 | + /* 32 2 */ 54, |
| 199 | + /* 33 3 */ 55, |
| 200 | + /* 34 4 */ 56, |
| 201 | + /* 35 5 */ 57, |
| 202 | + /* 36 6 */ 58, |
| 203 | + /* 37 7 */ 59, |
| 204 | + /* 38 8 */ 60, |
| 205 | + /* 39 9 */ 61, |
| 206 | + /* 3A : */ BIN_ERROR, |
| 207 | + /* 3B ; */ BIN_ERROR, |
| 208 | + /* 3C < */ BIN_ERROR, |
| 209 | + /* 3D = */ 0, // pad char |
| 210 | + /* 3E > */ BIN_ERROR, |
| 211 | + /* 3F ? */ BIN_ERROR, |
| 212 | + |
| 213 | + /* 40 @ */ BIN_ERROR, |
| 214 | + /* 41 A */ 0, |
| 215 | + /* 42 B */ 1, |
| 216 | + /* 43 C */ 2, |
| 217 | + /* 44 D */ 3, |
| 218 | + /* 45 E */ 4, |
| 219 | + /* 46 F */ 5, |
| 220 | + /* 47 G */ 6, |
| 221 | + /* 48 H */ 7, |
| 222 | + /* 49 I */ 8, |
| 223 | + /* 4A J */ 9, |
| 224 | + /* 4B K */ 10, |
| 225 | + /* 4C L */ 11, |
| 226 | + /* 4D M */ 12, |
| 227 | + /* 4E N */ 13, |
| 228 | + /* 4F O */ 14, |
| 229 | + |
| 230 | + /* 50 P */ 15, |
| 231 | + /* 51 Q */ 16, |
| 232 | + /* 52 R */ 17, |
| 233 | + /* 53 S */ 18, |
| 234 | + /* 54 T */ 19, |
| 235 | + /* 55 U */ 20, |
| 236 | + /* 56 V */ 21, |
| 237 | + /* 57 W */ 22, |
| 238 | + /* 58 X */ 23, |
| 239 | + /* 59 Y */ 24, |
| 240 | + /* 5A Z */ 25, |
| 241 | + /* 5B [ */ BIN_ERROR, |
| 242 | + /* 5C \ */ BIN_ERROR, |
| 243 | + /* 5D ] */ BIN_ERROR, |
| 244 | + /* 5E ^ */ BIN_ERROR, |
| 245 | + /* 5F _ */ 63, |
| 246 | + |
| 247 | + /* 60 ` */ BIN_ERROR, |
| 248 | + /* 61 a */ 26, |
| 249 | + /* 62 b */ 27, |
| 250 | + /* 63 c */ 28, |
| 251 | + /* 64 d */ 29, |
| 252 | + /* 65 e */ 30, |
| 253 | + /* 66 f */ 31, |
| 254 | + /* 67 g */ 32, |
| 255 | + /* 68 h */ 33, |
| 256 | + /* 69 i */ 34, |
| 257 | + /* 6A j */ 35, |
| 258 | + /* 6B k */ 36, |
| 259 | + /* 6C l */ 37, |
| 260 | + /* 6D m */ 38, |
| 261 | + /* 6E n */ 39, |
| 262 | + /* 6F o */ 40, |
| 263 | + |
| 264 | + /* 70 p */ 41, |
| 265 | + /* 71 q */ 42, |
| 266 | + /* 72 r */ 43, |
| 267 | + /* 73 s */ 44, |
| 268 | + /* 74 t */ 45, |
| 269 | + /* 75 u */ 46, |
| 270 | + /* 76 v */ 47, |
| 271 | + /* 77 w */ 48, |
| 272 | + /* 78 x */ 49, |
| 273 | + /* 79 y */ 50, |
| 274 | + /* 7A z */ 51, |
| 275 | + /* 7B { */ BIN_ERROR, |
| 276 | + /* 7C | */ BIN_ERROR, |
| 277 | + /* 7D } */ BIN_ERROR, |
| 278 | + /* 7E ~ */ BIN_ERROR, |
| 279 | + /* 7F DEL */ BIN_ERROR, |
| 280 | +}; |
| 281 | + |
160 | 282 |
|
161 | 283 | /***********************************************************************
|
162 | 284 | **
|
|
171 | 293 | "0123456789+/"
|
172 | 294 | };
|
173 | 295 |
|
| 296 | +/*********************************************************************** |
| 297 | +** |
| 298 | +*/ static const REBYTE Enbase64URL[64] = |
| 299 | +/* |
| 300 | +** Base-64-URL binary encoder table. |
| 301 | +** |
| 302 | +***********************************************************************/ |
| 303 | +{ |
| 304 | + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 305 | + "abcdefghijklmnopqrstuvwxyz" |
| 306 | + "0123456789-_" |
| 307 | +}; |
| 308 | + |
174 | 309 |
|
175 | 310 | /***********************************************************************
|
176 | 311 | **
|
|
269 | 404 |
|
270 | 405 | /***********************************************************************
|
271 | 406 | **
|
272 |
| -*/ static REBSER *Decode_Base64(REBYTE **src, REBCNT len, REBYTE delim) |
| 407 | +*/ static REBSER *Decode_Base64(REBYTE **src, REBCNT len, REBYTE delim, REBOOL urlSafe) |
273 | 408 | /*
|
274 | 409 | ***********************************************************************/
|
275 | 410 | {
|
|
286 | 421 | bp = STR_HEAD(ser);
|
287 | 422 | cp = *src;
|
288 | 423 |
|
| 424 | + const REBYTE *table; |
| 425 | + if (urlSafe) { |
| 426 | + table = Debase64URL; |
| 427 | + } else { |
| 428 | + table = Debase64; |
| 429 | + } |
| 430 | + |
289 | 431 | for (; len > 0; cp++, len--) {
|
290 | 432 |
|
291 | 433 | // Check for terminating delimiter (optional):
|
|
297 | 439 | goto err;
|
298 | 440 | }
|
299 | 441 |
|
300 |
| - lex = Debase64[*cp]; |
| 442 | + lex = table[*cp]; |
301 | 443 |
|
302 | 444 | if (lex < BIN_SPACE) {
|
303 | 445 |
|
|
350 | 492 |
|
351 | 493 | /***********************************************************************
|
352 | 494 | **
|
353 |
| -*/ REBYTE *Decode_Binary(REBVAL *value, REBYTE *src, REBCNT len, REBINT base, REBYTE delim) |
| 495 | +*/ REBYTE *Decode_Binary(REBVAL *value, REBYTE *src, REBCNT len, REBINT base, REBYTE delim, REBOOL urlSafe) |
354 | 496 | /*
|
355 | 497 | ** Scan and convert a binary string.
|
356 | 498 | **
|
|
360 | 502 |
|
361 | 503 | switch (base) {
|
362 | 504 | case 64:
|
363 |
| - ser = Decode_Base64(&src, len, delim); |
| 505 | + ser = Decode_Base64(&src, len, delim, urlSafe); |
364 | 506 | break;
|
365 | 507 | case 16:
|
366 | 508 | ser = Decode_Base16(&src, len, delim);
|
|
457 | 599 |
|
458 | 600 | /***********************************************************************
|
459 | 601 | **
|
460 |
| -*/ REBSER *Encode_Base64(REBVAL *value, REBSER *series, REBFLG brk) |
| 602 | +*/ REBSER *Encode_Base64(REBVAL *value, REBSER *series, REBFLG brk, REBOOL urlSafe) |
461 | 603 | /*
|
462 | 604 | ** Base64 encode a given series. Must be BYTES, not UNICODE.
|
463 | 605 | **
|
|
470 | 612 |
|
471 | 613 | len = VAL_LEN(value);
|
472 | 614 | src = VAL_BIN(value);
|
473 |
| - |
| 615 | + |
| 616 | + const REBYTE *table; |
| 617 | + if(urlSafe) { |
| 618 | + table = Enbase64URL; |
| 619 | + } else { |
| 620 | + table = Enbase64; |
| 621 | + } |
| 622 | + |
474 | 623 | // slop-factor
|
475 | 624 | series = Prep_String (series, &p, 4 * len / 3 + 2 * (len / 32) + 5);
|
476 | 625 | loop = (int) (len / 3) - 1;
|
477 | 626 | if (4 * loop > 64 && brk) *p++ = LF;
|
478 | 627 |
|
479 | 628 | for (x = 0; x <= 3 * loop; x += 3) {
|
480 |
| - *p++ = Enbase64[src[x] >> 2]; |
481 |
| - *p++ = Enbase64[((src[x] & 0x3) << 4) + (src[x + 1] >> 4)]; |
482 |
| - *p++ = Enbase64[((src[x + 1] & 0xF) << 2) + (src[x + 2] >> 6)]; |
483 |
| - *p++ = Enbase64[(src[x + 2] % 0x40)]; |
| 629 | + *p++ = table[src[x] >> 2]; |
| 630 | + *p++ = table[((src[x] & 0x3) << 4) + (src[x + 1] >> 4)]; |
| 631 | + *p++ = table[((src[x + 1] & 0xF) << 2) + (src[x + 2] >> 6)]; |
| 632 | + *p++ = table[(src[x + 2] % 0x40)]; |
484 | 633 | if ((x+3) % 48 == 0 && brk)
|
485 | 634 | *p++ = LF;
|
486 | 635 | }
|
487 | 636 |
|
488 | 637 | if ((len % 3) != 0) {
|
489 | 638 | p[2] = p[3] = '=';
|
490 |
| - *p++ = Enbase64[src[x] >> 2]; |
| 639 | + *p++ = table[src[x] >> 2]; |
491 | 640 | if ((len - x) >= 1)
|
492 |
| - *p++ = Enbase64[((src[x] & 0x3) << 4) + ((len - x) == 1 ? 0 : src[x + 1] >> 4)]; |
| 641 | + *p++ = table[((src[x] & 0x3) << 4) + ((len - x) == 1 ? 0 : src[x + 1] >> 4)]; |
493 | 642 | else p++;
|
494 | 643 | if ((len - x) == 2)
|
495 |
| - *p++ = Enbase64[(src[x + 1] & 0xF) << 2]; |
| 644 | + *p++ = table[(src[x + 1] & 0xF) << 2]; |
496 | 645 | else p++;
|
497 | 646 | p++;
|
498 | 647 | }
|
|
0 commit comments