diff --git a/external/jpgjs/LICENSE b/external/jpgjs/LICENSE index f28619c6a..1e29c87c8 100644 --- a/external/jpgjs/LICENSE +++ b/external/jpgjs/LICENSE @@ -1,24 +1,17 @@ -Copyright (C) 2011 by notmasteryet + Copyright (C) 2011 notmasteryet -Contributors: Yury Delendik - Brendan Dahl + Contributors: Yury Delendik + Brendan Dahl -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. + http://www.apache.org/licenses/LICENSE-2.0 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/external/jpgjs/jpg.js b/external/jpgjs/jpg.js index 103153d9d..941d01a87 100644 --- a/external/jpgjs/jpg.js +++ b/external/jpgjs/jpg.js @@ -1,5 +1,20 @@ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ +/* + Copyright 2011 notmasteryet + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ // - The JPEG specification can be found in the ITU CCITT Recommendation T.81 // (www.w3.org/Graphics/JPEG/itu-t81.pdf) @@ -627,8 +642,9 @@ var JpegImage = (function jpegImage() { break; case 0xFFDB: // DQT (Define Quantization Tables) - var quantizationTableCount = Math.floor((readUint16() - 2) / 65); - for (i = 0; i < quantizationTableCount; i++) { + var quantizationTablesLength = readUint16(); + var quantizationTablesEnd = quantizationTablesLength + offset - 2; + while (offset < quantizationTablesEnd) { var quantizationTableSpec = data[offset++]; var tableData = new Int32Array(64); if ((quantizationTableSpec >> 4) === 0) { // 8 bit values @@ -721,6 +737,13 @@ var JpegImage = (function jpegImage() { offset += processed; break; default: + if (data[offset - 3] == 0xFF && + data[offset - 2] >= 0xC0 && data[offset - 2] <= 0xFE) { + // could be incorrect encoding -- last 0xFF byte of the previous + // block was eaten by the encoder + offset -= 3; + break; + } throw "unknown JPEG marker " + fileMarker.toString(16); } fileMarker = readUint16(); diff --git a/make.js b/make.js index fa04b6c1d..7299bbf3c 100755 --- a/make.js +++ b/make.js @@ -618,18 +618,18 @@ target.chrome = function() { }); // If there was no chrome entry in the browser manifest, exit - if(!executable) { + if (!executable) { echo('There was no \'chrome\' entry in the browser manifest'); exit(1); } // If we're on a Darwin (Mac) OS, then let's check for an .app path if (process.platform === 'darwin' && executable.indexOf('.app') !== -1) { - executable = executable + '/Contents/MacOS/Google Chrome'); + executable = executable + '/Contents/MacOS/Google Chrome'; } // If the chrome executable doesn't exist - if(!test('-f', executable)) { + if (!test('-f', executable)) { echo('Incorrect executable path to chrome'); exit(1); } @@ -765,7 +765,10 @@ target.lint = function() { echo(); echo('### Linting JS files (this can take a while!)'); - var LINT_FILES = ['src/*.js', + var LINT_FILES = ['make.js', + 'external/builder/*.js', + 'external/crlfchecker/*.js', + 'src/*.js', 'web/*.js', 'test/*.js', 'test/unit/*.js', diff --git a/src/fonts.js b/src/fonts.js index eda67df33..4aef0962a 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -404,28 +404,15 @@ function mapPrivateUseChars(code) { } var FontLoader = { - listeningForFontLoad: false, + loadingContext: { + requests: [], + nextRequestId: 0 + }, bind: function fontLoaderBind(fonts, callback) { - function checkFontsLoaded() { - for (var i = 0, ii = fonts.length; i < ii; i++) { - var fontObj = fonts[i]; - if (fontObj.loading) { - return false; - } - } - - document.documentElement.removeEventListener( - 'pdfjsFontLoad', checkFontsLoaded, false); - - // Use timeout to fix chrome intermittent failures on font loading. - setTimeout(callback, 0); - return true; - } - - var rules = [], names = [], fontsToLoad = []; - var fontCreateTimer = 0; + assert(!isWorker, 'bind() shall be called from main thread'); + var rules = [], fontsToLoad = []; for (var i = 0, ii = fonts.length; i < ii; i++) { var font = fonts[i]; @@ -436,8 +423,6 @@ var FontLoader = { } font.attached = true; - fontsToLoad.push(font); - var str = ''; var data = font.data; if (data) { @@ -448,28 +433,51 @@ var FontLoader = { var rule = font.bindDOM(str); if (rule) { rules.push(rule); - names.push(font.loadedName); + fontsToLoad.push(font); } } } - this.listeningForFontLoad = false; - if (!isWorker && rules.length) { - FontLoader.prepareFontLoadEvent(rules, names, fontsToLoad); - } - - if (!checkFontsLoaded()) { - document.documentElement.addEventListener( - 'pdfjsFontLoad', checkFontsLoaded, false); + var request = FontLoader.queueLoadingCallback(callback); + if (rules.length > 0) { + FontLoader.prepareFontLoadEvent(rules, fontsToLoad, request); + } else { + request.complete(); } }, + + queueLoadingCallback: function FontLoader_queueLoadingCallback(callback) { + function LoadLoader_completeRequest() { + assert(!request.end, 'completeRequest() cannot be called twice'); + request.end = Date.now(); + + // sending all completed requests in order how they were queued + while (context.requests.length > 0 && context.requests[0].end) { + var otherRequest = context.requests.shift(); + setTimeout(otherRequest.callback, 0); + } + } + + var context = FontLoader.loadingContext; + var requestId = 'pdfjs-font-loading-' + (context.nextRequestId++); + var request = { + id: requestId, + complete: LoadLoader_completeRequest, + callback: callback, + started: Date.now() + }; + context.requests.push(request); + return request; + }, + // Set things up so that at least one pdfjsFontLoad event is - // dispatched when all the @font-face |rules| for |names| have been + // dispatched when all the @font-face |rules| for |fonts| have been // loaded in a subdocument. It's expected that the load of |rules| // has already started in this (outer) document, so that they should // be ordered before the load in the subdocument. - prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, names, - fonts) { + prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, + fonts, + request) { /** Hack begin */ // There's no event when a font has finished downloading so the // following code is a dirty hack to 'guess' when a font is @@ -493,6 +501,20 @@ var FontLoader = { // The postMessage() hackery was added to work around chrome bug // 82402. + var requestId = request.id; + // Validate the requestId parameter -- the value used to construct HTML. + if (!/^[\w\-]+$/.test(requestId)) { + error('Invalid request id: ' + requestId); + + // Normally the error-function throws. But if a malicious code + // intercepts the function call then the return is needed. + return; + } + + var names = []; + for (var i = 0, ii = fonts.length; i < ii; i++) + names.push(fonts[i].loadedName); + // Validate the names parameter -- the values can used to construct HTML. if (!/^\w+$/.test(names.join(''))) { error('Invalid font name(s): ' + names.join()); @@ -514,22 +536,21 @@ var FontLoader = { div.innerHTML = html; document.body.appendChild(div); - if (!this.listeningForFontLoad) { - window.addEventListener( - 'message', - function fontLoaderMessage(e) { - var fontNames = JSON.parse(e.data); - for (var i = 0, ii = fonts.length; i < ii; ++i) { - var font = fonts[i]; - font.loading = false; - } - var evt = document.createEvent('Events'); - evt.initEvent('pdfjsFontLoad', true, false); - document.documentElement.dispatchEvent(evt); - }, - false); - this.listeningForFontLoad = true; - } + window.addEventListener( + 'message', + function fontLoaderMessage(e) { + if (e.data !== requestId) + return; + for (var i = 0, ii = fonts.length; i < ii; ++i) { + var font = fonts[i]; + font.loading = false; + } + request.complete(); + // cleanup + document.body.removeChild(frame); + window.removeEventListener('message', fontLoaderMessage, false); + }, + false); // XXX we should have a time-out here too, and maybe fire // pdfjsFontLoadFailed? @@ -540,13 +561,8 @@ var FontLoader = { } src += ''; src += '