diff --git a/package-lock.json b/package-lock.json index f357177335..882caeb4ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23390,14 +23390,6 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" }, - "node_modules/pdfjs-dist": { - "version": "2.7.570", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.7.570.tgz", - "integrity": "sha512-/ZkA1FwkEOyDaq11JhMLazdwQAA0F9uwrP7h/1L9Akt9KWh1G5/tkzS+bPuUELq2s2GDFnaT+kooN/aSjT7DXQ==", - "peerDependencies": { - "worker-loader": "^3.0.7" - } - }, "node_modules/pdfjs-dist210": { "name": "pdfjs-dist", "version": "2.10.377", @@ -31849,7 +31841,6 @@ "lockfile": "^1.0.4", "lodash": "^4.17.21", "p-limit": "^3.1.0", - "pdfjs-dist": "~2.7.570", "request": "^2.88.2", "send": "^0.17.1", "workerpool": "^6.1.5" @@ -39703,7 +39694,6 @@ "mocha": "^8.4.0", "mock-fs": "^5.1.2", "p-limit": "^3.1.0", - "pdfjs-dist": "~2.7.570", "request": "^2.88.2", "sandboxed-module": "^2.0.4", "send": "^0.17.1", @@ -59303,12 +59293,6 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" }, - "pdfjs-dist": { - "version": "2.7.570", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.7.570.tgz", - "integrity": "sha512-/ZkA1FwkEOyDaq11JhMLazdwQAA0F9uwrP7h/1L9Akt9KWh1G5/tkzS+bPuUELq2s2GDFnaT+kooN/aSjT7DXQ==", - "requires": {} - }, "pdfjs-dist210": { "version": "npm:pdfjs-dist@2.10.377", "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.10.377.tgz", diff --git a/services/clsi/app/js/ContentCacheManager.js b/services/clsi/app/js/ContentCacheManager.js index 44288077bd..38789a974a 100644 --- a/services/clsi/app/js/ContentCacheManager.js +++ b/services/clsi/app/js/ContentCacheManager.js @@ -9,8 +9,12 @@ const Path = require('path') const Settings = require('@overleaf/settings') const OError = require('@overleaf/o-error') const pLimit = require('p-limit') -const { parseXrefTable } = require('../lib/pdfjs/parseXrefTable') -const { QueueLimitReachedError, TimedOutError } = require('./Errors') +const { parseXrefTable } = require('./XrefParser') +const { + QueueLimitReachedError, + TimedOutError, + NoXrefTableError, +} = require('./Errors') const workerpool = require('workerpool') const Metrics = require('@overleaf/metrics') @@ -89,6 +93,9 @@ async function updateOtherEventLoop(contentDir, filePath, size, compileTime) { if (e.message?.includes?.('Max queue size of ')) { throw new QueueLimitReachedError() } + if (e.message?.includes?.('xref')) { + throw new NoXrefTableError(e.message) + } throw e } } @@ -115,6 +122,7 @@ async function updateSameEventLoop(contentDir, filePath, size, compileTime) { size, checkDeadline ) + xRefEntries.sort((a, b) => { return a.offset - b.offset }) diff --git a/services/clsi/app/js/Errors.js b/services/clsi/app/js/Errors.js index a3eb8d9fd9..4e23a833d3 100644 --- a/services/clsi/app/js/Errors.js +++ b/services/clsi/app/js/Errors.js @@ -33,6 +33,7 @@ AlreadyCompilingError.prototype.__proto__ = Error.prototype class QueueLimitReachedError extends OError {} class TimedOutError extends OError {} +class NoXrefTableError extends OError {} module.exports = Errors = { QueueLimitReachedError, @@ -40,4 +41,5 @@ module.exports = Errors = { NotFoundError, FilesOutOfSyncError, AlreadyCompilingError, + NoXrefTableError, } diff --git a/services/clsi/app/js/OutputCacheManager.js b/services/clsi/app/js/OutputCacheManager.js index c92a119d2a..f7f1d04f69 100644 --- a/services/clsi/app/js/OutputCacheManager.js +++ b/services/clsi/app/js/OutputCacheManager.js @@ -24,7 +24,11 @@ const Metrics = require('./Metrics') const OutputFileOptimiser = require('./OutputFileOptimiser') const ContentCacheManager = require('./ContentCacheManager') -const { QueueLimitReachedError, TimedOutError } = require('./Errors') +const { + QueueLimitReachedError, + TimedOutError, + NoXrefTableError, +} = require('./Errors') const OLDEST_BUILD_DIR = new Map() const PENDING_PROJECT_ACTIONS = new Map() @@ -397,6 +401,9 @@ module.exports = OutputCacheManager = { pdfSize, timings.compile, function (err, result) { + if (err && err instanceof NoXrefTableError) { + return callback(null, err.message) + } if (err && err instanceof QueueLimitReachedError) { logger.warn({ err, outputDir }, 'pdf caching queue limit reached') stats['pdf-caching-queue-limit-reached'] = 1 diff --git a/services/clsi/app/js/XrefParser.js b/services/clsi/app/js/XrefParser.js new file mode 100644 index 0000000000..db6abf8647 --- /dev/null +++ b/services/clsi/app/js/XrefParser.js @@ -0,0 +1,68 @@ +const { NoXrefTableError } = require('./Errors') +const fs = require('fs') +const { O_RDONLY, O_NOFOLLOW } = fs.constants +const MAX_XREF_FILE_SIZE = 1024 * 1024 + +/** Parse qpdf --show-xref output to get a table of xref entries + * + * @param {string} filePath + * @param {integer} pdfFileSize + * @returns + */ +async function parseXrefTable(filePath, pdfFileSize) { + try { + // the xref table will be written to output.pdfxref when available + const xRefFilePath = filePath + 'xref' + // check the size of the file (as it is untrusted) + const stats = await fs.promises.stat(xRefFilePath) + if (!stats.isFile()) { + throw new NoXrefTableError('xref file invalid type') + } + if (stats.size === 0) { + throw new NoXrefTableError('xref file empty') + } + if (stats.size > MAX_XREF_FILE_SIZE) { + throw new NoXrefTableError('xref file too large') + } + const content = await fs.promises.readFile(xRefFilePath, { + encoding: 'ascii', + flag: O_RDONLY | O_NOFOLLOW, + }) + // the qpdf xref table output looks like this: + // + // 3/0: uncompressed; offset = 194159 + // + // we only need the uncompressed objects + const matches = content.matchAll( + // put an upper limit of 10^10 on all the matched numbers for safety + // ignore the generation id in "id/gen" + // in a linearized pdf all objects must have generation number 0 + /^(\d{1,9})\/\d{1,9}: uncompressed; offset = (\d{1,9})$/gm + ) + // include a zero-index object for backwards compatibility with + // our existing xref table parsing code + const xRefEntries = [{ offset: 0 }] + // extract all the xref table entries + for (const match of matches) { + const id = parseInt(match[1], 10) // must convert from strings to integers + const offset = parseInt(match[2], 10) + xRefEntries[id] = { offset, uncompressed: true } + } + if (xRefEntries.length === 1) { + throw new NoXrefTableError('xref file has no objects') + } + return { xRefEntries } + } catch (err) { + if (err instanceof NoXrefTableError) { + throw err + } else if (err.code) { + throw new NoXrefTableError(`xref file error ${err.code}`) + } else { + throw new NoXrefTableError('xref file parse error') + } + } +} + +module.exports = { + parseXrefTable, +} diff --git a/services/clsi/app/lib/pdfjs/FSPdfManager.js b/services/clsi/app/lib/pdfjs/FSPdfManager.js deleted file mode 100644 index 692576b2ce..0000000000 --- a/services/clsi/app/lib/pdfjs/FSPdfManager.js +++ /dev/null @@ -1,43 +0,0 @@ -const { PDFDocument } = require('pdfjs-dist/lib/core/document') -const { LocalPdfManager } = require('pdfjs-dist/lib/core/pdf_manager') -const { MissingDataException } = require('pdfjs-dist/lib/core/core_utils') -const { FSStream } = require('./FSStream') - -class FSPdfManager extends LocalPdfManager { - constructor(docId, { fh, size, checkDeadline }) { - const nonEmptyDummyBuffer = Buffer.alloc(1, 0) - super(docId, nonEmptyDummyBuffer) - this.stream = new FSStream(fh, 0, size, null, null, checkDeadline) - this.pdfDocument = new PDFDocument(this, this.stream) - } - - async ensure(obj, prop, args) { - try { - const value = obj[prop] - if (typeof value === 'function') { - return value.apply(obj, args) - } - return value - } catch (ex) { - if (!(ex instanceof MissingDataException)) { - throw ex - } - await this.requestRange(ex.begin, ex.end) - return this.ensure(obj, prop, args) - } - } - - requestRange(begin, end) { - return this.stream.requestRange(begin, end) - } - - requestLoadedStream() {} - - onLoadedStream() {} - - terminate(reason) {} -} - -module.exports = { - FSPdfManager, -} diff --git a/services/clsi/app/lib/pdfjs/FSStream.js b/services/clsi/app/lib/pdfjs/FSStream.js deleted file mode 100644 index 188184a32c..0000000000 --- a/services/clsi/app/lib/pdfjs/FSStream.js +++ /dev/null @@ -1,148 +0,0 @@ -const { Stream } = require('pdfjs-dist/lib/core/stream') -const { MissingDataException } = require('pdfjs-dist/lib/core/core_utils') - -const BUF_SIZE = 1024 // read from the file in 1024 byte pages - -class FSStream extends Stream { - constructor(fh, start, length, dict, cachedBytes, checkDeadline) { - const nonEmptyDummyBuffer = Buffer.alloc(1, 0) - super(nonEmptyDummyBuffer, start, length, dict) - delete this.bytes - this.fh = fh - this.checkDeadline = checkDeadline - this.cachedBytes = cachedBytes || [] - } - - get length() { - return this.end - this.start - } - - get isEmpty() { - return this.length === 0 - } - - // Manage cached reads from the file - - requestRange(begin, end) { - this.checkDeadline(`request range ${begin} - ${end}`) - // expand small ranges to read a larger amount - if (end - begin < BUF_SIZE) { - end = begin + BUF_SIZE - } - end = Math.min(end, this.length) - // keep a cache of previous reads with {begin,end,buffer} values - const result = { - begin, - end, - buffer: Buffer.alloc(end - begin, 0), - } - this.cachedBytes.push(result) - return this.fh.read(result.buffer, 0, end - begin, begin) - } - - _ensureGetPos(pos) { - const found = this.cachedBytes.find(x => { - return x.begin <= pos && pos < x.end - }) - if (!found) { - throw new MissingDataException(pos, pos + 1) - } - return found - } - - _ensureGetRange(begin, end) { - end = Math.min(end, this.length) // BG: handle overflow case - const found = this.cachedBytes.find(x => { - return x.begin <= begin && end <= x.end - }) - if (!found) { - throw new MissingDataException(begin, end) - } - return found - } - - _readByte(found, pos) { - return found.buffer[pos - found.begin] - } - - _readBytes(found, pos, end) { - return found.buffer.subarray(pos - found.begin, end - found.begin) - } - - // handle accesses to the bytes - - ensureByte(pos) { - this._ensureGetPos(pos) // may throw a MissingDataException - } - - getByte() { - const pos = this.pos - if (this.pos >= this.end) { - return -1 - } - const found = this._ensureGetPos(pos) - return this._readByte(found, this.pos++) - } - - // BG: for a range, end is not included (see Buffer.subarray for example) - - ensureBytes(length, forceClamped = false) { - const pos = this.pos - this._ensureGetRange(pos, pos + length) - } - - getBytes(length, forceClamped = false) { - const pos = this.pos - const strEnd = this.end - - const found = this._ensureGetRange(pos, pos + length) - if (!length) { - const subarray = this._readBytes(found, pos, strEnd) - // `this.bytes` is always a `Uint8Array` here. - return forceClamped ? new Uint8ClampedArray(subarray) : subarray - } - let end = pos + length - if (end > strEnd) { - end = strEnd - } - this.pos = end - const subarray = this._readBytes(found, pos, end) - // `this.bytes` is always a `Uint8Array` here. - return forceClamped ? new Uint8ClampedArray(subarray) : subarray - } - - getByteRange() { - // BG: this isn't needed as far as I can tell - throw new Error('not implemented') - } - - reset() { - this.pos = this.start - } - - moveStart() { - this.start = this.pos - } - - makeSubStream(start, length, dict = null) { - this.checkDeadline(`make sub stream start=${start}/length=${length}`) - // BG: had to add this check for null length, it is being called with only - // the start value at one point in the xref decoding. The intent is clear - // enough - // - a null length means "to the end of the file" -- not sure how it is - // working in the existing pdfjs code without this. - if (!length) { - length = this.end - start - } - return new FSStream( - this.fh, - start, - length, - dict, - this.cachedBytes, - this.checkDeadline - ) - } -} - -module.exports = { FSStream } diff --git a/services/clsi/app/lib/pdfjs/parseXrefTable.js b/services/clsi/app/lib/pdfjs/parseXrefTable.js deleted file mode 100644 index f24788f63b..0000000000 --- a/services/clsi/app/lib/pdfjs/parseXrefTable.js +++ /dev/null @@ -1,29 +0,0 @@ -const fs = require('fs') -const { FSPdfManager } = require('./FSPdfManager') - -async function parseXrefTable(path, size, checkDeadline) { - if (size === 0) { - return [] - } - - const file = await fs.promises.open(path) - try { - const manager = new FSPdfManager(0, { fh: file, size, checkDeadline }) - - await manager.ensureDoc('checkHeader') - checkDeadline('pdfjs: after checkHeader') - await manager.ensureDoc('parseStartXRef') - checkDeadline('pdfjs: after parseStartXRef') - await manager.ensureDoc('parse') - checkDeadline('pdfjs: after parse') - const xRefEntries = manager.pdfDocument.xref.entries || [] - const startXRefTable = manager.pdfDocument.xref.topDict?.get('Prev') - return { xRefEntries, startXRefTable } - } finally { - file.close() - } -} - -module.exports = { - parseXrefTable, -} diff --git a/services/clsi/package.json b/services/clsi/package.json index df79ebd1da..204d26615b 100644 --- a/services/clsi/package.json +++ b/services/clsi/package.json @@ -30,7 +30,6 @@ "lockfile": "^1.0.4", "lodash": "^4.17.21", "p-limit": "^3.1.0", - "pdfjs-dist": "~2.7.570", "request": "^2.88.2", "send": "^0.17.1", "workerpool": "^6.1.5" diff --git a/services/clsi/test/acceptance/fixtures/examples/asymptote/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/asymptote/output.pdfxref new file mode 100644 index 0000000000..de34f567f0 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/asymptote/output.pdfxref @@ -0,0 +1,81 @@ +1/0: uncompressed; offset = 123103 +2/0: uncompressed; offset = 123422 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 1084 +6/0: uncompressed; offset = 1244 +7/0: uncompressed; offset = 4001 +8/0: uncompressed; offset = 4155 +9/0: uncompressed; offset = 4297 +10/0: uncompressed; offset = 4933 +11/0: uncompressed; offset = 5309 +12/0: uncompressed; offset = 5498 +13/0: uncompressed; offset = 30250 +14/0: uncompressed; offset = 31471 +15/0: uncompressed; offset = 38404 +16/0: uncompressed; offset = 39046 +17/0: uncompressed; offset = 40166 +18/0: uncompressed; offset = 40906 +19/0: uncompressed; offset = 65560 +20/0: uncompressed; offset = 74702 +21/0: uncompressed; offset = 81705 +22/0: uncompressed; offset = 97182 +23/0: uncompressed; offset = 104117 +24/0: uncompressed; offset = 111195 +25/0: uncompressed; offset = 118571 +26/0: compressed; stream = 6, index = 0 +27/0: compressed; stream = 6, index = 1 +28/0: compressed; stream = 6, index = 2 +29/0: compressed; stream = 6, index = 3 +30/0: compressed; stream = 6, index = 4 +31/0: compressed; stream = 6, index = 5 +32/0: compressed; stream = 6, index = 6 +33/0: compressed; stream = 6, index = 7 +34/0: compressed; stream = 6, index = 8 +35/0: compressed; stream = 6, index = 9 +36/0: compressed; stream = 6, index = 10 +37/0: compressed; stream = 6, index = 11 +38/0: compressed; stream = 6, index = 12 +39/0: compressed; stream = 6, index = 13 +40/0: compressed; stream = 6, index = 14 +41/0: compressed; stream = 6, index = 15 +42/0: compressed; stream = 6, index = 16 +43/0: compressed; stream = 6, index = 17 +44/0: compressed; stream = 6, index = 18 +45/0: compressed; stream = 6, index = 19 +46/0: compressed; stream = 6, index = 20 +47/0: compressed; stream = 6, index = 21 +48/0: compressed; stream = 6, index = 22 +49/0: compressed; stream = 6, index = 23 +50/0: compressed; stream = 6, index = 24 +51/0: compressed; stream = 6, index = 25 +52/0: compressed; stream = 6, index = 26 +53/0: compressed; stream = 6, index = 27 +54/0: compressed; stream = 6, index = 28 +55/0: compressed; stream = 6, index = 29 +56/0: compressed; stream = 6, index = 30 +57/0: compressed; stream = 6, index = 31 +58/0: compressed; stream = 6, index = 32 +59/0: compressed; stream = 6, index = 33 +60/0: compressed; stream = 6, index = 34 +61/0: compressed; stream = 6, index = 35 +62/0: compressed; stream = 6, index = 36 +63/0: compressed; stream = 6, index = 37 +64/0: compressed; stream = 6, index = 38 +65/0: compressed; stream = 6, index = 39 +66/0: compressed; stream = 6, index = 40 +67/0: compressed; stream = 6, index = 41 +68/0: compressed; stream = 6, index = 42 +69/0: compressed; stream = 6, index = 43 +70/0: compressed; stream = 6, index = 44 +71/0: compressed; stream = 6, index = 45 +72/0: compressed; stream = 6, index = 46 +73/0: compressed; stream = 6, index = 47 +74/0: compressed; stream = 6, index = 48 +75/0: compressed; stream = 6, index = 49 +76/0: compressed; stream = 6, index = 50 +77/0: compressed; stream = 6, index = 51 +78/0: compressed; stream = 6, index = 52 +79/0: compressed; stream = 6, index = 53 +80/0: compressed; stream = 6, index = 54 +81/0: compressed; stream = 6, index = 55 diff --git a/services/clsi/test/acceptance/fixtures/examples/biber_bibliography/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/biber_bibliography/output.pdfxref new file mode 100644 index 0000000000..1f1ac2b394 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/biber_bibliography/output.pdfxref @@ -0,0 +1,31 @@ +1/0: uncompressed; offset = 59313 +2/0: uncompressed; offset = 59561 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 734 +6/0: uncompressed; offset = 784 +7/0: uncompressed; offset = 913 +8/0: uncompressed; offset = 1028 +9/0: uncompressed; offset = 1528 +10/0: uncompressed; offset = 9787 +11/0: uncompressed; offset = 18282 +12/0: uncompressed; offset = 33607 +13/0: uncompressed; offset = 45579 +14/0: uncompressed; offset = 58005 +15/0: compressed; stream = 14, index = 0 +16/0: compressed; stream = 14, index = 1 +17/0: compressed; stream = 14, index = 2 +18/0: compressed; stream = 14, index = 3 +19/0: compressed; stream = 14, index = 4 +20/0: compressed; stream = 14, index = 5 +21/0: compressed; stream = 14, index = 6 +22/0: compressed; stream = 14, index = 7 +23/0: compressed; stream = 14, index = 8 +24/0: compressed; stream = 14, index = 9 +25/0: compressed; stream = 14, index = 10 +26/0: compressed; stream = 14, index = 11 +27/0: compressed; stream = 14, index = 12 +28/0: compressed; stream = 14, index = 13 +29/0: compressed; stream = 14, index = 14 +30/0: compressed; stream = 14, index = 15 +31/0: compressed; stream = 14, index = 16 diff --git a/services/clsi/test/acceptance/fixtures/examples/draft_legacy/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/draft_legacy/output.pdfxref new file mode 100644 index 0000000000..eab8b421f9 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/draft_legacy/output.pdfxref @@ -0,0 +1,39 @@ +1/0: uncompressed; offset = 67338 +2/0: uncompressed; offset = 67606 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 790 +6/0: uncompressed; offset = 840 +7/0: uncompressed; offset = 975 +8/0: uncompressed; offset = 1083 +9/0: uncompressed; offset = 1578 +10/0: uncompressed; offset = 9881 +11/0: uncompressed; offset = 17868 +12/0: uncompressed; offset = 29906 +13/0: uncompressed; offset = 38400 +14/0: uncompressed; offset = 46656 +15/0: uncompressed; offset = 56198 +16/0: uncompressed; offset = 65682 +17/0: compressed; stream = 16, index = 0 +18/0: compressed; stream = 16, index = 1 +19/0: compressed; stream = 16, index = 2 +20/0: compressed; stream = 16, index = 3 +21/0: compressed; stream = 16, index = 4 +22/0: compressed; stream = 16, index = 5 +23/0: compressed; stream = 16, index = 6 +24/0: compressed; stream = 16, index = 7 +25/0: compressed; stream = 16, index = 8 +26/0: compressed; stream = 16, index = 9 +27/0: compressed; stream = 16, index = 10 +28/0: compressed; stream = 16, index = 11 +29/0: compressed; stream = 16, index = 12 +30/0: compressed; stream = 16, index = 13 +31/0: compressed; stream = 16, index = 14 +32/0: compressed; stream = 16, index = 15 +33/0: compressed; stream = 16, index = 16 +34/0: compressed; stream = 16, index = 17 +35/0: compressed; stream = 16, index = 18 +36/0: compressed; stream = 16, index = 19 +37/0: compressed; stream = 16, index = 20 +38/0: compressed; stream = 16, index = 21 +39/0: compressed; stream = 16, index = 22 diff --git a/services/clsi/test/acceptance/fixtures/examples/draft_mode/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/draft_mode/output.pdfxref new file mode 100644 index 0000000000..aa568c0b72 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/draft_mode/output.pdfxref @@ -0,0 +1,50 @@ +1/0: uncompressed; offset = 69708 +2/0: uncompressed; offset = 70038 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 867 +6/0: uncompressed; offset = 990 +7/0: uncompressed; offset = 1143 +8/0: uncompressed; offset = 1251 +9/0: uncompressed; offset = 1834 +10/0: uncompressed; offset = 10137 +11/0: uncompressed; offset = 18124 +12/0: uncompressed; offset = 31939 +13/0: uncompressed; offset = 40433 +14/0: uncompressed; offset = 48689 +15/0: uncompressed; offset = 58231 +16/0: uncompressed; offset = 67715 +17/0: compressed; stream = 16, index = 0 +18/0: compressed; stream = 16, index = 1 +19/0: compressed; stream = 16, index = 2 +20/0: compressed; stream = 16, index = 3 +21/0: compressed; stream = 16, index = 4 +22/0: compressed; stream = 16, index = 5 +23/0: compressed; stream = 16, index = 6 +24/0: compressed; stream = 16, index = 7 +25/0: compressed; stream = 16, index = 8 +26/0: compressed; stream = 16, index = 9 +27/0: compressed; stream = 16, index = 10 +28/0: compressed; stream = 16, index = 11 +29/0: compressed; stream = 16, index = 12 +30/0: compressed; stream = 16, index = 13 +31/0: compressed; stream = 16, index = 14 +32/0: compressed; stream = 16, index = 15 +33/0: compressed; stream = 16, index = 16 +34/0: compressed; stream = 16, index = 17 +35/0: compressed; stream = 16, index = 18 +36/0: compressed; stream = 16, index = 19 +37/0: compressed; stream = 16, index = 20 +38/0: compressed; stream = 16, index = 21 +39/0: compressed; stream = 16, index = 22 +40/0: compressed; stream = 16, index = 23 +41/0: compressed; stream = 16, index = 24 +42/0: compressed; stream = 16, index = 25 +43/0: compressed; stream = 16, index = 26 +44/0: compressed; stream = 16, index = 27 +45/0: compressed; stream = 16, index = 28 +46/0: compressed; stream = 16, index = 29 +47/0: compressed; stream = 16, index = 30 +48/0: compressed; stream = 16, index = 31 +49/0: compressed; stream = 16, index = 32 +50/0: compressed; stream = 16, index = 33 diff --git a/services/clsi/test/acceptance/fixtures/examples/epstopdf/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/epstopdf/output.pdfxref new file mode 100644 index 0000000000..f6f11e177f --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/epstopdf/output.pdfxref @@ -0,0 +1,30 @@ +1/0: uncompressed; offset = 31354 +2/0: uncompressed; offset = 31614 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 727 +6/0: uncompressed; offset = 777 +7/0: uncompressed; offset = 909 +8/0: uncompressed; offset = 1017 +9/0: uncompressed; offset = 19127 +10/0: uncompressed; offset = 19313 +11/0: uncompressed; offset = 19557 +12/0: uncompressed; offset = 19948 +13/0: uncompressed; offset = 20677 +14/0: uncompressed; offset = 23321 +15/0: uncompressed; offset = 30318 +16/0: compressed; stream = 15, index = 0 +17/0: compressed; stream = 15, index = 1 +18/0: compressed; stream = 15, index = 2 +19/0: compressed; stream = 15, index = 3 +20/0: compressed; stream = 15, index = 4 +21/0: compressed; stream = 15, index = 5 +22/0: compressed; stream = 15, index = 6 +23/0: compressed; stream = 15, index = 7 +24/0: compressed; stream = 15, index = 8 +25/0: compressed; stream = 15, index = 9 +26/0: compressed; stream = 15, index = 10 +27/0: compressed; stream = 15, index = 11 +28/0: compressed; stream = 15, index = 12 +29/0: compressed; stream = 15, index = 13 +30/0: compressed; stream = 15, index = 14 diff --git a/services/clsi/test/acceptance/fixtures/examples/feynmf/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/feynmf/output.pdfxref new file mode 100644 index 0000000000..2aa923d726 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/feynmf/output.pdfxref @@ -0,0 +1,28 @@ +1/0: uncompressed; offset = 27064 +2/0: uncompressed; offset = 27312 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 713 +6/0: uncompressed; offset = 763 +7/0: uncompressed; offset = 892 +8/0: uncompressed; offset = 1007 +9/0: uncompressed; offset = 1235 +10/0: uncompressed; offset = 4832 +11/0: uncompressed; offset = 12199 +12/0: uncompressed; offset = 19196 +13/0: uncompressed; offset = 26341 +14/0: compressed; stream = 13, index = 0 +15/0: compressed; stream = 13, index = 1 +16/0: compressed; stream = 13, index = 2 +17/0: compressed; stream = 13, index = 3 +18/0: compressed; stream = 13, index = 4 +19/0: compressed; stream = 13, index = 5 +20/0: compressed; stream = 13, index = 6 +21/0: compressed; stream = 13, index = 7 +22/0: compressed; stream = 13, index = 8 +23/0: compressed; stream = 13, index = 9 +24/0: compressed; stream = 13, index = 10 +25/0: compressed; stream = 13, index = 11 +26/0: compressed; stream = 13, index = 12 +27/0: compressed; stream = 13, index = 13 +28/0: compressed; stream = 13, index = 14 diff --git a/services/clsi/test/acceptance/fixtures/examples/feynmp/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/feynmp/output.pdfxref new file mode 100644 index 0000000000..c4ef6250b5 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/feynmp/output.pdfxref @@ -0,0 +1,20 @@ +1/0: uncompressed; offset = 4964 +2/0: uncompressed; offset = 5023 +3/0: uncompressed; offset = 5234 +4/0: uncompressed; offset = 15 +5/0: uncompressed; offset = 734 +6/0: uncompressed; offset = 799 +7/0: uncompressed; offset = 933 +8/0: uncompressed; offset = 1104 +9/0: uncompressed; offset = 1947 +10/0: uncompressed; offset = 1992 +11/0: uncompressed; offset = 2182 +12/0: uncompressed; offset = 2427 +13/0: uncompressed; offset = 2597 +14/0: uncompressed; offset = 2822 +15/0: uncompressed; offset = 2989 +16/0: uncompressed; offset = 3239 +17/0: uncompressed; offset = 3271 +18/0: uncompressed; offset = 3328 +19/0: uncompressed; offset = 3740 +20/0: uncompressed; offset = 4270 diff --git a/services/clsi/test/acceptance/fixtures/examples/fontawesome/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/fontawesome/output.pdfxref new file mode 100644 index 0000000000..96eb1a01f3 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/fontawesome/output.pdfxref @@ -0,0 +1,23 @@ +1/0: uncompressed; offset = 31058 +2/0: uncompressed; offset = 31307 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 678 +6/0: uncompressed; offset = 728 +7/0: uncompressed; offset = 855 +8/0: uncompressed; offset = 970 +9/0: uncompressed; offset = 1203 +10/0: uncompressed; offset = 18852 +11/0: uncompressed; offset = 30165 +12/0: compressed; stream = 11, index = 0 +13/0: compressed; stream = 11, index = 1 +14/0: compressed; stream = 11, index = 2 +15/0: compressed; stream = 11, index = 3 +16/0: compressed; stream = 11, index = 4 +17/0: compressed; stream = 11, index = 5 +18/0: compressed; stream = 11, index = 6 +19/0: compressed; stream = 11, index = 7 +20/0: compressed; stream = 11, index = 8 +21/0: compressed; stream = 11, index = 9 +22/0: compressed; stream = 11, index = 10 +23/0: compressed; stream = 11, index = 11 diff --git a/services/clsi/test/acceptance/fixtures/examples/fontawesome_xelatex/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/fontawesome_xelatex/output.pdfxref new file mode 100644 index 0000000000..d5c979d08a --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/fontawesome_xelatex/output.pdfxref @@ -0,0 +1,26 @@ +1/0: uncompressed; offset = 6344 +2/0: uncompressed; offset = 15 +3/0: uncompressed; offset = 216 +4/0: uncompressed; offset = 707 +5/0: uncompressed; offset = 757 +6/0: uncompressed; offset = 887 +7/0: uncompressed; offset = 990 +8/0: uncompressed; offset = 1257 +9/0: uncompressed; offset = 1679 +10/0: uncompressed; offset = 2052 +11/0: uncompressed; offset = 4249 +12/0: uncompressed; offset = 4343 +13/0: uncompressed; offset = 5387 +14/0: uncompressed; offset = 5481 +15/0: uncompressed; offset = 5519 +16/0: compressed; stream = 15, index = 0 +17/0: compressed; stream = 15, index = 1 +18/0: compressed; stream = 15, index = 2 +19/0: compressed; stream = 15, index = 3 +20/0: compressed; stream = 15, index = 4 +21/0: compressed; stream = 15, index = 5 +22/0: compressed; stream = 15, index = 6 +23/0: compressed; stream = 15, index = 7 +24/0: compressed; stream = 15, index = 8 +25/0: compressed; stream = 15, index = 9 +26/0: compressed; stream = 15, index = 10 diff --git a/services/clsi/test/acceptance/fixtures/examples/glossaries/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/glossaries/output.pdfxref new file mode 100644 index 0000000000..cbbbeb03fa --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/glossaries/output.pdfxref @@ -0,0 +1,23 @@ +1/0: uncompressed; offset = 34767 +2/0: uncompressed; offset = 35015 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 678 +6/0: uncompressed; offset = 728 +7/0: uncompressed; offset = 856 +8/0: uncompressed; offset = 971 +9/0: uncompressed; offset = 1394 +10/0: uncompressed; offset = 10990 +11/0: uncompressed; offset = 19087 +12/0: uncompressed; offset = 33769 +13/0: compressed; stream = 12, index = 0 +14/0: compressed; stream = 12, index = 1 +15/0: compressed; stream = 12, index = 2 +16/0: compressed; stream = 12, index = 3 +17/0: compressed; stream = 12, index = 4 +18/0: compressed; stream = 12, index = 5 +19/0: compressed; stream = 12, index = 6 +20/0: compressed; stream = 12, index = 7 +21/0: compressed; stream = 12, index = 8 +22/0: compressed; stream = 12, index = 9 +23/0: compressed; stream = 12, index = 10 diff --git a/services/clsi/test/acceptance/fixtures/examples/gnuplot/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/gnuplot/output.pdfxref new file mode 100644 index 0000000000..f9dee6b905 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/gnuplot/output.pdfxref @@ -0,0 +1,22 @@ +1/0: uncompressed; offset = 23295 +2/0: uncompressed; offset = 23543 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 671 +6/0: uncompressed; offset = 721 +7/0: uncompressed; offset = 847 +8/0: uncompressed; offset = 955 +9/0: uncompressed; offset = 7385 +10/0: uncompressed; offset = 15752 +11/0: uncompressed; offset = 22721 +12/0: compressed; stream = 11, index = 0 +13/0: compressed; stream = 11, index = 1 +14/0: compressed; stream = 11, index = 2 +15/0: compressed; stream = 11, index = 3 +16/0: compressed; stream = 11, index = 4 +17/0: compressed; stream = 11, index = 5 +18/0: compressed; stream = 11, index = 6 +19/0: compressed; stream = 11, index = 7 +20/0: compressed; stream = 11, index = 8 +21/0: compressed; stream = 11, index = 9 +22/0: compressed; stream = 11, index = 10 diff --git a/services/clsi/test/acceptance/fixtures/examples/hebrew/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/hebrew/output.pdfxref new file mode 100644 index 0000000000..4750e43b04 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/hebrew/output.pdfxref @@ -0,0 +1,20 @@ +1/0: uncompressed; offset = 24490 +2/0: uncompressed; offset = 24739 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 657 +6/0: uncompressed; offset = 707 +7/0: uncompressed; offset = 833 +8/0: uncompressed; offset = 948 +9/0: uncompressed; offset = 1290 +10/0: uncompressed; offset = 13083 +11/0: uncompressed; offset = 23411 +12/0: compressed; stream = 11, index = 0 +13/0: compressed; stream = 11, index = 1 +14/0: compressed; stream = 11, index = 2 +15/0: compressed; stream = 11, index = 3 +16/0: compressed; stream = 11, index = 4 +17/0: compressed; stream = 11, index = 5 +18/0: compressed; stream = 11, index = 6 +19/0: compressed; stream = 11, index = 7 +20/0: compressed; stream = 11, index = 8 diff --git a/services/clsi/test/acceptance/fixtures/examples/knitr/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/knitr/output.pdfxref new file mode 100644 index 0000000000..3fe1986864 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/knitr/output.pdfxref @@ -0,0 +1,31 @@ +1/0: uncompressed; offset = 43550 +2/0: uncompressed; offset = 43799 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 734 +6/0: uncompressed; offset = 784 +7/0: uncompressed; offset = 913 +8/0: uncompressed; offset = 1021 +9/0: uncompressed; offset = 1546 +10/0: uncompressed; offset = 5794 +11/0: uncompressed; offset = 12915 +12/0: uncompressed; offset = 23660 +13/0: uncompressed; offset = 30657 +14/0: uncompressed; offset = 42604 +15/0: compressed; stream = 14, index = 0 +16/0: compressed; stream = 14, index = 1 +17/0: compressed; stream = 14, index = 2 +18/0: compressed; stream = 14, index = 3 +19/0: compressed; stream = 14, index = 4 +20/0: compressed; stream = 14, index = 5 +21/0: compressed; stream = 14, index = 6 +22/0: compressed; stream = 14, index = 7 +23/0: compressed; stream = 14, index = 8 +24/0: compressed; stream = 14, index = 9 +25/0: compressed; stream = 14, index = 10 +26/0: compressed; stream = 14, index = 11 +27/0: compressed; stream = 14, index = 12 +28/0: compressed; stream = 14, index = 13 +29/0: compressed; stream = 14, index = 14 +30/0: compressed; stream = 14, index = 15 +31/0: compressed; stream = 14, index = 16 diff --git a/services/clsi/test/acceptance/fixtures/examples/knitr_utf8/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/knitr_utf8/output.pdfxref new file mode 100644 index 0000000000..30918b7c8f --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/knitr_utf8/output.pdfxref @@ -0,0 +1,39 @@ +1/0: uncompressed; offset = 75299 +2/0: uncompressed; offset = 75548 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 790 +6/0: uncompressed; offset = 840 +7/0: uncompressed; offset = 975 +8/0: uncompressed; offset = 1083 +9/0: uncompressed; offset = 2128 +10/0: uncompressed; offset = 13799 +11/0: uncompressed; offset = 23682 +12/0: uncompressed; offset = 31867 +13/0: uncompressed; offset = 36116 +14/0: uncompressed; offset = 50352 +15/0: uncompressed; offset = 61569 +16/0: uncompressed; offset = 73516 +17/0: compressed; stream = 16, index = 0 +18/0: compressed; stream = 16, index = 1 +19/0: compressed; stream = 16, index = 2 +20/0: compressed; stream = 16, index = 3 +21/0: compressed; stream = 16, index = 4 +22/0: compressed; stream = 16, index = 5 +23/0: compressed; stream = 16, index = 6 +24/0: compressed; stream = 16, index = 7 +25/0: compressed; stream = 16, index = 8 +26/0: compressed; stream = 16, index = 9 +27/0: compressed; stream = 16, index = 10 +28/0: compressed; stream = 16, index = 11 +29/0: compressed; stream = 16, index = 12 +30/0: compressed; stream = 16, index = 13 +31/0: compressed; stream = 16, index = 14 +32/0: compressed; stream = 16, index = 15 +33/0: compressed; stream = 16, index = 16 +34/0: compressed; stream = 16, index = 17 +35/0: compressed; stream = 16, index = 18 +36/0: compressed; stream = 16, index = 19 +37/0: compressed; stream = 16, index = 20 +38/0: compressed; stream = 16, index = 21 +39/0: compressed; stream = 16, index = 22 diff --git a/services/clsi/test/acceptance/fixtures/examples/latex_compiler/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/latex_compiler/output.pdfxref new file mode 100644 index 0000000000..8221852310 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/latex_compiler/output.pdfxref @@ -0,0 +1,26 @@ +1/0: uncompressed; offset = 25097 +2/0: uncompressed; offset = 25156 +3/0: uncompressed; offset = 25367 +4/0: uncompressed; offset = 15 +5/0: uncompressed; offset = 854 +6/0: uncompressed; offset = 919 +7/0: uncompressed; offset = 1074 +8/0: uncompressed; offset = 1245 +9/0: uncompressed; offset = 18343 +10/0: uncompressed; offset = 18388 +11/0: uncompressed; offset = 18752 +12/0: uncompressed; offset = 19071 +13/0: uncompressed; offset = 19360 +14/0: uncompressed; offset = 19604 +15/0: uncompressed; offset = 19770 +16/0: uncompressed; offset = 20007 +17/0: uncompressed; offset = 20174 +18/0: uncompressed; offset = 20424 +19/0: uncompressed; offset = 20456 +20/0: uncompressed; offset = 20525 +21/0: uncompressed; offset = 23109 +22/0: uncompressed; offset = 23500 +23/0: uncompressed; offset = 24229 +24/0: uncompressed; offset = 24641 +25/0: uncompressed; offset = 24741 +26/0: uncompressed; offset = 24985 diff --git a/services/clsi/test/acceptance/fixtures/examples/lualatex_compiler/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/lualatex_compiler/output.pdfxref new file mode 100644 index 0000000000..6e59a2d0a3 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/lualatex_compiler/output.pdfxref @@ -0,0 +1,18 @@ +1/0: uncompressed; offset = 3568 +2/0: uncompressed; offset = 3777 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 643 +6/0: uncompressed; offset = 693 +7/0: uncompressed; offset = 819 +8/0: uncompressed; offset = 934 +9/0: uncompressed; offset = 1118 +10/0: uncompressed; offset = 1210 +11/0: uncompressed; offset = 2555 +12/0: uncompressed; offset = 3030 +13/0: compressed; stream = 12, index = 0 +14/0: compressed; stream = 12, index = 1 +15/0: compressed; stream = 12, index = 2 +16/0: compressed; stream = 12, index = 3 +17/0: compressed; stream = 12, index = 4 +18/0: compressed; stream = 12, index = 5 diff --git a/services/clsi/test/acceptance/fixtures/examples/makeindex-custom-style/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/makeindex-custom-style/output.pdfxref new file mode 100644 index 0000000000..6557c98e3c --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/makeindex-custom-style/output.pdfxref @@ -0,0 +1,26 @@ +1/0: uncompressed; offset = 16762 +2/0: uncompressed; offset = 16877 +3/0: uncompressed; offset = 17142 +4/0: uncompressed; offset = 24335 +5/0: uncompressed; offset = 32164 +6/0: uncompressed; offset = 32412 +7/0: uncompressed; offset = 15 +8/0: uncompressed; offset = 216 +9/0: uncompressed; offset = 671 +10/0: uncompressed; offset = 721 +11/0: uncompressed; offset = 856 +12/0: uncompressed; offset = 973 +13/0: uncompressed; offset = 1318 +14/0: uncompressed; offset = 2218 +15/0: compressed; stream = 13, index = 0 +16/0: compressed; stream = 13, index = 1 +17/0: compressed; stream = 13, index = 2 +18/0: compressed; stream = 13, index = 3 +19/0: compressed; stream = 13, index = 4 +20/0: compressed; stream = 13, index = 5 +21/0: compressed; stream = 13, index = 6 +22/0: compressed; stream = 13, index = 7 +23/0: compressed; stream = 13, index = 8 +24/0: compressed; stream = 13, index = 9 +25/0: compressed; stream = 13, index = 10 +26/0: compressed; stream = 13, index = 11 diff --git a/services/clsi/test/acceptance/fixtures/examples/makeindex/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/makeindex/output.pdfxref new file mode 100644 index 0000000000..7188737097 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/makeindex/output.pdfxref @@ -0,0 +1,22 @@ +1/0: uncompressed; offset = 16778 +2/0: uncompressed; offset = 16893 +3/0: uncompressed; offset = 17109 +4/0: uncompressed; offset = 24938 +5/0: uncompressed; offset = 25186 +6/0: uncompressed; offset = 15 +7/0: uncompressed; offset = 216 +8/0: uncompressed; offset = 650 +9/0: uncompressed; offset = 700 +10/0: uncompressed; offset = 836 +11/0: uncompressed; offset = 953 +12/0: uncompressed; offset = 1298 +13/0: uncompressed; offset = 2103 +14/0: compressed; stream = 12, index = 0 +15/0: compressed; stream = 12, index = 1 +16/0: compressed; stream = 12, index = 2 +17/0: compressed; stream = 12, index = 3 +18/0: compressed; stream = 12, index = 4 +19/0: compressed; stream = 12, index = 5 +20/0: compressed; stream = 12, index = 6 +21/0: compressed; stream = 12, index = 7 +22/0: compressed; stream = 12, index = 8 diff --git a/services/clsi/test/acceptance/fixtures/examples/minted/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/minted/output.pdfxref new file mode 100644 index 0000000000..611764845d --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/minted/output.pdfxref @@ -0,0 +1,19 @@ +1/0: uncompressed; offset = 20679 +2/0: uncompressed; offset = 20927 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 650 +6/0: uncompressed; offset = 700 +7/0: uncompressed; offset = 826 +8/0: uncompressed; offset = 934 +9/0: uncompressed; offset = 1252 +10/0: uncompressed; offset = 8248 +11/0: uncompressed; offset = 20115 +12/0: compressed; stream = 11, index = 0 +13/0: compressed; stream = 11, index = 1 +14/0: compressed; stream = 11, index = 2 +15/0: compressed; stream = 11, index = 3 +16/0: compressed; stream = 11, index = 4 +17/0: compressed; stream = 11, index = 5 +18/0: compressed; stream = 11, index = 6 +19/0: compressed; stream = 11, index = 7 diff --git a/services/clsi/test/acceptance/fixtures/examples/multibib_bibliography/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/multibib_bibliography/output.pdfxref new file mode 100644 index 0000000000..2ceaa2b310 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/multibib_bibliography/output.pdfxref @@ -0,0 +1,32 @@ +1/0: uncompressed; offset = 29506 +2/0: uncompressed; offset = 29621 +3/0: uncompressed; offset = 29918 +4/0: uncompressed; offset = 30033 +5/0: uncompressed; offset = 30274 +6/0: uncompressed; offset = 30389 +7/0: uncompressed; offset = 30644 +8/0: uncompressed; offset = 42802 +9/0: uncompressed; offset = 43050 +10/0: uncompressed; offset = 15 +11/0: uncompressed; offset = 216 +12/0: uncompressed; offset = 695 +13/0: uncompressed; offset = 746 +14/0: uncompressed; offset = 900 +15/0: uncompressed; offset = 1017 +16/0: uncompressed; offset = 1286 +17/0: uncompressed; offset = 2443 +18/0: uncompressed; offset = 13147 +19/0: compressed; stream = 16, index = 0 +20/0: compressed; stream = 16, index = 1 +21/0: compressed; stream = 16, index = 2 +22/0: compressed; stream = 16, index = 3 +23/0: compressed; stream = 16, index = 4 +24/0: compressed; stream = 16, index = 5 +25/0: compressed; stream = 16, index = 6 +26/0: compressed; stream = 16, index = 7 +27/0: compressed; stream = 16, index = 8 +28/0: compressed; stream = 16, index = 9 +29/0: compressed; stream = 16, index = 10 +30/0: compressed; stream = 16, index = 11 +31/0: compressed; stream = 16, index = 12 +32/0: compressed; stream = 16, index = 13 diff --git a/services/clsi/test/acceptance/fixtures/examples/nomenclature/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/nomenclature/output.pdfxref new file mode 100644 index 0000000000..cc3f61c137 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/nomenclature/output.pdfxref @@ -0,0 +1,23 @@ +1/0: uncompressed; offset = 34102 +2/0: uncompressed; offset = 34350 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 678 +6/0: uncompressed; offset = 728 +7/0: uncompressed; offset = 856 +8/0: uncompressed; offset = 971 +9/0: uncompressed; offset = 1514 +10/0: uncompressed; offset = 10973 +11/0: uncompressed; offset = 19139 +12/0: uncompressed; offset = 33047 +13/0: compressed; stream = 12, index = 0 +14/0: compressed; stream = 12, index = 1 +15/0: compressed; stream = 12, index = 2 +16/0: compressed; stream = 12, index = 3 +17/0: compressed; stream = 12, index = 4 +18/0: compressed; stream = 12, index = 5 +19/0: compressed; stream = 12, index = 6 +20/0: compressed; stream = 12, index = 7 +21/0: compressed; stream = 12, index = 8 +22/0: compressed; stream = 12, index = 9 +23/0: compressed; stream = 12, index = 10 diff --git a/services/clsi/test/acceptance/fixtures/examples/references_in_include/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/references_in_include/output.pdfxref new file mode 100644 index 0000000000..744030a1ce --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/references_in_include/output.pdfxref @@ -0,0 +1,22 @@ +1/0: uncompressed; offset = 9449 +2/0: uncompressed; offset = 9564 +3/0: uncompressed; offset = 9730 +4/0: uncompressed; offset = 17293 +5/0: uncompressed; offset = 17541 +6/0: uncompressed; offset = 15 +7/0: uncompressed; offset = 216 +8/0: uncompressed; offset = 650 +9/0: uncompressed; offset = 700 +10/0: uncompressed; offset = 835 +11/0: uncompressed; offset = 952 +12/0: uncompressed; offset = 1097 +13/0: uncompressed; offset = 1758 +14/0: compressed; stream = 12, index = 0 +15/0: compressed; stream = 12, index = 1 +16/0: compressed; stream = 12, index = 2 +17/0: compressed; stream = 12, index = 3 +18/0: compressed; stream = 12, index = 4 +19/0: compressed; stream = 12, index = 5 +20/0: compressed; stream = 12, index = 6 +21/0: compressed; stream = 12, index = 7 +22/0: compressed; stream = 12, index = 8 diff --git a/services/clsi/test/acceptance/fixtures/examples/simple_bibliography/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/simple_bibliography/output.pdfxref new file mode 100644 index 0000000000..6633bfbd6b --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/simple_bibliography/output.pdfxref @@ -0,0 +1,23 @@ +1/0: uncompressed; offset = 37282 +2/0: uncompressed; offset = 37530 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 678 +6/0: uncompressed; offset = 728 +7/0: uncompressed; offset = 856 +8/0: uncompressed; offset = 971 +9/0: uncompressed; offset = 1322 +10/0: uncompressed; offset = 9581 +11/0: uncompressed; offset = 24286 +12/0: uncompressed; offset = 36258 +13/0: compressed; stream = 12, index = 0 +14/0: compressed; stream = 12, index = 1 +15/0: compressed; stream = 12, index = 2 +16/0: compressed; stream = 12, index = 3 +17/0: compressed; stream = 12, index = 4 +18/0: compressed; stream = 12, index = 5 +19/0: compressed; stream = 12, index = 6 +20/0: compressed; stream = 12, index = 7 +21/0: compressed; stream = 12, index = 8 +22/0: compressed; stream = 12, index = 9 +23/0: compressed; stream = 12, index = 10 diff --git a/services/clsi/test/acceptance/fixtures/examples/subdirectories/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/subdirectories/output.pdfxref new file mode 100644 index 0000000000..60f75102c8 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/subdirectories/output.pdfxref @@ -0,0 +1,26 @@ +1/0: uncompressed; offset = 48194 +2/0: uncompressed; offset = 48442 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 699 +6/0: uncompressed; offset = 749 +7/0: uncompressed; offset = 878 +8/0: uncompressed; offset = 1000 +9/0: uncompressed; offset = 8546 +10/0: uncompressed; offset = 9072 +11/0: uncompressed; offset = 10659 +12/0: uncompressed; offset = 18919 +13/0: uncompressed; offset = 35129 +14/0: uncompressed; offset = 47101 +15/0: compressed; stream = 14, index = 0 +16/0: compressed; stream = 14, index = 1 +17/0: compressed; stream = 14, index = 2 +18/0: compressed; stream = 14, index = 3 +19/0: compressed; stream = 14, index = 4 +20/0: compressed; stream = 14, index = 5 +21/0: compressed; stream = 14, index = 6 +22/0: compressed; stream = 14, index = 7 +23/0: compressed; stream = 14, index = 8 +24/0: compressed; stream = 14, index = 9 +25/0: compressed; stream = 14, index = 10 +26/0: compressed; stream = 14, index = 11 diff --git a/services/clsi/test/acceptance/fixtures/examples/tikz_feynman/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/tikz_feynman/output.pdfxref new file mode 100644 index 0000000000..64f5dc249c --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/tikz_feynman/output.pdfxref @@ -0,0 +1,35 @@ +1/0: uncompressed; offset = 2924 +2/0: uncompressed; offset = 3039 +3/0: uncompressed; offset = 4606 +4/0: uncompressed; offset = 4721 +5/0: uncompressed; offset = 7754 +6/0: uncompressed; offset = 7870 +7/0: uncompressed; offset = 11668 +8/0: uncompressed; offset = 21077 +9/0: uncompressed; offset = 28498 +10/0: uncompressed; offset = 35464 +11/0: uncompressed; offset = 35699 +12/0: uncompressed; offset = 15 +13/0: uncompressed; offset = 216 +14/0: uncompressed; offset = 703 +15/0: uncompressed; offset = 754 +16/0: uncompressed; offset = 909 +17/0: uncompressed; offset = 1026 +18/0: uncompressed; offset = 2161 +19/0: compressed; stream = 18, index = 0 +20/0: compressed; stream = 18, index = 1 +21/0: compressed; stream = 18, index = 2 +22/0: compressed; stream = 18, index = 3 +23/0: compressed; stream = 18, index = 4 +24/0: compressed; stream = 18, index = 5 +25/0: compressed; stream = 18, index = 6 +26/0: compressed; stream = 18, index = 7 +27/0: compressed; stream = 18, index = 8 +28/0: compressed; stream = 18, index = 9 +29/0: compressed; stream = 18, index = 10 +30/0: compressed; stream = 18, index = 11 +31/0: compressed; stream = 18, index = 12 +32/0: compressed; stream = 18, index = 13 +33/0: compressed; stream = 18, index = 14 +34/0: compressed; stream = 18, index = 15 +35/0: compressed; stream = 18, index = 16 diff --git a/services/clsi/test/acceptance/fixtures/examples/xelatex_compiler/output.pdfxref b/services/clsi/test/acceptance/fixtures/examples/xelatex_compiler/output.pdfxref new file mode 100644 index 0000000000..20aa4ba02d --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/examples/xelatex_compiler/output.pdfxref @@ -0,0 +1,19 @@ +1/0: uncompressed; offset = 8578 +2/0: uncompressed; offset = 15 +3/0: uncompressed; offset = 216 +4/0: uncompressed; offset = 658 +5/0: uncompressed; offset = 708 +6/0: uncompressed; offset = 837 +7/0: uncompressed; offset = 940 +8/0: uncompressed; offset = 1191 +9/0: uncompressed; offset = 1627 +10/0: uncompressed; offset = 7676 +11/0: uncompressed; offset = 7784 +12/0: uncompressed; offset = 7822 +13/0: compressed; stream = 12, index = 0 +14/0: compressed; stream = 12, index = 1 +15/0: compressed; stream = 12, index = 2 +16/0: compressed; stream = 12, index = 3 +17/0: compressed; stream = 12, index = 4 +18/0: compressed; stream = 12, index = 5 +19/0: compressed; stream = 12, index = 6 diff --git a/services/clsi/test/acceptance/fixtures/minimal.pdfxref b/services/clsi/test/acceptance/fixtures/minimal.pdfxref new file mode 100644 index 0000000000..38b6e8f191 --- /dev/null +++ b/services/clsi/test/acceptance/fixtures/minimal.pdfxref @@ -0,0 +1,15 @@ +1/0: uncompressed; offset = 11784 +2/0: uncompressed; offset = 12033 +3/0: uncompressed; offset = 15 +4/0: uncompressed; offset = 216 +5/0: uncompressed; offset = 621 +6/0: uncompressed; offset = 671 +7/0: uncompressed; offset = 791 +8/0: uncompressed; offset = 906 +9/0: uncompressed; offset = 1070 +10/0: uncompressed; offset = 11235 +11/0: compressed; stream = 10, index = 0 +12/0: compressed; stream = 10, index = 1 +13/0: compressed; stream = 10, index = 2 +14/0: compressed; stream = 10, index = 3 +15/0: compressed; stream = 10, index = 4 diff --git a/services/clsi/test/unit/js/ContentCacheManagerTests.js b/services/clsi/test/unit/js/ContentCacheManagerTests.js index a30fe76758..74fef7cbab 100644 --- a/services/clsi/test/unit/js/ContentCacheManagerTests.js +++ b/services/clsi/test/unit/js/ContentCacheManagerTests.js @@ -5,7 +5,7 @@ const { expect } = require('chai') const MODULE_PATH = '../../../app/js/ContentCacheManager' describe('ContentCacheManager', function () { - let contentDir, pdfPath + let contentDir, pdfPath, xrefPath let ContentCacheManager, files, Settings before(function () { Settings = require('@overleaf/settings') @@ -38,6 +38,8 @@ describe('ContentCacheManager', function () { '/overleaf/services/clsi/output/602cee6f6460fca0ba7921e6/content/1797a7f48f9-5abc1998509dea1f' pdfPath = '/overleaf/services/clsi/output/602cee6f6460fca0ba7921e6/generated-files/1797a7f48ea-8ac6805139f43351/output.pdf' + xrefPath = + '/overleaf/services/clsi/output/602cee6f6460fca0ba7921e6/generated-files/1797a7f48ea-8ac6805139f43351/output.pdfxref' reclaimed = 0 Settings.pdfCachingMinChunkSize = 1024 @@ -50,7 +52,8 @@ describe('ContentCacheManager', function () { }) describe('minimal', function () { - const PATH_MINIMAL = 'test/acceptance/fixtures/minimal.pdf' + const PATH_MINIMAL_PDF = 'test/acceptance/fixtures/minimal.pdf' + const PATH_MINIMAL_XREF = 'test/acceptance/fixtures/minimal.pdfxref' const OBJECT_ID_1 = '9 0 ' const HASH_LARGE = 'd7cfc73ad2fba4578a437517923e3714927bbf35e63ea88bd93c7a8076cf1fcd' @@ -62,9 +65,10 @@ describe('ContentCacheManager', function () { } let MINIMAL_SIZE, RANGE_1, RANGE_2, h1, h2, START_1, START_2, END_1, END_2 before(async function () { - await fs.promises.copyFile(PATH_MINIMAL, pdfPath) - const MINIMAL = await fs.promises.readFile(PATH_MINIMAL) - MINIMAL_SIZE = (await fs.promises.stat(PATH_MINIMAL)).size + await fs.promises.copyFile(PATH_MINIMAL_PDF, pdfPath) + await fs.promises.copyFile(PATH_MINIMAL_XREF, xrefPath) + const MINIMAL = await fs.promises.readFile(PATH_MINIMAL_PDF) + MINIMAL_SIZE = (await fs.promises.stat(PATH_MINIMAL_PDF)).size RANGE_1 = await fs.promises.readFile(getChunkPath(HASH_LARGE)) RANGE_2 = await fs.promises.readFile(getChunkPath(HASH_SMALL)) h1 = HASH_LARGE diff --git a/services/clsi/test/unit/js/pdfjsTests.js b/services/clsi/test/unit/js/pdfjsTests.js index 92f10279d2..ef85ccc704 100644 --- a/services/clsi/test/unit/js/pdfjsTests.js +++ b/services/clsi/test/unit/js/pdfjsTests.js @@ -1,7 +1,8 @@ const fs = require('fs') const Path = require('path') const { expect } = require('chai') -const { parseXrefTable } = require('../../../app/lib/pdfjs/parseXrefTable') +const { parseXrefTable } = require('../../../app/js/XrefParser') +const { NoXrefTableError } = require('../../../app/js/Errors') const PATH_EXAMPLES = 'test/acceptance/fixtures/examples/' const PATH_SNAPSHOTS = 'test/unit/js/snapshots/pdfjs/' const EXAMPLES = fs.readdirSync(PATH_EXAMPLES) @@ -48,24 +49,11 @@ describe('pdfjs', function () { describe('when the pdf is an empty file', function () { it('should yield no entries', async function () { const path = 'does/not/matter.pdf' - const table = await parseXrefTable(path, 0) - expect(table).to.deep.equal([]) - }) - }) - - describe('when the operation times out', function () { - it('should bail out', async function () { - const path = pdfPath(EXAMPLES[0]) - const { size } = await loadContext(EXAMPLES[0]) - const err = new Error() let table try { - table = await parseXrefTable(path, size, () => { - throw err - }) + table = await parseXrefTable(path, 0) } catch (e) { - expect(e).to.equal(err) - return + expect(e).to.be.an.instanceof(NoXrefTableError) } expect(table).to.not.exist }) @@ -89,7 +77,16 @@ describe('pdfjs', function () { it('should produce the expected xRef table', async function () { const table = await parseXrefTable(pdfPath(example), size, () => {}) - expect(table).to.deep.equal(snapshot) + // compare the essential parts of the xref table only + expect(table.xRefEntries[0]).to.include({ offset: 0 }) + expect(table.xRefEntries.slice(1)).to.deep.equal( + snapshot.xRefEntries + .slice(1) + .filter(xref => xref.uncompressed) // we only use the uncompressed fields + .map(xref => { + return { offset: xref.offset, uncompressed: xref.uncompressed } // ignore unused gen field + }) + ) }) }) }