diff --git a/src/core/chunked_stream.js b/src/core/chunked_stream.js index 040151815..98e8d7216 100644 --- a/src/core/chunked_stream.js +++ b/src/core/chunked_stream.js @@ -187,6 +187,8 @@ var ChunkedStream = (function ChunkedStreamClosure() { }, makeSubStream: function ChunkedStream_makeSubStream(start, length, dict) { + this.ensureRange(start, start + length); + function ChunkedStreamSubstream() {} ChunkedStreamSubstream.prototype = Object.create(this); ChunkedStreamSubstream.prototype.getMissingChunks = function() { diff --git a/src/core/parser.js b/src/core/parser.js index f5eaa1b41..28440eb3f 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -300,12 +300,10 @@ var Parser = (function ParserClosure() { return new LZWStream(stream, earlyChange); } if (name == 'DCTDecode' || name == 'DCT') { - var bytes = stream.getBytes(length); - return new JpegStream(bytes, stream.dict, this.xref); + return new JpegStream(stream, length, stream.dict, this.xref); } if (name == 'JPXDecode' || name == 'JPX') { - var bytes = stream.getBytes(length); - return new JpxStream(bytes, stream.dict); + return new JpxStream(stream, length, stream.dict); } if (name == 'ASCII85Decode' || name == 'A85') { return new Ascii85Stream(stream); @@ -320,8 +318,7 @@ var Parser = (function ParserClosure() { return new RunLengthStream(stream); } if (name == 'JBIG2Decode') { - var bytes = stream.getBytes(length); - return new Jbig2Stream(bytes, stream.dict); + return new Jbig2Stream(stream, length, stream.dict); } warn('filter "' + name + '" not supported yet'); return stream; diff --git a/src/core/stream.js b/src/core/stream.js index 7a5a2f889..819879506 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals bytesToString, ColorSpace, Dict, EOF, error, info, Jbig2Image, - JpegImage, JpxImage, Lexer, Util, PDFJS, isArray, warn */ +/* globals bytesToString, ColorSpace, Dict, EOF, error, info, isArray, + Jbig2Image, JpegImage, JpxImage, Lexer, PDFJS, shadow, Util, warn */ 'use strict'; @@ -328,13 +328,12 @@ var FlateStream = (function FlateStreamClosure() { 0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000 ]), 5]; - function FlateStream(stream) { - var bytes = stream.getBytes(); - var bytesPos = 0; + function FlateStream(str) { + this.str = str; + this.dict = str.dict; - this.dict = stream.dict; - var cmf = bytes[bytesPos++]; - var flg = bytes[bytesPos++]; + var cmf = str.getByte(); + var flg = str.getByte(); if (cmf == -1 || flg == -1) error('Invalid header in flate stream: ' + cmf + ', ' + flg); if ((cmf & 0x0f) != 0x08) @@ -344,9 +343,6 @@ var FlateStream = (function FlateStreamClosure() { if (flg & 0x20) error('FDICT bit set in flate stream: ' + cmf + ', ' + flg); - this.bytes = bytes; - this.bytesPos = bytesPos; - this.codeSize = 0; this.codeBuf = 0; @@ -356,37 +352,37 @@ var FlateStream = (function FlateStreamClosure() { FlateStream.prototype = Object.create(DecodeStream.prototype); FlateStream.prototype.getBits = function FlateStream_getBits(bits) { + var str = this.str; var codeSize = this.codeSize; var codeBuf = this.codeBuf; - var bytes = this.bytes; - var bytesPos = this.bytesPos; var b; while (codeSize < bits) { - if (typeof (b = bytes[bytesPos++]) == 'undefined') + if ((b = str.getByte()) === -1) { error('Bad encoding in flate stream'); + } codeBuf |= b << codeSize; codeSize += 8; } b = codeBuf & ((1 << bits) - 1); this.codeBuf = codeBuf >> bits; this.codeSize = codeSize -= bits; - this.bytesPos = bytesPos; + return b; }; FlateStream.prototype.getCode = function FlateStream_getCode(table) { + var str = this.str; var codes = table[0]; var maxLen = table[1]; var codeSize = this.codeSize; var codeBuf = this.codeBuf; - var bytes = this.bytes; - var bytesPos = this.bytesPos; while (codeSize < maxLen) { var b; - if (typeof (b = bytes[bytesPos++]) == 'undefined') + if ((b = str.getByte()) === -1) { error('Bad encoding in flate stream'); + } codeBuf |= (b << codeSize); codeSize += 8; } @@ -397,7 +393,6 @@ var FlateStream = (function FlateStreamClosure() { error('Bad encoding in flate stream'); this.codeBuf = (codeBuf >> codeLen); this.codeSize = (codeSize - codeLen); - this.bytesPos = bytesPos; return codeVal; }; @@ -441,6 +436,7 @@ var FlateStream = (function FlateStreamClosure() { }; FlateStream.prototype.readBlock = function FlateStream_readBlock() { + var str = this.str; // read block header var hdr = this.getBits(3); if (hdr & 1) @@ -448,21 +444,23 @@ var FlateStream = (function FlateStreamClosure() { hdr >>= 1; if (hdr === 0) { // uncompressed block - var bytes = this.bytes; - var bytesPos = this.bytesPos; var b; - if (typeof (b = bytes[bytesPos++]) == 'undefined') + if ((b = str.getByte()) === -1) { error('Bad block header in flate stream'); + } var blockLen = b; - if (typeof (b = bytes[bytesPos++]) == 'undefined') + if ((b = str.getByte()) === -1) { error('Bad block header in flate stream'); + } blockLen |= (b << 8); - if (typeof (b = bytes[bytesPos++]) == 'undefined') + if ((b = str.getByte()) === -1) { error('Bad block header in flate stream'); + } var check = b; - if (typeof (b = bytes[bytesPos++]) == 'undefined') + if ((b = str.getByte()) === -1) { error('Bad block header in flate stream'); + } check |= (b << 8); if (check != (~blockLen & 0xffff) && (blockLen !== 0 || check !== 0)) { @@ -478,19 +476,18 @@ var FlateStream = (function FlateStreamClosure() { var end = bufferLength + blockLen; this.bufferLength = end; if (blockLen === 0) { - if (typeof bytes[bytesPos] == 'undefined') { + if (str.peekBytes(1).length === 0) { this.eof = true; } } else { for (var n = bufferLength; n < end; ++n) { - if (typeof (b = bytes[bytesPos++]) == 'undefined') { + if ((b = str.getByte()) === -1) { this.eof = true; break; } buffer[n] = b; } } - this.bytesPos = bytesPos; return; } @@ -777,17 +774,25 @@ var PredictorStream = (function PredictorStreamClosure() { * DecodeStreams. */ var JpegStream = (function JpegStreamClosure() { - function JpegStream(bytes, dict, xref) { + function JpegStream(stream, length, dict, xref) { // TODO: per poppler, some images may have 'junk' before that // need to be removed + this.stream = stream; + this.length = length; this.dict = dict; - this.bytes = bytes; DecodeStream.call(this); } JpegStream.prototype = Object.create(DecodeStream.prototype); + Object.defineProperty(JpegStream.prototype, 'bytes', { + get: function JpegStream_bytes() { + return shadow(this, 'bytes', this.stream.getBytes(this.length)); + }, + configurable: true + }); + JpegStream.prototype.ensureBuffer = function JpegStream_ensureBuffer(req) { if (this.bufferLength) return; @@ -836,15 +841,23 @@ var JpegStream = (function JpegStreamClosure() { * the stream behaves like all the other DecodeStreams. */ var JpxStream = (function JpxStreamClosure() { - function JpxStream(bytes, dict) { + function JpxStream(stream, length, dict) { + this.stream = stream; + this.length = length; this.dict = dict; - this.bytes = bytes; DecodeStream.call(this); } JpxStream.prototype = Object.create(DecodeStream.prototype); + Object.defineProperty(JpxStream.prototype, 'bytes', { + get: function JpxStream_bytes() { + return shadow(this, 'bytes', this.stream.getBytes(this.length)); + }, + configurable: true + }); + JpxStream.prototype.ensureBuffer = function JpxStream_ensureBuffer(req) { if (this.bufferLength) return; @@ -935,15 +948,23 @@ var JpxStream = (function JpxStreamClosure() { * the stream behaves like all the other DecodeStreams. */ var Jbig2Stream = (function Jbig2StreamClosure() { - function Jbig2Stream(bytes, dict) { + function Jbig2Stream(stream, length, dict) { + this.stream = stream; + this.length = length; this.dict = dict; - this.bytes = bytes; DecodeStream.call(this); } Jbig2Stream.prototype = Object.create(DecodeStream.prototype); + Object.defineProperty(Jbig2Stream.prototype, 'bytes', { + get: function Jbig2Stream_bytes() { + return shadow(this, 'bytes', this.stream.getBytes(this.length)); + }, + configurable: true + }); + Jbig2Stream.prototype.ensureBuffer = function Jbig2Stream_ensureBuffer(req) { if (this.bufferLength) return;