patch-msdoc-viewer.mjs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import fs from 'node:fs'
  2. import path from 'node:path'
  3. import { createRequire } from 'node:module'
  4. const rootRequire = createRequire(import.meta.url)
  5. const coreRequire = createRequire(path.resolve('packages/core/package.json'))
  6. const wordRendererRequire = createRequire(path.resolve('packages/renderers/word/package.json'))
  7. const ORIGINAL_READ_SECTOR = `function readSectorAbsolute(bytes, sectorSize, sid) {
  8. const start = 512 + sid * sectorSize;
  9. const end = start + sectorSize;
  10. if (start < 0 || end > bytes.length) {
  11. throw new Error(\`Sector \${sid} is out of bounds\`);
  12. }
  13. return bytes.subarray(start, end);
  14. }`
  15. const PATCHED_READ_SECTOR = `function readSectorAbsolute(bytes, sectorSize, sid) {
  16. const start = 512 + sid * sectorSize;
  17. const end = start + sectorSize;
  18. if (start < 0 || start >= bytes.length) {
  19. throw new Error(\`Sector \${sid} is out of bounds\`);
  20. }
  21. if (end <= bytes.length) {
  22. return bytes.subarray(start, end);
  23. }
  24. const sector = new Uint8Array(sectorSize);
  25. sector.set(bytes.subarray(start));
  26. return sector;
  27. }`
  28. function resolveCfbPath() {
  29. let packageJsonPath
  30. try {
  31. packageJsonPath = wordRendererRequire.resolve('msdoc-viewer/package.json')
  32. } catch {
  33. try {
  34. packageJsonPath = rootRequire.resolve('msdoc-viewer/package.json')
  35. } catch {
  36. packageJsonPath = coreRequire.resolve('msdoc-viewer/package.json')
  37. }
  38. }
  39. return path.join(path.dirname(packageJsonPath), 'dist/core/cfb.js')
  40. }
  41. function patchMsDocViewer() {
  42. const cfbPath = resolveCfbPath()
  43. const source = fs.readFileSync(cfbPath, 'utf8')
  44. if (source.includes(PATCHED_READ_SECTOR)) {
  45. console.log('[file-viewer] msdoc-viewer CFB patch already applied.')
  46. return
  47. }
  48. if (!source.includes(ORIGINAL_READ_SECTOR)) {
  49. throw new Error(
  50. [
  51. '[file-viewer] Unable to patch msdoc-viewer: expected readSectorAbsolute implementation was not found.',
  52. `Checked file: ${cfbPath}`,
  53. 'The dependency may have changed; please review the CFB partial-sector compatibility fix manually.'
  54. ].join('\n')
  55. )
  56. }
  57. fs.writeFileSync(cfbPath, source.replace(ORIGINAL_READ_SECTOR, PATCHED_READ_SECTOR))
  58. console.log('[file-viewer] Patched msdoc-viewer CFB partial-sector reader.')
  59. }
  60. try {
  61. patchMsDocViewer()
  62. } catch (error) {
  63. console.error(error instanceof Error ? error.message : error)
  64. process.exitCode = 1
  65. }