]> Lady’s Gitweb - Pisces/commitdiff
Make base32 handling less forgiving 0.3.1
authorLady <redacted>
Mon, 22 May 2023 02:50:19 +0000 (19:50 -0700)
committerLady <redacted>
Mon, 22 May 2023 02:50:19 +0000 (19:50 -0700)
Ordinarily, one only encounters base32 strings of length 0, 2, 4, 5, or
7 characters (mod 8). If it is of length 3 or 6, the final character is
in the middle of an incomplete byte. As with length 1, this should
probably throw an error, as the other alternative is to entirely ignore
the character.

(It already did throw an error before this change, but
unintentionally.)

binary.js
binary.test.js

index 5c78d3916cc1dabd25d528d3a72bba443091c8bb..5ee2bda874ae5fcf84a577064c0f8e0c41770895 100644 (file)
--- a/binary.js
+++ b/binary.js
@@ -135,10 +135,13 @@ const decodeBase16 = (source) => {
   );
   const { length } = u4s;
   if (length % 2 == 1) {
   );
   const { length } = u4s;
   if (length % 2 == 1) {
+    // The length is such that an entire letter would be dropped during
+    // a forgiving decode.
     throw new RangeError(
       `Piscēs: Base16 string has invalid length: ${source}.`,
     );
   } else {
     throw new RangeError(
       `Piscēs: Base16 string has invalid length: ${source}.`,
     );
   } else {
+    // Every letter contributes at least some bits to the result.
     const dataView = new View(new Buffer(floor(length / 2)));
     for (let index = 0; index < length - 1;) {
       call(viewSetUint8, dataView, [
     const dataView = new View(new Buffer(floor(length / 2)));
     for (let index = 0; index < length - 1;) {
       call(viewSetUint8, dataView, [
@@ -224,11 +227,15 @@ const decodeBase32 = (source, wrmg) => {
     },
   );
   const { length } = u5s;
     },
   );
   const { length } = u5s;
-  if (length % 8 == 1) {
+  const lengthMod8 = length % 8;
+  if (lengthMod8 == 1 || lengthMod8 == 3 || lengthMod8 == 6) {
+    // The length is such that an entire letter would be dropped during
+    // a forgiving decode.
     throw new RangeError(
       `Piscēs: Base32 string has invalid length: ${source}.`,
     );
   } else {
     throw new RangeError(
       `Piscēs: Base32 string has invalid length: ${source}.`,
     );
   } else {
+    // Every letter contributes at least some bits to the result.
     const dataView = new View(new Buffer(floor(length * 5 / 8)));
     for (let index = 0; index < length - 1;) {
       // The final index is not handled; if the string is not divisible
     const dataView = new View(new Buffer(floor(length * 5 / 8)));
     for (let index = 0; index < length - 1;) {
       // The final index is not handled; if the string is not divisible
@@ -302,10 +309,13 @@ const decodeBase64 = (source, safe = false) => {
   );
   const { length } = u6s;
   if (length % 4 == 1) {
   );
   const { length } = u6s;
   if (length % 4 == 1) {
+    // The length is such that an entire letter would be dropped during
+    // a forgiving decode.
     throw new RangeError(
       `Piscēs: Base64 string has invalid length: ${source}.`,
     );
   } else {
     throw new RangeError(
       `Piscēs: Base64 string has invalid length: ${source}.`,
     );
   } else {
+    // Every letter contributes at least some bits to the result.
     const dataView = new View(new Buffer(floor(length * 3 / 4)));
     for (let index = 0; index < length - 1;) {
       // The final index is not handled; if the string is not divisible
     const dataView = new View(new Buffer(floor(length * 3 / 4)));
     for (let index = 0; index < length - 1;) {
       // The final index is not handled; if the string is not divisible
index f3c831764db4737ee98e7bc881601a881dc6ab8e..82fa4e030003ba18ca699eae9d742e2183e6e692 100755 (executable)
@@ -356,9 +356,11 @@ describe("base32Binary", () => {
     assertThrows(() => base32Binary("CT3ZYAY=="));
   });
 
     assertThrows(() => base32Binary("CT3ZYAY=="));
   });
 
-  it("[[Call]] throws when provided with a length with a remainder of 1 when divided by 4", () => {
+  it("[[Call]] throws when provided with a length with a remainder of 1, 3 ∣ 6 when divided by 8", () => {
     assertThrows(() => base32Binary("234BCDEAA"));
     assertThrows(() => base32Binary("234BCDEAA======="));
     assertThrows(() => base32Binary("234BCDEAA"));
     assertThrows(() => base32Binary("234BCDEAA======="));
+    assertThrows(() => base32Binary("UHI"));
+    assertThrows(() => base32Binary("UHIUJD"));
   });
 });
 
   });
 });
 
@@ -863,6 +865,13 @@ describe("wrmgBase32Binary", () => {
     assertThrows(() => wrmgBase32Binary("ABC="));
   });
 
     assertThrows(() => wrmgBase32Binary("ABC="));
   });
 
+  it("[[Call]] throws when provided with a length with a remainder of 1, 3 ∣ 6 when divided by 8", () => {
+    assertThrows(() => base32Binary("TVW123400"));
+    assertThrows(() => base32Binary("TVW123400======="));
+    assertThrows(() => base32Binary("M78"));
+    assertThrows(() => base32Binary("M78M93"));
+  });
+
   it("[[Call]] throws when provided with a length with a remainder of 1 when divided by 4", () => {
     assertThrows(() => wrmgBase32Binary("234BCDEAA"));
     assertThrows(() => wrmgBase32Binary("2-34-B--CD-EA-A-"));
   it("[[Call]] throws when provided with a length with a remainder of 1 when divided by 4", () => {
     assertThrows(() => wrmgBase32Binary("234BCDEAA"));
     assertThrows(() => wrmgBase32Binary("2-34-B--CD-EA-A-"));
This page took 0.029438 seconds and 4 git commands to generate.