refactor(encoding): prepare for noUncheckedIndexedAccess (#4275)

This commit is contained in:
cinchen 2024-02-25 04:24:08 +08:00 committed by GitHub
parent 271a100e8f
commit 8693c81d58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 87 additions and 79 deletions

View File

@ -44,9 +44,9 @@ export interface Ascii85Options {
delimiter?: boolean;
}
const rfc1924 =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~" as const;
const Z85 =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#";
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#" as const;
/**
* Converts data into an ascii58-encoded string.
@ -114,10 +114,10 @@ export function encodeAscii85(
}
break;
case "RFC 1924":
output = output.map((val) => rfc1924[val.charCodeAt(0) - 33]);
output = output.map((val) => rfc1924[val.charCodeAt(0) - 33]!);
break;
case "Z85":
output = output.map((val) => Z85[val.charCodeAt(0) - 33]);
output = output.map((val) => Z85[val.charCodeAt(0) - 33]!);
break;
}
return output.slice(0, output.length - difference).join("");

View File

@ -123,7 +123,7 @@ for (const [standard, tests] of Object.entries(testCasesNoDelimiter)) {
fn() {
for (const [bin, b85] of tests) {
assertEquals(
encodeAscii85(bin, {
encodeAscii85(bin as string, {
standard: standard as Ascii85Standard,
}),
b85,
@ -137,7 +137,9 @@ for (const [standard, tests] of Object.entries(testCasesNoDelimiter)) {
fn() {
for (const [bin, b85] of tests) {
assertEquals(
decodeAscii85(b85, { standard: standard as Ascii85Standard }),
decodeAscii85(b85 as string, {
standard: standard as Ascii85Standard,
}),
utf8encoder.encode(bin),
);
}
@ -151,7 +153,7 @@ for (const [standard, tests] of Object.entries(testCasesDelimiter)) {
fn() {
for (const [bin, b85] of tests) {
assertEquals(
encodeAscii85(bin, {
encodeAscii85(bin as string, {
standard: standard as Ascii85Standard,
delimiter: true,
}),
@ -166,7 +168,7 @@ for (const [standard, tests] of Object.entries(testCasesDelimiter)) {
fn() {
for (const [bin, b85] of tests) {
assertEquals(
decodeAscii85(b85, {
decodeAscii85(b85 as string, {
standard: standard as Ascii85Standard,
delimiter: true,
}),
@ -200,7 +202,7 @@ Deno.test({
["<~FCfN8Bl7P~>", "testing"],
["<~A7]XsCgh3l~>", "denoland"],
["<~@<5pmBfIsm@:X:cAH~>", "ascii85 adobe"],
];
] as const;
for (const [input, expect] of tests) {
assertEquals(

View File

@ -16,15 +16,9 @@
import { validateBinaryLike } from "./_util.ts";
const lookup: string[] = [];
const lookup: string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".split("");
const revLookup: number[] = [];
// RFC4648 base32
const code = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
for (let i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i];
revLookup[code.charCodeAt(i)] = i;
}
lookup.forEach((c, i) => revLookup[c.charCodeAt(0)] = i);
const placeHolderPadLookup = [0, 1, , 2, 3, , 4];
function _getPadLen(placeHoldersLen: number): number {
@ -79,55 +73,55 @@ export function decodeBase32(b32: string): Uint8Array {
let i: number;
for (i = 0; i < len; i += 8) {
tmp = (revLookup[b32.charCodeAt(i)] << 20) |
(revLookup[b32.charCodeAt(i + 1)] << 15) |
(revLookup[b32.charCodeAt(i + 2)] << 10) |
(revLookup[b32.charCodeAt(i + 3)] << 5) |
revLookup[b32.charCodeAt(i + 4)];
tmp = (revLookup[b32.charCodeAt(i)]! << 20) |
(revLookup[b32.charCodeAt(i + 1)]! << 15) |
(revLookup[b32.charCodeAt(i + 2)]! << 10) |
(revLookup[b32.charCodeAt(i + 3)]! << 5) |
revLookup[b32.charCodeAt(i + 4)]!;
arr[curByte++] = (tmp >> 17) & 0xff;
arr[curByte++] = (tmp >> 9) & 0xff;
arr[curByte++] = (tmp >> 1) & 0xff;
tmp = ((tmp & 1) << 15) |
(revLookup[b32.charCodeAt(i + 5)] << 10) |
(revLookup[b32.charCodeAt(i + 6)] << 5) |
revLookup[b32.charCodeAt(i + 7)];
(revLookup[b32.charCodeAt(i + 5)]! << 10) |
(revLookup[b32.charCodeAt(i + 6)]! << 5) |
revLookup[b32.charCodeAt(i + 7)]!;
arr[curByte++] = (tmp >> 8) & 0xff;
arr[curByte++] = tmp & 0xff;
}
if (placeHoldersLen === 1) {
tmp = (revLookup[b32.charCodeAt(i)] << 20) |
(revLookup[b32.charCodeAt(i + 1)] << 15) |
(revLookup[b32.charCodeAt(i + 2)] << 10) |
(revLookup[b32.charCodeAt(i + 3)] << 5) |
revLookup[b32.charCodeAt(i + 4)];
tmp = (revLookup[b32.charCodeAt(i)]! << 20) |
(revLookup[b32.charCodeAt(i + 1)]! << 15) |
(revLookup[b32.charCodeAt(i + 2)]! << 10) |
(revLookup[b32.charCodeAt(i + 3)]! << 5) |
revLookup[b32.charCodeAt(i + 4)]!;
arr[curByte++] = (tmp >> 17) & 0xff;
arr[curByte++] = (tmp >> 9) & 0xff;
arr[curByte++] = (tmp >> 1) & 0xff;
tmp = ((tmp & 1) << 7) |
(revLookup[b32.charCodeAt(i + 5)] << 2) |
(revLookup[b32.charCodeAt(i + 6)] >> 3);
(revLookup[b32.charCodeAt(i + 5)]! << 2) |
(revLookup[b32.charCodeAt(i + 6)]! >> 3);
arr[curByte++] = tmp & 0xff;
} else if (placeHoldersLen === 3) {
tmp = (revLookup[b32.charCodeAt(i)] << 19) |
(revLookup[b32.charCodeAt(i + 1)] << 14) |
(revLookup[b32.charCodeAt(i + 2)] << 9) |
(revLookup[b32.charCodeAt(i + 3)] << 4) |
(revLookup[b32.charCodeAt(i + 4)] >> 1);
tmp = (revLookup[b32.charCodeAt(i)]! << 19) |
(revLookup[b32.charCodeAt(i + 1)]! << 14) |
(revLookup[b32.charCodeAt(i + 2)]! << 9) |
(revLookup[b32.charCodeAt(i + 3)]! << 4) |
(revLookup[b32.charCodeAt(i + 4)]! >> 1);
arr[curByte++] = (tmp >> 16) & 0xff;
arr[curByte++] = (tmp >> 8) & 0xff;
arr[curByte++] = tmp & 0xff;
} else if (placeHoldersLen === 4) {
tmp = (revLookup[b32.charCodeAt(i)] << 11) |
(revLookup[b32.charCodeAt(i + 1)] << 6) |
(revLookup[b32.charCodeAt(i + 2)] << 1) |
(revLookup[b32.charCodeAt(i + 3)] >> 4);
tmp = (revLookup[b32.charCodeAt(i)]! << 11) |
(revLookup[b32.charCodeAt(i + 1)]! << 6) |
(revLookup[b32.charCodeAt(i + 2)]! << 1) |
(revLookup[b32.charCodeAt(i + 3)]! >> 4);
arr[curByte++] = (tmp >> 8) & 0xff;
arr[curByte++] = tmp & 0xff;
} else if (placeHoldersLen === 6) {
tmp = (revLookup[b32.charCodeAt(i)] << 3) |
(revLookup[b32.charCodeAt(i + 1)] >> 2);
tmp = (revLookup[b32.charCodeAt(i)]! << 3) |
(revLookup[b32.charCodeAt(i + 1)]! >> 2);
arr[curByte++] = tmp & 0xff;
}
@ -138,16 +132,16 @@ function encodeChunk(uint8: Uint8Array, start: number, end: number): string {
let tmp: number;
const output = [];
for (let i = start; i < end; i += 5) {
tmp = ((uint8[i] << 16) & 0xff0000) |
((uint8[i + 1] << 8) & 0xff00) |
(uint8[i + 2] & 0xff);
tmp = ((uint8[i]! << 16) & 0xff0000) |
((uint8[i + 1]! << 8) & 0xff00) |
(uint8[i + 2]! & 0xff);
output.push(lookup[(tmp >> 19) & 0x1f]);
output.push(lookup[(tmp >> 14) & 0x1f]);
output.push(lookup[(tmp >> 9) & 0x1f]);
output.push(lookup[(tmp >> 4) & 0x1f]);
tmp = ((tmp & 0xf) << 16) |
((uint8[i + 3] << 8) & 0xff00) |
(uint8[i + 4] & 0xff);
((uint8[i + 3]! << 8) & 0xff00) |
(uint8[i + 4]! & 0xff);
output.push(lookup[(tmp >> 15) & 0x1f]);
output.push(lookup[(tmp >> 10) & 0x1f]);
output.push(lookup[(tmp >> 5) & 0x1f]);
@ -191,22 +185,22 @@ export function encodeBase32(data: ArrayBuffer | Uint8Array | string): string {
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 4) {
tmp = ((uint8[len2] & 0xff) << 16) |
((uint8[len2 + 1] & 0xff) << 8) |
(uint8[len2 + 2] & 0xff);
tmp = ((uint8[len2]! & 0xff) << 16) |
((uint8[len2 + 1]! & 0xff) << 8) |
(uint8[len2 + 2]! & 0xff);
parts.push(lookup[(tmp >> 19) & 0x1f]);
parts.push(lookup[(tmp >> 14) & 0x1f]);
parts.push(lookup[(tmp >> 9) & 0x1f]);
parts.push(lookup[(tmp >> 4) & 0x1f]);
tmp = ((tmp & 0xf) << 11) | (uint8[len2 + 3] << 3);
tmp = ((tmp & 0xf) << 11) | (uint8[len2 + 3]! << 3);
parts.push(lookup[(tmp >> 10) & 0x1f]);
parts.push(lookup[(tmp >> 5) & 0x1f]);
parts.push(lookup[tmp & 0x1f]);
parts.push("=");
} else if (extraBytes === 3) {
tmp = ((uint8[len2] & 0xff) << 17) |
((uint8[len2 + 1] & 0xff) << 9) |
((uint8[len2 + 2] & 0xff) << 1);
tmp = ((uint8[len2]! & 0xff) << 17) |
((uint8[len2 + 1]! & 0xff) << 9) |
((uint8[len2 + 2]! & 0xff) << 1);
parts.push(lookup[(tmp >> 20) & 0x1f]);
parts.push(lookup[(tmp >> 15) & 0x1f]);
parts.push(lookup[(tmp >> 10) & 0x1f]);
@ -214,14 +208,15 @@ export function encodeBase32(data: ArrayBuffer | Uint8Array | string): string {
parts.push(lookup[tmp & 0x1f]);
parts.push("===");
} else if (extraBytes === 2) {
tmp = ((uint8[len2] & 0xff) << 12) | ((uint8[len2 + 1] & 0xff) << 4);
tmp = ((uint8[len2]! & 0xff) << 12) |
((uint8[len2 + 1]! & 0xff) << 4);
parts.push(lookup[(tmp >> 15) & 0x1f]);
parts.push(lookup[(tmp >> 10) & 0x1f]);
parts.push(lookup[(tmp >> 5) & 0x1f]);
parts.push(lookup[tmp & 0x1f]);
parts.push("====");
} else if (extraBytes === 1) {
tmp = (uint8[len2] & 0xff) << 2;
tmp = (uint8[len2]! & 0xff) << 2;
parts.push(lookup[(tmp >> 5) & 0x1f]);
parts.push(lookup[tmp & 0x1f]);
parts.push("======");

View File

@ -85,7 +85,7 @@ const testCases = [
"f2fc2319bd29457ccd01e8e194ee9bd7e97298b6610df4ab0f3d5baa0b2d7ccf69829edb74edef",
"6L6CGGN5FFCXZTIB5DQZJ3U327UXFGFWMEG7JKYPHVN2UCZNPTHWTAU63N2O33Y=",
],
];
] as const;
Deno.test({
name: "encodeBase32()",

View File

@ -81,7 +81,9 @@ export function encodeBase58(data: ArrayBuffer | Uint8Array | string): string {
strResult.fill("1", 0, zeroes);
}
b58Encoding.forEach((byteValue) => strResult.push(base58alphabet[byteValue]));
b58Encoding.forEach((byteValue) =>
strResult.push(base58alphabet[byteValue]!)
);
return strResult.join("");
}

View File

@ -26,7 +26,7 @@ const testSetString = [
]),
"HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F",
],
];
] as const;
const testSetBinary = testSetString.map(([data, b58]) => {
if (typeof data === "string") {

View File

@ -99,22 +99,31 @@ export function encodeBase64(data: ArrayBuffer | Uint8Array | string): string {
i;
const l = uint8.length;
for (i = 2; i < l; i += 3) {
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];
result += base64abc[((uint8[i - 1] & 0x0f) << 2) | (uint8[i] >> 6)];
result += base64abc[uint8[i] & 0x3f];
result += base64abc[(uint8[i - 2]!) >> 2];
result += base64abc[
(((uint8[i - 2]!) & 0x03) << 4) |
((uint8[i - 1]!) >> 4)
];
result += base64abc[
(((uint8[i - 1]!) & 0x0f) << 2) |
((uint8[i]!) >> 6)
];
result += base64abc[(uint8[i]!) & 0x3f];
}
if (i === l + 1) {
// 1 octet yet to write
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[(uint8[i - 2] & 0x03) << 4];
result += base64abc[(uint8[i - 2]!) >> 2];
result += base64abc[((uint8[i - 2]!) & 0x03) << 4];
result += "==";
}
if (i === l) {
// 2 octets yet to write
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];
result += base64abc[(uint8[i - 1] & 0x0f) << 2];
result += base64abc[(uint8[i - 2]!) >> 2];
result += base64abc[
(((uint8[i - 2]!) & 0x03) << 4) |
((uint8[i - 1]!) >> 4)
];
result += base64abc[((uint8[i - 1]!) & 0x0f) << 2];
result += "=";
}
return result;

View File

@ -12,7 +12,7 @@ const testsetString = [
["foob", "Zm9vYg=="],
["fooba", "Zm9vYmE="],
["foobar", "Zm9vYmFy"],
];
] as const;
const testsetBinary = testsetString.map(([str, b64]) => [
new TextEncoder().encode(str),

View File

@ -29,7 +29,7 @@ const testsetInvalid = [
Deno.test("encodeBase64Url() encodes string", () => {
for (const [input, output] of testsetString) {
assertEquals(encodeBase64Url(input), output);
assertEquals(encodeBase64Url(input!), output);
}
});

View File

@ -70,9 +70,9 @@ export function encodeHex(src: string | Uint8Array | ArrayBuffer): string {
const dst = new Uint8Array(u8.length * 2);
for (let i = 0; i < dst.length; i++) {
const v = u8[i];
dst[i * 2] = hexTable[v >> 4];
dst[i * 2 + 1] = hexTable[v & 0x0f];
const v = u8[i]!;
dst[i * 2] = hexTable[v >> 4]!;
dst[i * 2 + 1] = hexTable[v & 0x0f]!;
}
return textDecoder.decode(dst);
}
@ -92,15 +92,15 @@ export function decodeHex(src: string): Uint8Array {
const u8 = textEncoder.encode(src);
const dst = new Uint8Array(u8.length / 2);
for (let i = 0; i < dst.length; i++) {
const a = fromHexChar(u8[i * 2]);
const b = fromHexChar(u8[i * 2 + 1]);
const a = fromHexChar(u8[i * 2]!);
const b = fromHexChar(u8[i * 2 + 1]!);
dst[i] = (a << 4) | b;
}
if (u8.length % 2 === 1) {
// Check for invalid char before reporting bad length,
// since the invalid char (if present) is an earlier problem.
fromHexChar(u8[dst.length * 2]);
fromHexChar(u8[dst.length * 2]!);
throw errLength();
}

View File

@ -53,7 +53,7 @@ export function decode(buf: Uint8Array, offset = 0): [bigint, number] {
let byte;
do {
// Get a single byte from the buffer
byte = buf[i];
byte = buf[i]!;
// 1. Take the lower 7 bits of the byte.
// 2. Shift the bits into the correct position.
@ -120,7 +120,7 @@ export function decode32(buf: Uint8Array, offset = 0): [number, number] {
i <= len;
i += 1, shift += SHIFT
) {
const byte = buf[i];
const byte = buf[i]!;
decoded += (byte & REST) * Math.pow(2, shift);
if (!(byte & MSB)) return [decoded, i + 1];
}