Skip to content

Commit

Permalink
fix(hgetall): handle unsafe integer in deserialization (#664)
Browse files Browse the repository at this point in the history
* fix(hgetall): handle unsafe integer in deserialization

* test: add test for randomUnsafeIntegerString()

* fix(test-utils): Fix randomUnsafeIntegerString implementation

* Format changes with fmt

---------

Co-authored-by: ogzhanolguncu <ogzhan11@gmail.com>
  • Loading branch information
ImBIOS and ogzhanolguncu authored Oct 18, 2023
1 parent 6460921 commit bf6288e
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 3 deletions.
34 changes: 34 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 25 additions & 2 deletions pkg/commands/hgetall.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { keygen, newHttpClient, randomID } from "../test-utils.ts";
import { assertEquals } from "https://deno.land/std@0.177.0/testing/asserts.ts";
import { afterAll } from "https://deno.land/std@0.177.0/testing/bdd.ts";
import { HSetCommand } from "./hset.ts";
import {
keygen,
newHttpClient,
randomID,
randomUnsafeIntegerString,
} from "../test-utils.ts";
import { HGetAllCommand } from "./hgetall.ts";
import { HSetCommand } from "./hset.ts";

const client = newHttpClient();

Expand All @@ -29,3 +34,21 @@ Deno.test("when hash does not exist", async (t) => {
assertEquals(res, null);
});
});
Deno.test("properly return bigint precisely", async () => {
const key = newKey();
const field3 = randomID();
const field2 = randomID();
const field1 = randomID();
const value1 = false;
const value2 = randomID();
const value3 = randomUnsafeIntegerString();
await new HSetCommand([
key,
{ [field1]: value1, [field2]: value2, [field3]: value3 },
]).exec(client);

const res = await new HGetAllCommand([key]).exec(client);

const obj = { [field1]: value1, [field2]: value2, [field3]: value3 };
assertEquals(res, obj);
});
9 changes: 8 additions & 1 deletion pkg/commands/hgetall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ function deserialize<TData extends Record<string, unknown>>(
const key = result.shift()!;
const value = result.shift()!;
try {
obj[key] = JSON.parse(value);
// handle unsafe integer
const valueIsNumberAndNotSafeInteger = !isNaN(Number(value)) &&
!Number.isSafeInteger(value);
if (valueIsNumberAndNotSafeInteger) {
obj[key] = value;
} else {
obj[key] = JSON.parse(value);
}
} catch {
obj[key] = value;
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/test-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
assertEquals,
assertFalse,
} from "https://deno.land/std@0.177.0/testing/asserts.ts";
import { randomUnsafeIntegerString } from "./test-utils.ts";

Deno.test("randomUnsafeIntegerString() should return a string", () => {
const result = randomUnsafeIntegerString();
assertEquals(typeof result, "string");
});
Deno.test("randomUnsafeIntegerString() should return different values", () => {
const result1 = randomUnsafeIntegerString();
const result2 = randomUnsafeIntegerString();
assertEquals(result1 !== result2, true);
});
Deno.test(
"randomUnsafeIntegerString() should return a string with unsafe integer",
() => {
const result = randomUnsafeIntegerString();
assertFalse(Number.isSafeInteger(Number(result)));
},
);
7 changes: 7 additions & 0 deletions pkg/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ export function randomID(): string {
}
return btoa(s.join(""));
}
export const randomUnsafeIntegerString = (): string => {
const buffer = new Uint8Array(8);
crypto.getRandomValues(buffer);
const dataView = new DataView(buffer.buffer);
const unsafeInteger = dataView.getBigInt64(0, true); // true for little-endian
return unsafeInteger.toString();
};
export const newHttpClient = () => {
const url = Deno.env.get("UPSTASH_REDIS_REST_URL");
if (!url) {
Expand Down

0 comments on commit bf6288e

Please sign in to comment.