Skip to content

Commit

Permalink
add integrity hash for wasm (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
hillac authored Aug 28, 2024
1 parent 2e2a313 commit f2fbd15
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
3 changes: 2 additions & 1 deletion demo/vite/package-lock.json

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

15 changes: 15 additions & 0 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import rollupReplace from "@rollup/plugin-replace";
import typescript from "@rollup/plugin-typescript";
import copyPlugin from "rollup-plugin-copy";
import deletePlugin from "rollup-plugin-delete";
import crypto from "node:crypto";

const pkg = JSON.parse(fs.readFileSync("./package.json", "utf-8"));

Expand Down Expand Up @@ -63,6 +64,18 @@ function injectDebugLog({ message }) {
};
}

const wasmFile = fs.readFileSync("src/vendor/pdfium.wasm");
const wasmSHA256B64 = crypto.createHash("sha256").update(wasmFile).digest("base64");

function injectWasmHash() {
return rollupReplace({
preventAssignment: true,
values: {
__WASM_SHA265_B64__: JSON.stringify(wasmSHA256B64),
},
});
}

export default [
// CommonJS build
{
Expand All @@ -77,6 +90,7 @@ export default [
deletePlugin({ targets: `${DIST_FOLDER}/*` }),
!IS_PROD && injectDebugLog({ message: "PDFium CJS loaded" }),
injectPackageVersion(),
injectWasmHash(),
resolve(),
typescript(),
commonjs({
Expand All @@ -102,6 +116,7 @@ export default [
!IS_PROD && injectDebugLog({ message: "PDFium ESM loaded" }),
...nodeEsmShim(),
injectPackageVersion(),
injectWasmHash(),
resolve(),
typescript(),
commonjs({
Expand Down
31 changes: 24 additions & 7 deletions src/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ import { lengthBytesUTF8, stringToUTF8 } from "./emscripten";

// This global variable is defined by Rollup at build time
declare const __PACKAGE_VERSION__: string;
declare const __WASM_SHA265_B64__: string;

const CDN_WASM_WARNING = `@hyzyla/pdfium: You are using the default CDN URL to load the PDFium wasm binary. For better performance, consider hosting the wasm binary yourself and passing it to the PDFiumLibrary.init method using the 'wasmBinary' option or by providing a 'wasmUrl' pointing to your own CDN or server. You can also disable this warning by passing the 'disableWarningAboutCDN' option to PDFiumLibrary.init method.`;
const CDN_BROWSER_WARNING = `@hyzyla/pdfium: The useCDN option is only available in browser environment.`;
const NO_OPTION_WARNING = `@hyzyla/pdfium: wasmUrl, wasmBinary or useCDN option is required.`;

const CDN_WASM_LINK = `https://cdn.jsdelivr.net/npm/@hyzyla/pdfium@${__PACKAGE_VERSION__}/dist/pdfium.wasm`;

const WASM_INTEGRITY = `sha256-${__WASM_SHA265_B64__}`;

/**
* Converts a JavaScript string to a null-terminated C string and returns
* a pointer to the allocated memory.
Expand All @@ -35,6 +40,7 @@ function stringToCString(module: t.PDFium, str: string): number {
type PDFiumLibraryInitOptions = {
wasmUrl?: string;
wasmBinary?: ArrayBuffer;
useCDN?: boolean;
disableWarningAboutCDN?: boolean;
};

Expand All @@ -47,13 +53,20 @@ export class PDFiumLibrary {
loadOptions.locateFile = (path: string) => wasmUrl;
} else if (wasmBinary) {
loadOptions.wasmBinary = wasmBinary;
} else {
if (typeof window !== "undefined") {
loadOptions.locateFile = (path: string) => CDN_WASM_LINK;
if (!options?.disableWarningAboutCDN) {
console.warn(CDN_WASM_WARNING);
}
} else if (options?.useCDN) {
if (typeof window === "undefined") {
console.warn(CDN_BROWSER_WARNING);
throw new Error(CDN_BROWSER_WARNING);
}
const req = await fetch(CDN_WASM_LINK, { integrity: WASM_INTEGRITY });
const wasmBinary = await req.arrayBuffer();
loadOptions.wasmBinary = wasmBinary;
if (!options?.disableWarningAboutCDN) {
console.warn(CDN_WASM_WARNING);
}
} else {
console.warn(NO_OPTION_WARNING);
throw new Error(NO_OPTION_WARNING);
}

const module = await vendor(loadOptions);
Expand Down Expand Up @@ -98,7 +111,11 @@ export class PDFiumLibrary {
// This line reads the PDF document from the memory block starting at documentPtr and of size bytes.
// If the document is password-protected, the password should be provided as a null-terminated C string.
// The function returns a document index (handle) that can be used to interact with the document.
const documentIdx = this.module._FPDF_LoadMemDocument(documentPtr, size, passwordPtr);
const documentIdx = this.module._FPDF_LoadMemDocument(
documentPtr,
size,
passwordPtr
);

// Handle error if the document could not be loaded
const lastError = this.module._FPDF_GetLastError();
Expand Down

0 comments on commit f2fbd15

Please sign in to comment.