mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-21 23:58:07 +02:00
Merge branch 'master' of github.com:mozilla/pdf.js into textsearch
This commit is contained in:
commit
0bac4abcb5
22 changed files with 675 additions and 78 deletions
|
@ -8,10 +8,12 @@
|
|||
* e.g. No cross domain requests without CORS.
|
||||
*
|
||||
* @param {string|TypedAray} source Either a url to a PDF is located or a
|
||||
* typed array already populated with data.
|
||||
* typed array (Uint8Array) already populated with data.
|
||||
* @param {Object} headers An object containing the http headers like this:
|
||||
* { Authorization: "BASIC XXX" }.
|
||||
* @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.
|
||||
*/
|
||||
PDFJS.getDocument = function getDocument(source) {
|
||||
PDFJS.getDocument = function getDocument(source, headers) {
|
||||
var promise = new PDFJS.Promise();
|
||||
var transport = new WorkerTransport(promise);
|
||||
if (typeof source === 'string') {
|
||||
|
@ -29,7 +31,8 @@ PDFJS.getDocument = function getDocument(source) {
|
|||
error: function getPDFError(e) {
|
||||
promise.reject('Unexpected server response of ' +
|
||||
e.target.status + '.');
|
||||
}
|
||||
},
|
||||
headers: headers
|
||||
},
|
||||
function getPDFLoad(data) {
|
||||
transport.sendData(data);
|
||||
|
|
12
src/core.js
12
src/core.js
|
@ -31,7 +31,19 @@ function getPdf(arg, callback) {
|
|||
params = { url: arg };
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open('GET', params.url);
|
||||
|
||||
var headers = params.headers;
|
||||
if (headers) {
|
||||
for (var property in headers) {
|
||||
if (typeof headers[property] === 'undefined')
|
||||
continue;
|
||||
|
||||
xhr.setRequestHeader(property, params.headers[property]);
|
||||
}
|
||||
}
|
||||
|
||||
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
|
||||
var protocol = params.url.indexOf(':') < 0 ? window.location.protocol :
|
||||
params.url.substring(0, params.url.indexOf(':') + 1);
|
||||
|
|
|
@ -419,13 +419,14 @@ var CipherTransform = (function CipherTransformClosure() {
|
|||
})();
|
||||
|
||||
var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
||||
var defaultPasswordBytes = new Uint8Array([
|
||||
0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41,
|
||||
0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
|
||||
0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80,
|
||||
0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A]);
|
||||
|
||||
function prepareKeyData(fileId, password, ownerPassword, userPassword,
|
||||
flags, revision, keyLength, encryptMetadata) {
|
||||
var defaultPasswordBytes = new Uint8Array([
|
||||
0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41,
|
||||
0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
|
||||
0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80,
|
||||
0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A]);
|
||||
var hashData = new Uint8Array(100), i = 0, j, n;
|
||||
if (password) {
|
||||
n = Math.min(32, password.length);
|
||||
|
@ -462,9 +463,8 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
|||
var cipher, checkData;
|
||||
|
||||
if (revision >= 3) {
|
||||
// padded password in hashData, we can use this array for user
|
||||
// password check
|
||||
i = 32;
|
||||
for (i = 0; i < 32; ++i)
|
||||
hashData[i] = defaultPasswordBytes[i];
|
||||
for (j = 0, n = fileId.length; j < n; ++j)
|
||||
hashData[i++] = fileId[j];
|
||||
cipher = new ARCFourCipher(encryptionKey);
|
||||
|
@ -477,16 +477,53 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
|||
cipher = new ARCFourCipher(derivedKey);
|
||||
checkData = cipher.encryptBlock(checkData);
|
||||
}
|
||||
for (j = 0, n = checkData.length; j < n; ++j) {
|
||||
if (userPassword[j] != checkData[j])
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
cipher = new ARCFourCipher(encryptionKey);
|
||||
checkData = cipher.encryptBlock(hashData.subarray(0, 32));
|
||||
}
|
||||
for (j = 0, n = checkData.length; j < n; ++j) {
|
||||
if (userPassword[j] != checkData[j])
|
||||
error('incorrect password');
|
||||
checkData = cipher.encryptBlock(defaultPasswordBytes);
|
||||
for (j = 0, n = checkData.length; j < n; ++j) {
|
||||
if (userPassword[j] != checkData[j])
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return encryptionKey;
|
||||
}
|
||||
function decodeUserPassword(password, ownerPassword, revision, keyLength) {
|
||||
var hashData = new Uint8Array(32), i = 0, j, n;
|
||||
n = Math.min(32, password.length);
|
||||
for (; i < n; ++i)
|
||||
hashData[i] = password[i];
|
||||
j = 0;
|
||||
while (i < 32) {
|
||||
hashData[i++] = defaultPasswordBytes[j++];
|
||||
}
|
||||
var hash = calculateMD5(hashData, 0, i);
|
||||
var keyLengthInBytes = keyLength >> 3;
|
||||
if (revision >= 3) {
|
||||
for (j = 0; j < 50; ++j) {
|
||||
hash = calculateMD5(hash, 0, hash.length);
|
||||
}
|
||||
}
|
||||
|
||||
var cipher, userPassword;
|
||||
if (revision >= 3) {
|
||||
userPassword = ownerPassword;
|
||||
var derivedKey = new Uint8Array(keyLengthInBytes), k;
|
||||
for (j = 19; j >= 0; j--) {
|
||||
for (k = 0; k < keyLengthInBytes; ++k)
|
||||
derivedKey[k] = hash[k] ^ j;
|
||||
cipher = new ARCFourCipher(derivedKey);
|
||||
userPassword = cipher.encryptBlock(userPassword);
|
||||
}
|
||||
} else {
|
||||
cipher = new ARCFourCipher(hash.subarray(0, keyLengthInBytes));
|
||||
userPassword = cipher.encryptBlock(ownerPassword);
|
||||
}
|
||||
return userPassword;
|
||||
}
|
||||
|
||||
var identityName = new Name('Identity');
|
||||
|
||||
|
@ -516,10 +553,23 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
|||
if (password)
|
||||
passwordBytes = stringToBytes(password);
|
||||
|
||||
this.encryptionKey = prepareKeyData(fileIdBytes, passwordBytes,
|
||||
ownerPassword, userPassword,
|
||||
flags, revision,
|
||||
keyLength, encryptMetadata);
|
||||
var encryptionKey = prepareKeyData(fileIdBytes, passwordBytes,
|
||||
ownerPassword, userPassword, flags,
|
||||
revision, keyLength, encryptMetadata);
|
||||
if (!encryptionKey && password) {
|
||||
// Attempting use the password as an owner password
|
||||
var decodedPassword = decodeUserPassword(passwordBytes, ownerPassword,
|
||||
revision, keyLength);
|
||||
encryptionKey = prepareKeyData(fileIdBytes, decodedPassword,
|
||||
ownerPassword, userPassword, flags,
|
||||
revision, keyLength, encryptMetadata);
|
||||
}
|
||||
|
||||
if (!encryptionKey)
|
||||
error('incorrect password or encryption data');
|
||||
|
||||
this.encryptionKey = encryptionKey;
|
||||
|
||||
if (algorithm == 4) {
|
||||
this.cf = dict.get('CF');
|
||||
this.stmf = dict.get('StmF') || identityName;
|
||||
|
|
|
@ -112,14 +112,33 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||
};
|
||||
|
||||
function splitCombinedOperations(operations) {
|
||||
// Two operations can be combined together, trying to find which two
|
||||
// Two or more operations can be combined together, trying to find which
|
||||
// operations were concatenated.
|
||||
for (var i = operations.length - 1; i > 0; i--) {
|
||||
var op1 = operations.substring(0, i), op2 = operations.substring(i);
|
||||
if (op1 in OP_MAP && op2 in OP_MAP)
|
||||
return [op1, op2]; // operations found
|
||||
var result = [];
|
||||
var opIndex = 0;
|
||||
|
||||
if (!operations) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
while (opIndex < operations.length) {
|
||||
var currentOp = '';
|
||||
for (var op in OP_MAP) {
|
||||
if (op == operations.substr(opIndex, op.length) &&
|
||||
op.length > currentOp.length) {
|
||||
currentOp = op;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentOp.length > 0) {
|
||||
result.push(operations.substr(opIndex, currentOp.length));
|
||||
opIndex += currentOp.length;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PartialEvaluator.prototype = {
|
||||
|
@ -268,14 +287,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||
var patterns = resources.get('Pattern') || new Dict();
|
||||
var parser = new Parser(new Lexer(stream), false, xref);
|
||||
var res = resources;
|
||||
var hasNextObj = false, nextObj;
|
||||
var hasNextObj = false, nextObjs;
|
||||
var args = [], obj;
|
||||
var TILING_PATTERN = 1, SHADING_PATTERN = 2;
|
||||
|
||||
while (true) {
|
||||
if (hasNextObj) {
|
||||
obj = nextObj;
|
||||
hasNextObj = false;
|
||||
obj = nextObjs.pop();
|
||||
hasNextObj = (nextObjs.length > 0);
|
||||
} else {
|
||||
obj = parser.getObj();
|
||||
if (isEOF(obj))
|
||||
|
@ -291,9 +310,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||
if (cmds) {
|
||||
cmd = cmds[0];
|
||||
fn = OP_MAP[cmd];
|
||||
// feeding other command on the next interation
|
||||
// feeding other command on the next iteration
|
||||
hasNextObj = true;
|
||||
nextObj = Cmd.get(cmds[1]);
|
||||
nextObjs = [];
|
||||
for (var idx = 1; idx < cmds.length; idx++) {
|
||||
nextObjs.push(Cmd.get(cmds[idx]));
|
||||
}
|
||||
}
|
||||
}
|
||||
assertWellFormed(fn, 'Unknown command "' + cmd + '"');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue