From 8267fd8a524b08ab1ef4e5cca918aff984a21875 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 4 May 2022 15:03:46 +0200 Subject: [PATCH] Replace the `AnnotationStorage.lastModified`-getter with a proper hash-method The current `lastModified`-getter, which only contains a time-stamp, is a fairly crude way of detecting if the stored data has actually been changed. In particular, when the `getRawValue`-method is used, the `lastModified`-getter doesn't cope with data being modified from the "outside". To fix these issues[1], and to prevent any future bugs in this code, this patch introduces a new `AnnotationStorage.hash`-getter which computes a hash of the currently stored data. To simplify things this re-uses the existing `MurmurHash3_64`-implementation, which required moving that file into the `src/shared/`-folder, since its performance should be good enough here. --- [1] Given how the `AnnotationStorage.lastModified`-getter was used, this would have been limited to *printing* of forms. --- src/core/evaluator.js | 2 +- src/display/annotation_storage.js | 12 ++++++++---- src/display/api.js | 6 +++--- src/{core => shared}/murmurhash3.js | 2 +- test/unit/murmurhash3_spec.js | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) rename src/{core => shared}/murmurhash3.js (98%) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index b9b55c8e6..68dcab9aa 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -75,7 +75,7 @@ import { DecodeStream } from "./decode_stream.js"; import { getGlyphsUnicode } from "./glyphlist.js"; import { getLookupTableFactory } from "./core_utils.js"; import { getMetrics } from "./metrics.js"; -import { MurmurHash3_64 } from "./murmurhash3.js"; +import { MurmurHash3_64 } from "../shared/murmurhash3.js"; import { OperatorList } from "./operator_list.js"; import { PDFImage } from "./image.js"; diff --git a/src/display/annotation_storage.js b/src/display/annotation_storage.js index 43099079b..458dceadc 100644 --- a/src/display/annotation_storage.js +++ b/src/display/annotation_storage.js @@ -13,6 +13,7 @@ * limitations under the License. */ +import { MurmurHash3_64 } from "../shared/murmurhash3.js"; import { objectFromMap } from "../shared/util.js"; /** @@ -21,7 +22,6 @@ import { objectFromMap } from "../shared/util.js"; class AnnotationStorage { constructor() { this._storage = new Map(); - this._timeStamp = Date.now(); this._modified = false; // Callbacks to signal when the modification state is set or reset. @@ -85,7 +85,6 @@ class AnnotationStorage { this._storage.set(key, value); } if (modified) { - this._timeStamp = Date.now(); this._setModified(); } } @@ -131,8 +130,13 @@ class AnnotationStorage { * PLEASE NOTE: Only intended for usage within the API itself. * @ignore */ - get lastModified() { - return this._timeStamp.toString(); + get hash() { + const hash = new MurmurHash3_64(); + + for (const [key, value] of this._storage) { + hash.update(`${key}:${JSON.stringify(value)}`); + } + return hash.hexdigest(); } } diff --git a/src/display/api.js b/src/display/api.js index 9c4c5f0b5..89ef148a2 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -2402,7 +2402,7 @@ class WorkerTransport { isOpList = false ) { let renderingIntent = RenderingIntentFlag.DISPLAY; // Default value. - let lastModified = ""; + let annotationHash = ""; switch (intent) { case "any": @@ -2429,7 +2429,7 @@ class WorkerTransport { case AnnotationMode.ENABLE_STORAGE: renderingIntent += RenderingIntentFlag.ANNOTATIONS_STORAGE; - lastModified = this.annotationStorage.lastModified; + annotationHash = this.annotationStorage.hash; break; default: warn(`getRenderingIntent - invalid annotationMode: ${annotationMode}`); @@ -2441,7 +2441,7 @@ class WorkerTransport { return { renderingIntent, - cacheKey: `${renderingIntent}_${lastModified}`, + cacheKey: `${renderingIntent}_${annotationHash}`, }; } diff --git a/src/core/murmurhash3.js b/src/shared/murmurhash3.js similarity index 98% rename from src/core/murmurhash3.js rename to src/shared/murmurhash3.js index fca00f0f0..f8412ad9f 100644 --- a/src/core/murmurhash3.js +++ b/src/shared/murmurhash3.js @@ -17,7 +17,7 @@ * Hashes roughly 100 KB per millisecond on i7 3.4 GHz. */ -import { isArrayBuffer } from "../shared/util.js"; +import { isArrayBuffer } from "./util.js"; const SEED = 0xc3d2e1f0; // Workaround for missing math precision in JS. diff --git a/test/unit/murmurhash3_spec.js b/test/unit/murmurhash3_spec.js index a665b165b..ed8777b34 100644 --- a/test/unit/murmurhash3_spec.js +++ b/test/unit/murmurhash3_spec.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { MurmurHash3_64 } from "../../src/core/murmurhash3.js"; +import { MurmurHash3_64 } from "../../src/shared/murmurhash3.js"; describe("MurmurHash3_64", function () { it("instantiates without seed", function () {