Skip to content

Commit

Permalink
copying of fix for objectstore from nats-io/nats.deno#746
Browse files Browse the repository at this point in the history
Signed-off-by: Alberto Ricart <alberto@synadia.com>
  • Loading branch information
aricart committed Feb 7, 2025
1 parent 47338f4 commit 97874da
Show file tree
Hide file tree
Showing 7 changed files with 538 additions and 383 deletions.
3 changes: 2 additions & 1 deletion obj/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
},
"imports": {
"@nats-io/nats-core": "jsr:@nats-io/nats-core@~3.0.0-50",
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-37"
"@nats-io/jetstream": "jsr:@nats-io/jetstream@~3.0.0-37",
"js-sha256": "npm:js-sha256@0.11.0"
}
}
2 changes: 1 addition & 1 deletion obj/src/internal_mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ export { StorageType } from "./types.ts";

export { Objm } from "./objectstore.ts";

export { SHA256, sha256 } from "./sha256.ts";
export { sha256 } from "./js-sha256.js";

export { Base64Codec, Base64UrlCodec, Base64UrlPaddedCodec } from "./base64.ts";
404 changes: 404 additions & 0 deletions obj/src/js-sha256.js

Large diffs are not rendered by default.

36 changes: 22 additions & 14 deletions obj/src/objectstore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022-2024 The NATS Authors
* Copyright 2022-2025 The NATS Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
Expand Down Expand Up @@ -68,8 +68,9 @@ import type {
ObjectStoreStatus,
ObjectWatchInfo,
} from "./types.ts";
import { SHA256 } from "./sha256.ts";
import { Base64UrlPaddedCodec } from "./base64.ts";
import { sha256 } from "./js-sha256.js";
import { checkSha256, parseSha256 } from "./sha_digest.parser.ts";

export const osPrefix = "OBJ_";
export const digestType = "SHA-256=";
Expand Down Expand Up @@ -470,7 +471,7 @@ export class ObjectStoreImpl implements ObjectStore {
const db = new DataBuffer();
try {
const reader = rs ? rs.getReader() : null;
const sha = new SHA256();
const sha = sha256.create();

while (true) {
const { done, value } = reader
Expand All @@ -491,10 +492,11 @@ export class ObjectStoreImpl implements ObjectStore {

// prepare the metadata
info.mtime = new Date().toISOString();
const digest = sha.digest("base64");
const pad = digest.length % 3;
const padding = pad > 0 ? "=".repeat(pad) : "";
info.digest = `${digestType}${digest}${padding}`;
const digest = Base64UrlPaddedCodec.encode(
Uint8Array.from(sha.digest()),
);
info.digest = `${digestType}${digest}`;

info.deleted = false;

// trailing md for the object
Expand Down Expand Up @@ -640,6 +642,16 @@ export class ObjectStoreImpl implements ObjectStore {
return os.get(ln);
}

if (!info.digest.startsWith(digestType)) {
return Promise.reject(new Error(`unknown digest type: ${info.digest}`));
}
const digest = parseSha256(info.digest.substring(8));
if (digest === null) {
return Promise.reject(
new Error(`unable to parse digest: ${info.digest}`),
);
}

const d = deferred<Error | null>();

const r: Partial<ObjectResult> = {
Expand All @@ -652,7 +664,7 @@ export class ObjectStoreImpl implements ObjectStore {
return Promise.resolve(r as ObjectResult);
}

const sha = new SHA256();
const sha = sha256.create();
let controller: ReadableStreamDefaultController;

const cc: Partial<ConsumerConfig> = {};
Expand All @@ -667,12 +679,8 @@ export class ObjectStoreImpl implements ObjectStore {
controller!.enqueue(jm.data);
}
if (jm.info.pending === 0) {
const hash = sha.digest("base64");
// go pads the hash - which should be multiple of 3 - otherwise pads with '='
const pad = hash.length % 3;
const padding = pad > 0 ? "=".repeat(pad) : "";
const digest = `${digestType}${hash}${padding}`;
if (digest !== info.digest) {
const digest = Uint8Array.from(sha.digest());
if (!checkSha256(digest, Uint8Array.from(sha.digest()))) {
controller!.error(
new Error(
`received a corrupt object, digests do not match received: ${info.digest} calculated ${digest}`,
Expand Down
Loading

0 comments on commit 97874da

Please sign in to comment.