Skip to content

Commit 64f296e

Browse files
committed
[fix] decode base64
1 parent edace6b commit 64f296e

File tree

5 files changed

+41
-34
lines changed

5 files changed

+41
-34
lines changed

assembly/buffer/index.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,12 @@ export namespace Buffer {
378378
}
379379

380380
export namespace BASE64 {
381-
381+
// @ts-ignore: Decorators!
382+
@inline
382383
function charCodeFromByte(value: i32): u64 {
383384
if (i32(value >= 0) & i32(value < 26)) return value + 0x41;
384-
else if (i32(value >= 26) & i32(value < 51)) return value + 0x61;
385+
else if (i32(value >= 26) & i32(value < 52)) return value + 0x47;
386+
else if (i32(value >= 52) & i32(value < 62)) return value - 0x4;
385387
else return select(0x2B, 0x2F, value == 62);
386388
}
387389

@@ -401,20 +403,20 @@ export namespace Buffer {
401403
return decodeUnsafe(changetype<usize>(buffer), buffer.byteLength);
402404
}
403405

404-
export function decodeUnsafe(pointer: usize, length: i32): string {
406+
export function decodeUnsafe(sourcePointer: usize, length: i32): string {
405407
if (length == 0) return "";
406408
let iterations = <i32>Math.floor(length / 3);
407409
let leftoverBytes = length % 3;
408-
let stringLength = (iterations << 2) + select(4, 0, leftoverBytes);
410+
let stringLength = (iterations << 2) + select(4, 0, leftoverBytes != 0);
409411
let output = __alloc(stringLength << 1, idof<String>());
410412

411413
for (let i = 0; i < iterations; i++) {
412-
let bytes = bswap<u32>(load<u32>(pointer + <usize>i * 3)) >>> 8;
414+
let bytes = bswap<u32>(load<u32>(sourcePointer + <usize>i * 3)) >>> 8;
415+
413416
let value1 = (bytes & 0b111111000000000000000000) >> 18; // first 6 bits
414417
let value2 = (bytes & 0b111111000000000000) >> 12; // second 6 bits
415418
let value3 = (bytes & 0b111111000000) >> 6 ; // third 6 bits
416419
let value4 = (bytes & 0b111111) ; // fourth 6 bits
417-
418420
let chars: u64 = charCodeFromByte(value1)
419421
| (charCodeFromByte(value2) << 16)
420422
| (charCodeFromByte(value3) << 32)
@@ -425,7 +427,7 @@ export namespace Buffer {
425427
// A is 0x61
426428
// = is 0x3D
427429
if (leftoverBytes == 2) {
428-
let bytes = <u32>bswap<u16>(load<u16>(pointer + <usize>(iterations * 3))) << 2;
430+
let bytes = <u32>bswap<u16>(load<u16>(sourcePointer + <usize>(iterations * 3))) << 2;
429431
let value1 = (bytes & 0b111111000000000000) >> 12; // first 6 bits
430432
let value2 = (bytes & 0b111111000000) >> 6 ; // second 6 bits
431433
let value3 = (bytes & 0b111111) >> 0 ; // third 6 bits
@@ -435,9 +437,14 @@ export namespace Buffer {
435437
| <u64>0x3D000000000000;
436438
store<u64>(output + (<usize>iterations << alignof<u64>()), chars);
437439
} else if (leftoverBytes == 1) {
438-
let bytes = <i32>load<u8>(pointer + <usize>(iterations * 3)) >> 2;
439-
let chars: u64 = charCodeFromByte(bytes & 0b111111)
440-
| <u64>0x3D003D00410000;
440+
let bytes = <i32>load<u8>(sourcePointer + <usize>(iterations * 3));
441+
trace("bytes", 1, bytes);
442+
let value1 = (bytes & 0b11111100) >> 2;
443+
let value2 = (bytes & 0b11) << 4;
444+
let chars: u64 = charCodeFromByte(value1)
445+
| <u64>(charCodeFromByte(value2) << 16)
446+
| <u64>0x3D003D00000000;
447+
441448
store<u64>(output + (<usize>iterations << alignof<u64>()), chars);
442449
}
443450

assembly/node.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,9 @@ declare namespace Buffer {
9494
/** Decodes a chunk of memory to a utf16le encoded string in hex format. */
9595
export function decodeUnsafe(ptr: usize, byteLength: i32): string;
9696
}
97+
98+
export namespace BASE64 {
99+
/** Creates a string from a given ArrayBuffer that is decoded into base64 format. */
100+
export function decode(buffer: ArrayBuffer): string;
101+
}
97102
}

package-lock.json

Lines changed: 12 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"url": "https://github.com/AssemblyScript/node/issues"
1313
},
1414
"devDependencies": {
15-
"@as-pect/core": "^2.3.1",
15+
"@as-pect/core": "^2.4.0",
1616
"assemblyscript": "github:assemblyscript/assemblyscript",
1717
"glob": "^7.1.4",
1818
"wasi": "github:devsnek/node-wasi"

tests/buffer.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,6 @@ describe("buffer", () => {
592592
expect<string>(decoded).toStrictEqual("AQIDBA==");
593593
decoded = Buffer.BASE64.decode(create<Buffer>([1, 2, 3, 4, 5]).buffer);
594594
expect<string>(decoded).toBe("AQIDBAU=", "target");
595-
596595
decoded = Buffer.BASE64.decode(create<Buffer>([
597596
150, 144, 40, 36, 82, 6, 240, 81, 182, 94, 22,
598597
137, 32, 212, 14, 6, 176, 169, 104, 91, 243, 241,
@@ -615,5 +614,11 @@ describe("buffer", () => {
615614
106
616615
]).buffer);
617616
expect<string>(decoded).toBe("vSQJHj1Wusb3lhfgbLIj35vyjKujgq1+PEZT03EGiYymYl5eBG6SAuIze+LrBCwfcUWpZGGq77l3anBroizTpljhjSZ6UuWZcxdsdyYR5Mw0DhtoO0DFbevO88SrswY+ag==");
617+
618+
decoded = Buffer.BASE64.decode(create<Buffer>([
619+
141, 192, 94, 172,
620+
180, 140, 2, 59
621+
]).buffer);
622+
expect<string>(decoded).toBe("jcBerLSMAjs=");
618623
});
619624
});

0 commit comments

Comments
 (0)