Skip to content

Commit b54e1b8

Browse files
committed
FEAT: improving DEBASE so it can decode URL safe Base64 variant input even without using a /url refinement
relates to: metaeducation/rebol-issues#2318 Previously this would throw an error: ``` >> debase "qL8R4QIcQ_ZsRqOAbeRfcZhilN_MksRtDaErMA==" ** Script error: data not in correct format: "qL8R4QIcQ_ZsRqOAbeRfcZhilN_MksRtDaErMA==" ``` The reason is that the input is using URL safe alphabet. With this commit when such a situation is detected, the decoder restarts itself automatically as if it would be used with /url refinement. NOTE: if you are sure that input should be in URL safe format, use the refinement to avoid unnecessary computations. Possible test: ``` key: "qL8R4QIcQ_ZsRqOAbeRfcZhilN_MksRtDaErMA==" equal? (debase key) (debase/url key) ;== should be TRUE ```
1 parent a01c683 commit b54e1b8

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

src/core/f-enbase.c

+18-6
Original file line numberDiff line numberDiff line change
@@ -410,16 +410,20 @@
410410
{
411411
REBYTE *bp;
412412
REBYTE *cp;
413-
REBCNT flip = 0;
414-
REBINT accum = 0;
413+
REBCNT flip, pos;
414+
REBINT accum;
415415
REBYTE lex;
416416
REBSER *ser;
417417

418418
// Allocate buffer large enough to hold result:
419419
// Accounts for e bytes decoding into 3 bytes.
420420
ser = Make_Binary(((len + 3) * 3) / 4);
421+
422+
start:
421423
bp = STR_HEAD(ser);
422424
cp = *src;
425+
accum = 0;
426+
flip = 0;
423427

424428
const REBYTE *table;
425429
if (urlSafe) {
@@ -428,7 +432,7 @@
428432
table = Debase64;
429433
}
430434

431-
for (; len > 0; cp++, len--) {
435+
for (pos = len; pos > 0; cp++, pos--) {
432436

433437
// Check for terminating delimiter (optional):
434438
if (delim && *cp == delim) break;
@@ -455,14 +459,14 @@
455459
} else {
456460
// Special padding: "="
457461
cp++;
458-
len--;
462+
pos--;
459463
if (flip == 3) {
460464
*bp++ = (REBYTE)(accum >> 10);
461465
*bp++ = (REBYTE)(accum >> 2);
462466
flip = 0;
463467
}
464468
else if (flip == 2) {
465-
if (!Skip_To_Char(cp, cp + len, '=')) goto err;
469+
if (!Skip_To_Char(cp, cp + pos, '=')) goto err;
466470
cp++;
467471
*bp++ = (REBYTE)(accum >> 4);
468472
flip = 0;
@@ -471,7 +475,15 @@
471475
break;
472476
}
473477
}
474-
else if (lex == BIN_ERROR) goto err;
478+
else if (lex == BIN_ERROR) {
479+
if(!urlSafe && (*cp == '-' || *cp == '_')) {
480+
// there was found char, which is used in URL safe encoding, but we are in simple Base64 mode,
481+
// so try to decode it using safe table, instead of throwing an error immediately.
482+
urlSafe = TRUE;
483+
goto start;
484+
}
485+
goto err;
486+
}
475487
}
476488

477489
if(flip==2) {

0 commit comments

Comments
 (0)