Merge pull request #13321 from timvandermeij/src-core-no-var

Enable the `no-var` linting rule in `src/core/{crypto,function}.js`
This commit is contained in:
Tim van der Meij 2021-05-02 13:45:33 +02:00 committed by GitHub
commit af9feb1307
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 292 additions and 297 deletions

View File

@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* eslint-disable no-var */
import { import {
bytesToString, bytesToString,
@ -32,16 +31,14 @@ class ARCFourCipher {
constructor(key) { constructor(key) {
this.a = 0; this.a = 0;
this.b = 0; this.b = 0;
var s = new Uint8Array(256); const s = new Uint8Array(256);
var i, const keyLength = key.length;
j = 0,
tmp, for (let i = 0; i < 256; ++i) {
keyLength = key.length;
for (i = 0; i < 256; ++i) {
s[i] = i; s[i] = i;
} }
for (i = 0; i < 256; ++i) { for (let i = 0, j = 0; i < 256; ++i) {
tmp = s[i]; const tmp = s[i];
j = (j + tmp + key[i % keyLength]) & 0xff; j = (j + tmp + key[i % keyLength]) & 0xff;
s[i] = s[j]; s[i] = s[j];
s[j] = tmp; s[j] = tmp;
@ -50,19 +47,16 @@ class ARCFourCipher {
} }
encryptBlock(data) { encryptBlock(data) {
var i, let a = this.a,
n = data.length, b = this.b;
tmp, const s = this.s;
tmp2; const n = data.length;
var a = this.a, const output = new Uint8Array(n);
b = this.b, for (let i = 0; i < n; ++i) {
s = this.s;
var output = new Uint8Array(n);
for (i = 0; i < n; ++i) {
a = (a + 1) & 0xff; a = (a + 1) & 0xff;
tmp = s[a]; const tmp = s[a];
b = (b + tmp) & 0xff; b = (b + tmp) & 0xff;
tmp2 = s[b]; const tmp2 = s[b];
s[a] = tmp2; s[a] = tmp2;
s[b] = tmp; s[b] = tmp;
output[i] = data[i] ^ s[(tmp + tmp2) & 0xff]; output[i] = data[i] ^ s[(tmp + tmp2) & 0xff];
@ -81,16 +75,16 @@ class ARCFourCipher {
} }
} }
var calculateMD5 = (function calculateMD5Closure() { const calculateMD5 = (function calculateMD5Closure() {
// prettier-ignore // prettier-ignore
var r = new Uint8Array([ const r = new Uint8Array([
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]); 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]);
// prettier-ignore // prettier-ignore
var k = new Int32Array([ const k = new Int32Array([
-680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426,
-1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162,
1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632,
@ -104,19 +98,19 @@ var calculateMD5 = (function calculateMD5Closure() {
-145523070, -1120210379, 718787259, -343485551]); -145523070, -1120210379, 718787259, -343485551]);
function hash(data, offset, length) { function hash(data, offset, length) {
var h0 = 1732584193, let h0 = 1732584193,
h1 = -271733879, h1 = -271733879,
h2 = -1732584194, h2 = -1732584194,
h3 = 271733878; h3 = 271733878;
// pre-processing // pre-processing
var paddedLength = (length + 72) & ~63; // data + 9 extra bytes const paddedLength = (length + 72) & ~63; // data + 9 extra bytes
var padded = new Uint8Array(paddedLength); const padded = new Uint8Array(paddedLength);
var i, j, n; let i, j;
for (i = 0; i < length; ++i) { for (i = 0; i < length; ++i) {
padded[i] = data[offset++]; padded[i] = data[offset++];
} }
padded[i++] = 0x80; padded[i++] = 0x80;
n = paddedLength - 8; const n = paddedLength - 8;
while (i < n) { while (i < n) {
padded[i++] = 0; padded[i++] = 0;
} }
@ -128,7 +122,7 @@ var calculateMD5 = (function calculateMD5Closure() {
padded[i++] = 0; padded[i++] = 0;
padded[i++] = 0; padded[i++] = 0;
padded[i++] = 0; padded[i++] = 0;
var w = new Int32Array(16); const w = new Int32Array(16);
for (i = 0; i < paddedLength; ) { for (i = 0; i < paddedLength; ) {
for (j = 0; j < 16; ++j, i += 4) { for (j = 0; j < 16; ++j, i += 4) {
w[j] = w[j] =
@ -137,7 +131,7 @@ var calculateMD5 = (function calculateMD5Closure() {
(padded[i + 2] << 16) | (padded[i + 2] << 16) |
(padded[i + 3] << 24); (padded[i + 3] << 24);
} }
var a = h0, let a = h0,
b = h1, b = h1,
c = h2, c = h2,
d = h3, d = h3,
@ -157,7 +151,7 @@ var calculateMD5 = (function calculateMD5Closure() {
f = c ^ (b | ~d); f = c ^ (b | ~d);
g = (7 * j) & 15; g = (7 * j) & 15;
} }
var tmp = d, const tmp = d,
rotateArg = (a + f + k[j] + w[g]) | 0, rotateArg = (a + f + k[j] + w[g]) | 0,
rotate = r[j]; rotate = r[j];
d = c; d = c;
@ -224,7 +218,7 @@ class Word64 {
} }
rotateRight(places) { rotateRight(places) {
var low, high; let low, high;
if (places & 32) { if (places & 32) {
high = this.low; high = this.low;
low = this.high; low = this.high;
@ -243,8 +237,8 @@ class Word64 {
} }
add(word) { add(word) {
var lowAdd = (this.low >>> 0) + (word.low >>> 0); const lowAdd = (this.low >>> 0) + (word.low >>> 0);
var highAdd = (this.high >>> 0) + (word.high >>> 0); let highAdd = (this.high >>> 0) + (word.high >>> 0);
if (lowAdd > 0xffffffff) { if (lowAdd > 0xffffffff) {
highAdd += 1; highAdd += 1;
} }
@ -269,7 +263,7 @@ class Word64 {
} }
} }
var calculateSHA256 = (function calculateSHA256Closure() { const calculateSHA256 = (function calculateSHA256Closure() {
function rotr(x, n) { function rotr(x, n) {
return (x >>> n) | (x << (32 - n)); return (x >>> n) | (x << (32 - n));
} }
@ -299,7 +293,7 @@ var calculateSHA256 = (function calculateSHA256Closure() {
} }
// prettier-ignore // prettier-ignore
var k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, const k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
@ -318,7 +312,7 @@ var calculateSHA256 = (function calculateSHA256Closure() {
function hash(data, offset, length) { function hash(data, offset, length) {
// initial hash values // initial hash values
var h0 = 0x6a09e667, let h0 = 0x6a09e667,
h1 = 0xbb67ae85, h1 = 0xbb67ae85,
h2 = 0x3c6ef372, h2 = 0x3c6ef372,
h3 = 0xa54ff53a, h3 = 0xa54ff53a,
@ -327,14 +321,14 @@ var calculateSHA256 = (function calculateSHA256Closure() {
h6 = 0x1f83d9ab, h6 = 0x1f83d9ab,
h7 = 0x5be0cd19; h7 = 0x5be0cd19;
// pre-processing // pre-processing
var paddedLength = Math.ceil((length + 9) / 64) * 64; const paddedLength = Math.ceil((length + 9) / 64) * 64;
var padded = new Uint8Array(paddedLength); const padded = new Uint8Array(paddedLength);
var i, j, n; let i, j;
for (i = 0; i < length; ++i) { for (i = 0; i < length; ++i) {
padded[i] = data[offset++]; padded[i] = data[offset++];
} }
padded[i++] = 0x80; padded[i++] = 0x80;
n = paddedLength - 8; const n = paddedLength - 8;
while (i < n) { while (i < n) {
padded[i++] = 0; padded[i++] = 0;
} }
@ -346,7 +340,7 @@ var calculateSHA256 = (function calculateSHA256Closure() {
padded[i++] = (length >> 13) & 0xff; padded[i++] = (length >> 13) & 0xff;
padded[i++] = (length >> 5) & 0xff; padded[i++] = (length >> 5) & 0xff;
padded[i++] = (length << 3) & 0xff; padded[i++] = (length << 3) & 0xff;
var w = new Uint32Array(64); const w = new Uint32Array(64);
// for each 512 bit block // for each 512 bit block
for (i = 0; i < paddedLength; ) { for (i = 0; i < paddedLength; ) {
for (j = 0; j < 16; ++j) { for (j = 0; j < 16; ++j) {
@ -366,7 +360,7 @@ var calculateSHA256 = (function calculateSHA256Closure() {
w[j - 16]) | w[j - 16]) |
0; 0;
} }
var a = h0, let a = h0,
b = h1, b = h1,
c = h2, c = h2,
d = h3, d = h3,
@ -413,7 +407,7 @@ var calculateSHA256 = (function calculateSHA256Closure() {
return hash; return hash;
})(); })();
var calculateSHA512 = (function calculateSHA512Closure() { const calculateSHA512 = (function calculateSHA512Closure() {
function ch(result, x, y, z, tmp) { function ch(result, x, y, z, tmp) {
result.assign(x); result.assign(x);
result.and(y); result.and(y);
@ -479,7 +473,7 @@ var calculateSHA512 = (function calculateSHA512Closure() {
} }
// prettier-ignore // prettier-ignore
var k = [ const k = [
new Word64(0x428a2f98, 0xd728ae22), new Word64(0x71374491, 0x23ef65cd), new Word64(0x428a2f98, 0xd728ae22), new Word64(0x71374491, 0x23ef65cd),
new Word64(0xb5c0fbcf, 0xec4d3b2f), new Word64(0xe9b5dba5, 0x8189dbbc), new Word64(0xb5c0fbcf, 0xec4d3b2f), new Word64(0xe9b5dba5, 0x8189dbbc),
new Word64(0x3956c25b, 0xf348b538), new Word64(0x59f111f1, 0xb605d019), new Word64(0x3956c25b, 0xf348b538), new Word64(0x59f111f1, 0xb605d019),
@ -523,7 +517,7 @@ var calculateSHA512 = (function calculateSHA512Closure() {
function hash(data, offset, length, mode384 = false) { function hash(data, offset, length, mode384 = false) {
// initial hash values // initial hash values
var h0, h1, h2, h3, h4, h5, h6, h7; let h0, h1, h2, h3, h4, h5, h6, h7;
if (!mode384) { if (!mode384) {
h0 = new Word64(0x6a09e667, 0xf3bcc908); h0 = new Word64(0x6a09e667, 0xf3bcc908);
h1 = new Word64(0xbb67ae85, 0x84caa73b); h1 = new Word64(0xbb67ae85, 0x84caa73b);
@ -547,14 +541,14 @@ var calculateSHA512 = (function calculateSHA512Closure() {
} }
// pre-processing // pre-processing
var paddedLength = Math.ceil((length + 17) / 128) * 128; const paddedLength = Math.ceil((length + 17) / 128) * 128;
var padded = new Uint8Array(paddedLength); const padded = new Uint8Array(paddedLength);
var i, j, n; let i, j;
for (i = 0; i < length; ++i) { for (i = 0; i < length; ++i) {
padded[i] = data[offset++]; padded[i] = data[offset++];
} }
padded[i++] = 0x80; padded[i++] = 0x80;
n = paddedLength - 16; const n = paddedLength - 16;
while (i < n) { while (i < n) {
padded[i++] = 0; padded[i++] = 0;
} }
@ -575,23 +569,23 @@ var calculateSHA512 = (function calculateSHA512Closure() {
padded[i++] = (length >> 5) & 0xff; padded[i++] = (length >> 5) & 0xff;
padded[i++] = (length << 3) & 0xff; padded[i++] = (length << 3) & 0xff;
var w = new Array(80); const w = new Array(80);
for (i = 0; i < 80; i++) { for (i = 0; i < 80; i++) {
w[i] = new Word64(0, 0); w[i] = new Word64(0, 0);
} }
var a = new Word64(0, 0), let a = new Word64(0, 0),
b = new Word64(0, 0), b = new Word64(0, 0),
c = new Word64(0, 0); c = new Word64(0, 0);
var d = new Word64(0, 0), let d = new Word64(0, 0),
e = new Word64(0, 0), e = new Word64(0, 0),
f = new Word64(0, 0); f = new Word64(0, 0);
var g = new Word64(0, 0), let g = new Word64(0, 0),
h = new Word64(0, 0); h = new Word64(0, 0);
var t1 = new Word64(0, 0), const t1 = new Word64(0, 0),
t2 = new Word64(0, 0); t2 = new Word64(0, 0);
var tmp1 = new Word64(0, 0), const tmp1 = new Word64(0, 0),
tmp2 = new Word64(0, 0), tmp2 = new Word64(0, 0);
tmp3; let tmp3;
// for each 1024 bit block // for each 1024 bit block
for (i = 0; i < paddedLength; ) { for (i = 0; i < paddedLength; ) {
@ -661,7 +655,7 @@ var calculateSHA512 = (function calculateSHA512Closure() {
h7.add(h); h7.add(h);
} }
var result; let result;
if (!mode384) { if (!mode384) {
result = new Uint8Array(64); result = new Uint8Array(64);
h0.copyTo(result, 0); h0.copyTo(result, 0);
@ -1255,49 +1249,49 @@ class AES256Cipher extends AESBaseCipher {
class PDF17 { class PDF17 {
checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) { checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) {
var hashData = new Uint8Array(password.length + 56); const hashData = new Uint8Array(password.length + 56);
hashData.set(password, 0); hashData.set(password, 0);
hashData.set(ownerValidationSalt, password.length); hashData.set(ownerValidationSalt, password.length);
hashData.set(userBytes, password.length + ownerValidationSalt.length); hashData.set(userBytes, password.length + ownerValidationSalt.length);
var result = calculateSHA256(hashData, 0, hashData.length); const result = calculateSHA256(hashData, 0, hashData.length);
return isArrayEqual(result, ownerPassword); return isArrayEqual(result, ownerPassword);
} }
checkUserPassword(password, userValidationSalt, userPassword) { checkUserPassword(password, userValidationSalt, userPassword) {
var hashData = new Uint8Array(password.length + 8); const hashData = new Uint8Array(password.length + 8);
hashData.set(password, 0); hashData.set(password, 0);
hashData.set(userValidationSalt, password.length); hashData.set(userValidationSalt, password.length);
var result = calculateSHA256(hashData, 0, hashData.length); const result = calculateSHA256(hashData, 0, hashData.length);
return isArrayEqual(result, userPassword); return isArrayEqual(result, userPassword);
} }
getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) { getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) {
var hashData = new Uint8Array(password.length + 56); const hashData = new Uint8Array(password.length + 56);
hashData.set(password, 0); hashData.set(password, 0);
hashData.set(ownerKeySalt, password.length); hashData.set(ownerKeySalt, password.length);
hashData.set(userBytes, password.length + ownerKeySalt.length); hashData.set(userBytes, password.length + ownerKeySalt.length);
var key = calculateSHA256(hashData, 0, hashData.length); const key = calculateSHA256(hashData, 0, hashData.length);
var cipher = new AES256Cipher(key); const cipher = new AES256Cipher(key);
return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16)); return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));
} }
getUserKey(password, userKeySalt, userEncryption) { getUserKey(password, userKeySalt, userEncryption) {
var hashData = new Uint8Array(password.length + 8); const hashData = new Uint8Array(password.length + 8);
hashData.set(password, 0); hashData.set(password, 0);
hashData.set(userKeySalt, password.length); hashData.set(userKeySalt, password.length);
// `key` is the decryption key for the UE string. // `key` is the decryption key for the UE string.
var key = calculateSHA256(hashData, 0, hashData.length); const key = calculateSHA256(hashData, 0, hashData.length);
var cipher = new AES256Cipher(key); const cipher = new AES256Cipher(key);
return cipher.decryptBlock(userEncryption, false, new Uint8Array(16)); return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));
} }
} }
var PDF20 = (function PDF20Closure() { const PDF20 = (function PDF20Closure() {
function calculatePDF20Hash(password, input, userBytes) { function calculatePDF20Hash(password, input, userBytes) {
// This refers to Algorithm 2.B as defined in ISO 32000-2. // This refers to Algorithm 2.B as defined in ISO 32000-2.
var k = calculateSHA256(input, 0, input.length).subarray(0, 32); let k = calculateSHA256(input, 0, input.length).subarray(0, 32);
var e = [0]; let e = [0];
var i = 0; let i = 0;
while (i < 64 || e[e.length - 1] > i - 32) { while (i < 64 || e[e.length - 1] > i - 32) {
const combinedLength = password.length + k.length + userBytes.length, const combinedLength = password.length + k.length + userBytes.length,
combinedArray = new Uint8Array(combinedLength); combinedArray = new Uint8Array(combinedLength);
@ -1308,20 +1302,20 @@ var PDF20 = (function PDF20Closure() {
writeOffset += k.length; writeOffset += k.length;
combinedArray.set(userBytes, writeOffset); combinedArray.set(userBytes, writeOffset);
var k1 = new Uint8Array(combinedLength * 64); const k1 = new Uint8Array(combinedLength * 64);
for (var j = 0, pos = 0; j < 64; j++, pos += combinedLength) { for (let j = 0, pos = 0; j < 64; j++, pos += combinedLength) {
k1.set(combinedArray, pos); k1.set(combinedArray, pos);
} }
// AES128 CBC NO PADDING with first 16 bytes of k as the key // AES128 CBC NO PADDING with first 16 bytes of k as the key
// and the second 16 as the iv. // and the second 16 as the iv.
var cipher = new AES128Cipher(k.subarray(0, 16)); const cipher = new AES128Cipher(k.subarray(0, 16));
e = cipher.encrypt(k1, k.subarray(16, 32)); e = cipher.encrypt(k1, k.subarray(16, 32));
// Now we have to take the first 16 bytes of an unsigned big endian // Now we have to take the first 16 bytes of an unsigned big endian
// integer and compute the remainder modulo 3. That is a fairly large // integer and compute the remainder modulo 3. That is a fairly large
// number and JavaScript isn't going to handle that well, so we're using // number and JavaScript isn't going to handle that well, so we're using
// a trick that allows us to perform modulo math byte by byte. // a trick that allows us to perform modulo math byte by byte.
var remainder = 0; let remainder = 0;
for (var z = 0; z < 16; z++) { for (let z = 0; z < 16; z++) {
remainder *= 256 % 3; remainder *= 256 % 3;
remainder %= 3; remainder %= 3;
remainder += (e[z] >>> 0) % 3; remainder += (e[z] >>> 0) % 3;
@ -1351,39 +1345,39 @@ var PDF20 = (function PDF20Closure() {
userBytes, userBytes,
ownerPassword ownerPassword
) { ) {
var hashData = new Uint8Array(password.length + 56); const hashData = new Uint8Array(password.length + 56);
hashData.set(password, 0); hashData.set(password, 0);
hashData.set(ownerValidationSalt, password.length); hashData.set(ownerValidationSalt, password.length);
hashData.set(userBytes, password.length + ownerValidationSalt.length); hashData.set(userBytes, password.length + ownerValidationSalt.length);
var result = calculatePDF20Hash(password, hashData, userBytes); const result = calculatePDF20Hash(password, hashData, userBytes);
return isArrayEqual(result, ownerPassword); return isArrayEqual(result, ownerPassword);
} }
checkUserPassword(password, userValidationSalt, userPassword) { checkUserPassword(password, userValidationSalt, userPassword) {
var hashData = new Uint8Array(password.length + 8); const hashData = new Uint8Array(password.length + 8);
hashData.set(password, 0); hashData.set(password, 0);
hashData.set(userValidationSalt, password.length); hashData.set(userValidationSalt, password.length);
var result = calculatePDF20Hash(password, hashData, []); const result = calculatePDF20Hash(password, hashData, []);
return isArrayEqual(result, userPassword); return isArrayEqual(result, userPassword);
} }
getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) { getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) {
var hashData = new Uint8Array(password.length + 56); const hashData = new Uint8Array(password.length + 56);
hashData.set(password, 0); hashData.set(password, 0);
hashData.set(ownerKeySalt, password.length); hashData.set(ownerKeySalt, password.length);
hashData.set(userBytes, password.length + ownerKeySalt.length); hashData.set(userBytes, password.length + ownerKeySalt.length);
var key = calculatePDF20Hash(password, hashData, userBytes); const key = calculatePDF20Hash(password, hashData, userBytes);
var cipher = new AES256Cipher(key); const cipher = new AES256Cipher(key);
return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16)); return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));
} }
getUserKey(password, userKeySalt, userEncryption) { getUserKey(password, userKeySalt, userEncryption) {
var hashData = new Uint8Array(password.length + 8); const hashData = new Uint8Array(password.length + 8);
hashData.set(password, 0); hashData.set(password, 0);
hashData.set(userKeySalt, password.length); hashData.set(userKeySalt, password.length);
// `key` is the decryption key for the UE string. // `key` is the decryption key for the UE string.
var key = calculatePDF20Hash(password, hashData, []); const key = calculatePDF20Hash(password, hashData, []);
var cipher = new AES256Cipher(key); const cipher = new AES256Cipher(key);
return cipher.decryptBlock(userEncryption, false, new Uint8Array(16)); return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));
} }
} }
@ -1398,7 +1392,7 @@ class CipherTransform {
} }
createStream(stream, length) { createStream(stream, length) {
var cipher = new this.StreamCipherConstructor(); const cipher = new this.StreamCipherConstructor();
return new DecryptStream( return new DecryptStream(
stream, stream,
length, length,
@ -1409,8 +1403,8 @@ class CipherTransform {
} }
decryptString(s) { decryptString(s) {
var cipher = new this.StringCipherConstructor(); const cipher = new this.StringCipherConstructor();
var data = stringToBytes(s); let data = stringToBytes(s);
data = cipher.decryptBlock(data, true); data = cipher.decryptBlock(data, true);
return bytesToString(data); return bytesToString(data);
} }
@ -1453,9 +1447,9 @@ class CipherTransform {
} }
} }
var CipherTransformFactory = (function CipherTransformFactoryClosure() { const CipherTransformFactory = (function CipherTransformFactoryClosure() {
// prettier-ignore // prettier-ignore
var defaultPasswordBytes = new Uint8Array([ const defaultPasswordBytes = new Uint8Array([
0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41,
0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80,
@ -1476,12 +1470,12 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
perms perms
) { ) {
if (password) { if (password) {
var passwordLength = Math.min(127, password.length); const passwordLength = Math.min(127, password.length);
password = password.subarray(0, passwordLength); password = password.subarray(0, passwordLength);
} else { } else {
password = []; password = [];
} }
var pdfAlgorithm; let pdfAlgorithm;
if (revision === 6) { if (revision === 6) {
pdfAlgorithm = new PDF20(); pdfAlgorithm = new PDF20();
} else { } else {
@ -1522,9 +1516,9 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
keyLength, keyLength,
encryptMetadata encryptMetadata
) { ) {
var hashDataSize = 40 + ownerPassword.length + fileId.length; const hashDataSize = 40 + ownerPassword.length + fileId.length;
var hashData = new Uint8Array(hashDataSize), const hashData = new Uint8Array(hashDataSize);
i = 0, let i = 0,
j, j,
n; n;
if (password) { if (password) {
@ -1554,15 +1548,15 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
hashData[i++] = 0xff; hashData[i++] = 0xff;
hashData[i++] = 0xff; hashData[i++] = 0xff;
} }
var hash = calculateMD5(hashData, 0, i); let hash = calculateMD5(hashData, 0, i);
var keyLengthInBytes = keyLength >> 3; const keyLengthInBytes = keyLength >> 3;
if (revision >= 3) { if (revision >= 3) {
for (j = 0; j < 50; ++j) { for (j = 0; j < 50; ++j) {
hash = calculateMD5(hash, 0, keyLengthInBytes); hash = calculateMD5(hash, 0, keyLengthInBytes);
} }
} }
var encryptionKey = hash.subarray(0, keyLengthInBytes); const encryptionKey = hash.subarray(0, keyLengthInBytes);
var cipher, checkData; let cipher, checkData;
if (revision >= 3) { if (revision >= 3) {
for (i = 0; i < 32; ++i) { for (i = 0; i < 32; ++i) {
@ -1574,10 +1568,9 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
cipher = new ARCFourCipher(encryptionKey); cipher = new ARCFourCipher(encryptionKey);
checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i)); checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i));
n = encryptionKey.length; n = encryptionKey.length;
var derivedKey = new Uint8Array(n), const derivedKey = new Uint8Array(n);
k;
for (j = 1; j <= 19; ++j) { for (j = 1; j <= 19; ++j) {
for (k = 0; k < n; ++k) { for (let k = 0; k < n; ++k) {
derivedKey[k] = encryptionKey[k] ^ j; derivedKey[k] = encryptionKey[k] ^ j;
} }
cipher = new ARCFourCipher(derivedKey); cipher = new ARCFourCipher(derivedKey);
@ -1601,33 +1594,30 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
} }
function decodeUserPassword(password, ownerPassword, revision, keyLength) { function decodeUserPassword(password, ownerPassword, revision, keyLength) {
var hashData = new Uint8Array(32), const hashData = new Uint8Array(32);
i = 0, let i = 0;
j, const n = Math.min(32, password.length);
n;
n = Math.min(32, password.length);
for (; i < n; ++i) { for (; i < n; ++i) {
hashData[i] = password[i]; hashData[i] = password[i];
} }
j = 0; let j = 0;
while (i < 32) { while (i < 32) {
hashData[i++] = defaultPasswordBytes[j++]; hashData[i++] = defaultPasswordBytes[j++];
} }
var hash = calculateMD5(hashData, 0, i); let hash = calculateMD5(hashData, 0, i);
var keyLengthInBytes = keyLength >> 3; const keyLengthInBytes = keyLength >> 3;
if (revision >= 3) { if (revision >= 3) {
for (j = 0; j < 50; ++j) { for (j = 0; j < 50; ++j) {
hash = calculateMD5(hash, 0, hash.length); hash = calculateMD5(hash, 0, hash.length);
} }
} }
var cipher, userPassword; let cipher, userPassword;
if (revision >= 3) { if (revision >= 3) {
userPassword = ownerPassword; userPassword = ownerPassword;
var derivedKey = new Uint8Array(keyLengthInBytes), const derivedKey = new Uint8Array(keyLengthInBytes);
k;
for (j = 19; j >= 0; j--) { for (j = 19; j >= 0; j--) {
for (k = 0; k < keyLengthInBytes; ++k) { for (let k = 0; k < keyLengthInBytes; ++k) {
derivedKey[k] = hash[k] ^ j; derivedKey[k] = hash[k] ^ j;
} }
cipher = new ARCFourCipher(derivedKey); cipher = new ARCFourCipher(derivedKey);
@ -1640,13 +1630,13 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
return userPassword; return userPassword;
} }
var identityName = Name.get("Identity"); const identityName = Name.get("Identity");
function buildObjectKey(num, gen, encryptionKey, isAes = false) { function buildObjectKey(num, gen, encryptionKey, isAes = false) {
var key = new Uint8Array(encryptionKey.length + 9), const key = new Uint8Array(encryptionKey.length + 9);
i, const n = encryptionKey.length;
n; let i;
for (i = 0, n = encryptionKey.length; i < n; ++i) { for (i = 0; i < n; ++i) {
key[i] = encryptionKey[i]; key[i] = encryptionKey[i];
} }
key[i++] = num & 0xff; key[i++] = num & 0xff;
@ -1660,7 +1650,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
key[i++] = 0x6c; key[i++] = 0x6c;
key[i++] = 0x54; key[i++] = 0x54;
} }
var hash = calculateMD5(key, 0, i); const hash = calculateMD5(key, 0, i);
return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); return hash.subarray(0, Math.min(encryptionKey.length + 5, 16));
} }
@ -1668,8 +1658,8 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
if (!isName(name)) { if (!isName(name)) {
throw new FormatError("Invalid crypt filter name."); throw new FormatError("Invalid crypt filter name.");
} }
var cryptFilter = cf.get(name.name); const cryptFilter = cf.get(name.name);
var cfm; let cfm;
if (cryptFilter !== null && cryptFilter !== undefined) { if (cryptFilter !== null && cryptFilter !== undefined) {
cfm = cryptFilter.get("CFM"); cfm = cryptFilter.get("CFM");
} }
@ -1703,12 +1693,12 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
class CipherTransformFactory { class CipherTransformFactory {
constructor(dict, fileId, password) { constructor(dict, fileId, password) {
var filter = dict.get("Filter"); const filter = dict.get("Filter");
if (!isName(filter, "Standard")) { if (!isName(filter, "Standard")) {
throw new FormatError("unknown encryption method"); throw new FormatError("unknown encryption method");
} }
this.dict = dict; this.dict = dict;
var algorithm = dict.get("V"); const algorithm = dict.get("V");
if ( if (
!Number.isInteger(algorithm) || !Number.isInteger(algorithm) ||
(algorithm !== 1 && (algorithm !== 1 &&
@ -1719,7 +1709,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
throw new FormatError("unsupported encryption algorithm"); throw new FormatError("unsupported encryption algorithm");
} }
this.algorithm = algorithm; this.algorithm = algorithm;
var keyLength = dict.get("Length"); let keyLength = dict.get("Length");
if (!keyLength) { if (!keyLength) {
// Spec asks to rely on encryption dictionary's Length entry, however // Spec asks to rely on encryption dictionary's Length entry, however
// some PDFs don't have it. Trying to recover. // some PDFs don't have it. Trying to recover.
@ -1728,11 +1718,11 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
keyLength = 40; keyLength = 40;
} else { } else {
// Trying to find default handler -- it usually has Length. // Trying to find default handler -- it usually has Length.
var cfDict = dict.get("CF"); const cfDict = dict.get("CF");
var streamCryptoName = dict.get("StmF"); const streamCryptoName = dict.get("StmF");
if (isDict(cfDict) && isName(streamCryptoName)) { if (isDict(cfDict) && isName(streamCryptoName)) {
cfDict.suppressEncryption = true; // See comment below. cfDict.suppressEncryption = true; // See comment below.
var handlerDict = cfDict.get(streamCryptoName.name); const handlerDict = cfDict.get(streamCryptoName.name);
keyLength = (handlerDict && handlerDict.get("Length")) || 128; keyLength = (handlerDict && handlerDict.get("Length")) || 128;
if (keyLength < 40) { if (keyLength < 40) {
// Sometimes it's incorrect value of bits, generators specify // Sometimes it's incorrect value of bits, generators specify
@ -1751,18 +1741,18 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
} }
// prepare keys // prepare keys
var ownerPassword = stringToBytes(dict.get("O")).subarray(0, 32); const ownerPassword = stringToBytes(dict.get("O")).subarray(0, 32);
var userPassword = stringToBytes(dict.get("U")).subarray(0, 32); const userPassword = stringToBytes(dict.get("U")).subarray(0, 32);
var flags = dict.get("P"); const flags = dict.get("P");
var revision = dict.get("R"); const revision = dict.get("R");
// meaningful when V is 4 or 5 // meaningful when V is 4 or 5
var encryptMetadata = const encryptMetadata =
(algorithm === 4 || algorithm === 5) && (algorithm === 4 || algorithm === 5) &&
dict.get("EncryptMetadata") !== false; dict.get("EncryptMetadata") !== false;
this.encryptMetadata = encryptMetadata; this.encryptMetadata = encryptMetadata;
var fileIdBytes = stringToBytes(fileId); const fileIdBytes = stringToBytes(fileId);
var passwordBytes; let passwordBytes;
if (password) { if (password) {
if (revision === 6) { if (revision === 6) {
try { try {
@ -1777,7 +1767,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
passwordBytes = stringToBytes(password); passwordBytes = stringToBytes(password);
} }
var encryptionKey; let encryptionKey;
if (algorithm !== 5) { if (algorithm !== 5) {
encryptionKey = prepareKeyData( encryptionKey = prepareKeyData(
fileIdBytes, fileIdBytes,
@ -1790,14 +1780,20 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
encryptMetadata encryptMetadata
); );
} else { } else {
var ownerValidationSalt = stringToBytes(dict.get("O")).subarray(32, 40); const ownerValidationSalt = stringToBytes(dict.get("O")).subarray(
var ownerKeySalt = stringToBytes(dict.get("O")).subarray(40, 48); 32,
var uBytes = stringToBytes(dict.get("U")).subarray(0, 48); 40
var userValidationSalt = stringToBytes(dict.get("U")).subarray(32, 40); );
var userKeySalt = stringToBytes(dict.get("U")).subarray(40, 48); const ownerKeySalt = stringToBytes(dict.get("O")).subarray(40, 48);
var ownerEncryption = stringToBytes(dict.get("OE")); const uBytes = stringToBytes(dict.get("U")).subarray(0, 48);
var userEncryption = stringToBytes(dict.get("UE")); const userValidationSalt = stringToBytes(dict.get("U")).subarray(
var perms = stringToBytes(dict.get("Perms")); 32,
40
);
const userKeySalt = stringToBytes(dict.get("U")).subarray(40, 48);
const ownerEncryption = stringToBytes(dict.get("OE"));
const userEncryption = stringToBytes(dict.get("UE"));
const perms = stringToBytes(dict.get("Perms"));
encryptionKey = createEncryptionKey20( encryptionKey = createEncryptionKey20(
revision, revision,
passwordBytes, passwordBytes,
@ -1820,7 +1816,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
); );
} else if (!encryptionKey && password) { } else if (!encryptionKey && password) {
// Attempting use the password as an owner password // Attempting use the password as an owner password
var decodedPassword = decodeUserPassword( const decodedPassword = decodeUserPassword(
passwordBytes, passwordBytes,
ownerPassword, ownerPassword,
revision, revision,
@ -1848,7 +1844,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
this.encryptionKey = encryptionKey; this.encryptionKey = encryptionKey;
if (algorithm >= 4) { if (algorithm >= 4) {
var cf = dict.get("CF"); const cf = dict.get("CF");
if (isDict(cf)) { if (isDict(cf)) {
// The 'CF' dictionary itself should not be encrypted, and by setting // The 'CF' dictionary itself should not be encrypted, and by setting
// `suppressEncryption` we can prevent an infinite loop inside of // `suppressEncryption` we can prevent an infinite loop inside of
@ -1883,13 +1879,13 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
); );
} }
// algorithms 1 and 2 // algorithms 1 and 2
var key = buildObjectKey( const key = buildObjectKey(
num, num,
gen, gen,
this.encryptionKey, this.encryptionKey,
/* isAes = */ false /* isAes = */ false
); );
var cipherConstructor = function buildCipherCipherConstructor() { const cipherConstructor = function buildCipherCipherConstructor() {
return new ARCFourCipher(key); return new ARCFourCipher(key);
}; };
return new CipherTransform(cipherConstructor, cipherConstructor); return new CipherTransform(cipherConstructor, cipherConstructor);

View File

@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* eslint-disable no-var */
import { Dict, isDict, isStream, Ref } from "./primitives.js"; import { Dict, isDict, isStream, Ref } from "./primitives.js";
import { import {
@ -132,7 +131,7 @@ function toNumberArray(arr) {
return arr; return arr;
} }
var PDFFunction = (function PDFFunctionClosure() { const PDFFunction = (function PDFFunctionClosure() {
const CONSTRUCT_SAMPLED = 0; const CONSTRUCT_SAMPLED = 0;
const CONSTRUCT_INTERPOLATED = 2; const CONSTRUCT_INTERPOLATED = 2;
const CONSTRUCT_STICHED = 3; const CONSTRUCT_STICHED = 3;
@ -140,21 +139,21 @@ var PDFFunction = (function PDFFunctionClosure() {
return { return {
getSampleArray(size, outputSize, bps, stream) { getSampleArray(size, outputSize, bps, stream) {
var i, ii; let i, ii;
var length = 1; let length = 1;
for (i = 0, ii = size.length; i < ii; i++) { for (i = 0, ii = size.length; i < ii; i++) {
length *= size[i]; length *= size[i];
} }
length *= outputSize; length *= outputSize;
var array = new Array(length); const array = new Array(length);
var codeSize = 0; let codeSize = 0;
var codeBuf = 0; let codeBuf = 0;
// 32 is a valid bps so shifting won't work // 32 is a valid bps so shifting won't work
var sampleMul = 1.0 / (2.0 ** bps - 1); const sampleMul = 1.0 / (2.0 ** bps - 1);
var strBytes = stream.getBytes((length * bps + 7) / 8); const strBytes = stream.getBytes((length * bps + 7) / 8);
var strIdx = 0; let strIdx = 0;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
while (codeSize < bps) { while (codeSize < bps) {
codeBuf <<= 8; codeBuf <<= 8;
@ -169,12 +168,12 @@ var PDFFunction = (function PDFFunctionClosure() {
}, },
getIR({ xref, isEvalSupported, fn }) { getIR({ xref, isEvalSupported, fn }) {
var dict = fn.dict; let dict = fn.dict;
if (!dict) { if (!dict) {
dict = fn; dict = fn;
} }
var types = [ const types = [
this.constructSampled, this.constructSampled,
null, null,
this.constructInterpolated, this.constructInterpolated,
@ -182,8 +181,8 @@ var PDFFunction = (function PDFFunctionClosure() {
this.constructPostScript, this.constructPostScript,
]; ];
var typeNum = dict.get("FunctionType"); const typeNum = dict.get("FunctionType");
var typeFn = types[typeNum]; const typeFn = types[typeNum];
if (!typeFn) { if (!typeFn) {
throw new FormatError("Unknown type of function"); throw new FormatError("Unknown type of function");
} }
@ -192,7 +191,7 @@ var PDFFunction = (function PDFFunctionClosure() {
}, },
fromIR({ xref, isEvalSupported, IR }) { fromIR({ xref, isEvalSupported, IR }) {
var type = IR[0]; const type = IR[0];
switch (type) { switch (type) {
case CONSTRUCT_SAMPLED: case CONSTRUCT_SAMPLED:
return this.constructSampledFromIR({ xref, isEvalSupported, IR }); return this.constructSampledFromIR({ xref, isEvalSupported, IR });
@ -221,14 +220,14 @@ var PDFFunction = (function PDFFunctionClosure() {
return this.parse({ xref, isEvalSupported, fn: fnObj }); return this.parse({ xref, isEvalSupported, fn: fnObj });
} }
var fnArray = []; const fnArray = [];
for (var j = 0, jj = fnObj.length; j < jj; j++) { for (let j = 0, jj = fnObj.length; j < jj; j++) {
fnArray.push( fnArray.push(
this.parse({ xref, isEvalSupported, fn: xref.fetchIfRef(fnObj[j]) }) this.parse({ xref, isEvalSupported, fn: xref.fetchIfRef(fnObj[j]) })
); );
} }
return function (src, srcOffset, dest, destOffset) { return function (src, srcOffset, dest, destOffset) {
for (var i = 0, ii = fnArray.length; i < ii; i++) { for (let i = 0, ii = fnArray.length; i < ii; i++) {
fnArray[i](src, srcOffset, dest, destOffset + i); fnArray[i](src, srcOffset, dest, destOffset + i);
} }
}; };
@ -236,55 +235,55 @@ var PDFFunction = (function PDFFunctionClosure() {
constructSampled({ xref, isEvalSupported, fn, dict }) { constructSampled({ xref, isEvalSupported, fn, dict }) {
function toMultiArray(arr) { function toMultiArray(arr) {
var inputLength = arr.length; const inputLength = arr.length;
var out = []; const out = [];
var index = 0; let index = 0;
for (var i = 0; i < inputLength; i += 2) { for (let i = 0; i < inputLength; i += 2) {
out[index] = [arr[i], arr[i + 1]]; out[index] = [arr[i], arr[i + 1]];
++index; ++index;
} }
return out; return out;
} }
var domain = toNumberArray(dict.getArray("Domain")); let domain = toNumberArray(dict.getArray("Domain"));
var range = toNumberArray(dict.getArray("Range")); let range = toNumberArray(dict.getArray("Range"));
if (!domain || !range) { if (!domain || !range) {
throw new FormatError("No domain or range"); throw new FormatError("No domain or range");
} }
var inputSize = domain.length / 2; const inputSize = domain.length / 2;
var outputSize = range.length / 2; const outputSize = range.length / 2;
domain = toMultiArray(domain); domain = toMultiArray(domain);
range = toMultiArray(range); range = toMultiArray(range);
var size = toNumberArray(dict.getArray("Size")); const size = toNumberArray(dict.getArray("Size"));
var bps = dict.get("BitsPerSample"); const bps = dict.get("BitsPerSample");
var order = dict.get("Order") || 1; const order = dict.get("Order") || 1;
if (order !== 1) { if (order !== 1) {
// No description how cubic spline interpolation works in PDF32000:2008 // No description how cubic spline interpolation works in PDF32000:2008
// As in poppler, ignoring order, linear interpolation may work as good // As in poppler, ignoring order, linear interpolation may work as good
info("No support for cubic spline interpolation: " + order); info("No support for cubic spline interpolation: " + order);
} }
var encode = toNumberArray(dict.getArray("Encode")); let encode = toNumberArray(dict.getArray("Encode"));
if (!encode) { if (!encode) {
encode = []; encode = [];
for (var i = 0; i < inputSize; ++i) { for (let i = 0; i < inputSize; ++i) {
encode.push([0, size[i] - 1]); encode.push([0, size[i] - 1]);
} }
} else { } else {
encode = toMultiArray(encode); encode = toMultiArray(encode);
} }
var decode = toNumberArray(dict.getArray("Decode")); let decode = toNumberArray(dict.getArray("Decode"));
if (!decode) { if (!decode) {
decode = range; decode = range;
} else { } else {
decode = toMultiArray(decode); decode = toMultiArray(decode);
} }
var samples = this.getSampleArray(size, outputSize, bps, fn); const samples = this.getSampleArray(size, outputSize, bps, fn);
return [ return [
CONSTRUCT_SAMPLED, CONSTRUCT_SAMPLED,
@ -313,41 +312,41 @@ var PDFFunction = (function PDFFunctionClosure() {
destOffset destOffset
) { ) {
// See chapter 3, page 110 of the PDF reference. // See chapter 3, page 110 of the PDF reference.
var m = IR[1]; const m = IR[1];
var domain = IR[2]; const domain = IR[2];
var encode = IR[3]; const encode = IR[3];
var decode = IR[4]; const decode = IR[4];
var samples = IR[5]; const samples = IR[5];
var size = IR[6]; const size = IR[6];
var n = IR[7]; const n = IR[7];
// var mask = IR[8]; // var mask = IR[8];
var range = IR[9]; const range = IR[9];
// Building the cube vertices: its part and sample index // Building the cube vertices: its part and sample index
// http://rjwagner49.com/Mathematics/Interpolation.pdf // http://rjwagner49.com/Mathematics/Interpolation.pdf
var cubeVertices = 1 << m; const cubeVertices = 1 << m;
var cubeN = new Float64Array(cubeVertices); const cubeN = new Float64Array(cubeVertices);
var cubeVertex = new Uint32Array(cubeVertices); const cubeVertex = new Uint32Array(cubeVertices);
var i, j; let i, j;
for (j = 0; j < cubeVertices; j++) { for (j = 0; j < cubeVertices; j++) {
cubeN[j] = 1; cubeN[j] = 1;
} }
var k = n, let k = n,
pos = 1; pos = 1;
// Map x_i to y_j for 0 <= i < m using the sampled function. // Map x_i to y_j for 0 <= i < m using the sampled function.
for (i = 0; i < m; ++i) { for (i = 0; i < m; ++i) {
// x_i' = min(max(x_i, Domain_2i), Domain_2i+1) // x_i' = min(max(x_i, Domain_2i), Domain_2i+1)
var domain_2i = domain[i][0]; const domain_2i = domain[i][0];
var domain_2i_1 = domain[i][1]; const domain_2i_1 = domain[i][1];
var xi = Math.min( const xi = Math.min(
Math.max(src[srcOffset + i], domain_2i), Math.max(src[srcOffset + i], domain_2i),
domain_2i_1 domain_2i_1
); );
// e_i = Interpolate(x_i', Domain_2i, Domain_2i+1, // e_i = Interpolate(x_i', Domain_2i, Domain_2i+1,
// Encode_2i, Encode_2i+1) // Encode_2i, Encode_2i+1)
var e = interpolate( let e = interpolate(
xi, xi,
domain_2i, domain_2i,
domain_2i_1, domain_2i_1,
@ -356,15 +355,15 @@ var PDFFunction = (function PDFFunctionClosure() {
); );
// e_i' = min(max(e_i, 0), Size_i - 1) // e_i' = min(max(e_i, 0), Size_i - 1)
var size_i = size[i]; const size_i = size[i];
e = Math.min(Math.max(e, 0), size_i - 1); e = Math.min(Math.max(e, 0), size_i - 1);
// Adjusting the cube: N and vertex sample index // Adjusting the cube: N and vertex sample index
var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1; const e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1;
var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0); const n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0);
var n1 = e - e0; // (e - e0) / (e1 - e0); const n1 = e - e0; // (e - e0) / (e1 - e0);
var offset0 = e0 * k; const offset0 = e0 * k;
var offset1 = offset0 + k; // e1 * k const offset1 = offset0 + k; // e1 * k
for (j = 0; j < cubeVertices; j++) { for (j = 0; j < cubeVertices; j++) {
if (j & pos) { if (j & pos) {
cubeN[j] *= n1; cubeN[j] *= n1;
@ -381,7 +380,7 @@ var PDFFunction = (function PDFFunctionClosure() {
for (j = 0; j < n; ++j) { for (j = 0; j < n; ++j) {
// Sum all cube vertices' samples portions // Sum all cube vertices' samples portions
var rj = 0; let rj = 0;
for (i = 0; i < cubeVertices; i++) { for (i = 0; i < cubeVertices; i++) {
rj += samples[cubeVertex[i] + j] * cubeN[i]; rj += samples[cubeVertex[i] + j] * cubeN[i];
} }
@ -400,13 +399,13 @@ var PDFFunction = (function PDFFunctionClosure() {
}, },
constructInterpolated({ xref, isEvalSupported, fn, dict }) { constructInterpolated({ xref, isEvalSupported, fn, dict }) {
var c0 = toNumberArray(dict.getArray("C0")) || [0]; const c0 = toNumberArray(dict.getArray("C0")) || [0];
var c1 = toNumberArray(dict.getArray("C1")) || [1]; const c1 = toNumberArray(dict.getArray("C1")) || [1];
var n = dict.get("N"); const n = dict.get("N");
var length = c0.length; const length = c0.length;
var diff = []; const diff = [];
for (var i = 0; i < length; ++i) { for (let i = 0; i < length; ++i) {
diff.push(c1[i] - c0[i]); diff.push(c1[i] - c0[i]);
} }
@ -414,11 +413,11 @@ var PDFFunction = (function PDFFunctionClosure() {
}, },
constructInterpolatedFromIR({ xref, isEvalSupported, IR }) { constructInterpolatedFromIR({ xref, isEvalSupported, IR }) {
var c0 = IR[1]; const c0 = IR[1];
var diff = IR[2]; const diff = IR[2];
var n = IR[3]; const n = IR[3];
var length = diff.length; const length = diff.length;
return function constructInterpolatedFromIRResult( return function constructInterpolatedFromIRResult(
src, src,
@ -426,46 +425,46 @@ var PDFFunction = (function PDFFunctionClosure() {
dest, dest,
destOffset destOffset
) { ) {
var x = n === 1 ? src[srcOffset] : src[srcOffset] ** n; const x = n === 1 ? src[srcOffset] : src[srcOffset] ** n;
for (var j = 0; j < length; ++j) { for (let j = 0; j < length; ++j) {
dest[destOffset + j] = c0[j] + x * diff[j]; dest[destOffset + j] = c0[j] + x * diff[j];
} }
}; };
}, },
constructStiched({ xref, isEvalSupported, fn, dict }) { constructStiched({ xref, isEvalSupported, fn, dict }) {
var domain = toNumberArray(dict.getArray("Domain")); const domain = toNumberArray(dict.getArray("Domain"));
if (!domain) { if (!domain) {
throw new FormatError("No domain"); throw new FormatError("No domain");
} }
var inputSize = domain.length / 2; const inputSize = domain.length / 2;
if (inputSize !== 1) { if (inputSize !== 1) {
throw new FormatError("Bad domain for stiched function"); throw new FormatError("Bad domain for stiched function");
} }
var fnRefs = dict.get("Functions"); const fnRefs = dict.get("Functions");
var fns = []; const fns = [];
for (var i = 0, ii = fnRefs.length; i < ii; ++i) { for (let i = 0, ii = fnRefs.length; i < ii; ++i) {
fns.push( fns.push(
this.parse({ xref, isEvalSupported, fn: xref.fetchIfRef(fnRefs[i]) }) this.parse({ xref, isEvalSupported, fn: xref.fetchIfRef(fnRefs[i]) })
); );
} }
var bounds = toNumberArray(dict.getArray("Bounds")); const bounds = toNumberArray(dict.getArray("Bounds"));
var encode = toNumberArray(dict.getArray("Encode")); const encode = toNumberArray(dict.getArray("Encode"));
return [CONSTRUCT_STICHED, domain, bounds, encode, fns]; return [CONSTRUCT_STICHED, domain, bounds, encode, fns];
}, },
constructStichedFromIR({ xref, isEvalSupported, IR }) { constructStichedFromIR({ xref, isEvalSupported, IR }) {
var domain = IR[1]; const domain = IR[1];
var bounds = IR[2]; const bounds = IR[2];
var encode = IR[3]; const encode = IR[3];
var fns = IR[4]; const fns = IR[4];
var tmpBuf = new Float32Array(1); const tmpBuf = new Float32Array(1);
return function constructStichedFromIRResult( return function constructStichedFromIRResult(
src, src,
@ -473,7 +472,7 @@ var PDFFunction = (function PDFFunctionClosure() {
dest, dest,
destOffset destOffset
) { ) {
var clip = function constructStichedFromIRClip(v, min, max) { const clip = function constructStichedFromIRClip(v, min, max) {
if (v > max) { if (v > max) {
v = max; v = max;
} else if (v < min) { } else if (v < min) {
@ -483,26 +482,28 @@ var PDFFunction = (function PDFFunctionClosure() {
}; };
// clip to domain // clip to domain
var v = clip(src[srcOffset], domain[0], domain[1]); const v = clip(src[srcOffset], domain[0], domain[1]);
// calculate which bound the value is in // calculate which bound the value is in
for (var i = 0, ii = bounds.length; i < ii; ++i) { const length = bounds.length;
let i;
for (i = 0; i < length; ++i) {
if (v < bounds[i]) { if (v < bounds[i]) {
break; break;
} }
} }
// encode value into domain of function // encode value into domain of function
var dmin = domain[0]; let dmin = domain[0];
if (i > 0) { if (i > 0) {
dmin = bounds[i - 1]; dmin = bounds[i - 1];
} }
var dmax = domain[1]; let dmax = domain[1];
if (i < bounds.length) { if (i < bounds.length) {
dmax = bounds[i]; dmax = bounds[i];
} }
var rmin = encode[2 * i]; const rmin = encode[2 * i];
var rmax = encode[2 * i + 1]; const rmax = encode[2 * i + 1];
// Prevent the value from becoming NaN as a result // Prevent the value from becoming NaN as a result
// of division by zero (fixes issue6113.pdf). // of division by zero (fixes issue6113.pdf).
@ -517,8 +518,8 @@ var PDFFunction = (function PDFFunctionClosure() {
}, },
constructPostScript({ xref, isEvalSupported, fn, dict }) { constructPostScript({ xref, isEvalSupported, fn, dict }) {
var domain = toNumberArray(dict.getArray("Domain")); const domain = toNumberArray(dict.getArray("Domain"));
var range = toNumberArray(dict.getArray("Range")); const range = toNumberArray(dict.getArray("Range"));
if (!domain) { if (!domain) {
throw new FormatError("No domain."); throw new FormatError("No domain.");
@ -528,17 +529,17 @@ var PDFFunction = (function PDFFunctionClosure() {
throw new FormatError("No range."); throw new FormatError("No range.");
} }
var lexer = new PostScriptLexer(fn); const lexer = new PostScriptLexer(fn);
var parser = new PostScriptParser(lexer); const parser = new PostScriptParser(lexer);
var code = parser.parse(); const code = parser.parse();
return [CONSTRUCT_POSTSCRIPT, domain, range, code]; return [CONSTRUCT_POSTSCRIPT, domain, range, code];
}, },
constructPostScriptFromIR({ xref, isEvalSupported, IR }) { constructPostScriptFromIR({ xref, isEvalSupported, IR }) {
var domain = IR[1]; const domain = IR[1];
var range = IR[2]; const range = IR[2];
var code = IR[3]; const code = IR[3];
if (isEvalSupported && IsEvalSupportedCached.value) { if (isEvalSupported && IsEvalSupportedCached.value) {
const compiled = new PostScriptCompiler().compile(code, domain, range); const compiled = new PostScriptCompiler().compile(code, domain, range);
@ -558,17 +559,17 @@ var PDFFunction = (function PDFFunctionClosure() {
} }
info("Unable to compile PS function"); info("Unable to compile PS function");
var numOutputs = range.length >> 1; const numOutputs = range.length >> 1;
var numInputs = domain.length >> 1; const numInputs = domain.length >> 1;
var evaluator = new PostScriptEvaluator(code); const evaluator = new PostScriptEvaluator(code);
// Cache the values for a big speed up, the cache size is limited though // Cache the values for a big speed up, the cache size is limited though
// since the number of possible values can be huge from a PS function. // since the number of possible values can be huge from a PS function.
var cache = Object.create(null); const cache = Object.create(null);
// The MAX_CACHE_SIZE is set to ~4x the maximum number of distinct values // The MAX_CACHE_SIZE is set to ~4x the maximum number of distinct values
// seen in our tests. // seen in our tests.
var MAX_CACHE_SIZE = 2048 * 4; const MAX_CACHE_SIZE = 2048 * 4;
var cache_available = MAX_CACHE_SIZE; let cache_available = MAX_CACHE_SIZE;
var tmpBuf = new Float32Array(numInputs); const tmpBuf = new Float32Array(numInputs);
return function constructPostScriptFromIRResult( return function constructPostScriptFromIRResult(
src, src,
@ -576,27 +577,27 @@ var PDFFunction = (function PDFFunctionClosure() {
dest, dest,
destOffset destOffset
) { ) {
var i, value; let i, value;
var key = ""; let key = "";
var input = tmpBuf; const input = tmpBuf;
for (i = 0; i < numInputs; i++) { for (i = 0; i < numInputs; i++) {
value = src[srcOffset + i]; value = src[srcOffset + i];
input[i] = value; input[i] = value;
key += value + "_"; key += value + "_";
} }
var cachedValue = cache[key]; const cachedValue = cache[key];
if (cachedValue !== undefined) { if (cachedValue !== undefined) {
dest.set(cachedValue, destOffset); dest.set(cachedValue, destOffset);
return; return;
} }
var output = new Float32Array(numOutputs); const output = new Float32Array(numOutputs);
var stack = evaluator.execute(input); const stack = evaluator.execute(input);
var stackIndex = stack.length - numOutputs; const stackIndex = stack.length - numOutputs;
for (i = 0; i < numOutputs; i++) { for (i = 0; i < numOutputs; i++) {
value = stack[stackIndex + i]; value = stack[stackIndex + i];
var bound = range[i * 2]; let bound = range[i * 2];
if (value < bound) { if (value < bound) {
value = bound; value = bound;
} else { } else {
@ -618,7 +619,7 @@ var PDFFunction = (function PDFFunctionClosure() {
})(); })();
function isPDFFunction(v) { function isPDFFunction(v) {
var fnDict; let fnDict;
if (typeof v !== "object") { if (typeof v !== "object") {
return false; return false;
} else if (isDict(v)) { } else if (isDict(v)) {
@ -631,8 +632,8 @@ function isPDFFunction(v) {
return fnDict.has("FunctionType"); return fnDict.has("FunctionType");
} }
var PostScriptStack = (function PostScriptStackClosure() { const PostScriptStack = (function PostScriptStackClosure() {
var MAX_STACK_SIZE = 100; const MAX_STACK_SIZE = 100;
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
class PostScriptStack { class PostScriptStack {
@ -660,8 +661,8 @@ var PostScriptStack = (function PostScriptStackClosure() {
if (this.stack.length + n >= MAX_STACK_SIZE) { if (this.stack.length + n >= MAX_STACK_SIZE) {
throw new Error("PostScript function stack overflow."); throw new Error("PostScript function stack overflow.");
} }
var stack = this.stack; const stack = this.stack;
for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++) { for (let i = stack.length - n, j = n - 1; j >= 0; j--, i++) {
stack.push(stack[i]); stack.push(stack[i]);
} }
} }
@ -672,25 +673,23 @@ var PostScriptStack = (function PostScriptStackClosure() {
// rotate the last n stack elements p times // rotate the last n stack elements p times
roll(n, p) { roll(n, p) {
var stack = this.stack; const stack = this.stack;
var l = stack.length - n; const l = stack.length - n;
var r = stack.length - 1, const r = stack.length - 1;
c = l + (p - Math.floor(p / n) * n), const c = l + (p - Math.floor(p / n) * n);
i,
j, for (let i = l, j = r; i < j; i++, j--) {
t; const t = stack[i];
for (i = l, j = r; i < j; i++, j--) {
t = stack[i];
stack[i] = stack[j]; stack[i] = stack[j];
stack[j] = t; stack[j] = t;
} }
for (i = l, j = c - 1; i < j; i++, j--) { for (let i = l, j = c - 1; i < j; i++, j--) {
t = stack[i]; const t = stack[i];
stack[i] = stack[j]; stack[i] = stack[j];
stack[j] = t; stack[j] = t;
} }
for (i = c, j = r; i < j; i++, j--) { for (let i = c, j = r; i < j; i++, j--) {
t = stack[i]; const t = stack[i];
stack[i] = stack[j]; stack[i] = stack[j];
stack[j] = t; stack[j] = t;
} }
@ -706,11 +705,11 @@ class PostScriptEvaluator {
} }
execute(initialStack) { execute(initialStack) {
var stack = new PostScriptStack(initialStack); const stack = new PostScriptStack(initialStack);
var counter = 0; let counter = 0;
var operators = this.operators; const operators = this.operators;
var length = operators.length; const length = operators.length;
var operator, a, b; let operator, a, b;
while (counter < length) { while (counter < length) {
operator = operators[counter++]; operator = operators[counter++];
if (typeof operator === "number") { if (typeof operator === "number") {
@ -940,7 +939,7 @@ class PostScriptEvaluator {
// We can compile most of such programs, and at the same moment, we can // We can compile most of such programs, and at the same moment, we can
// optimize some expressions using basic math properties. Keeping track of // optimize some expressions using basic math properties. Keeping track of
// min/max values will allow us to avoid extra Math.min/Math.max calls. // min/max values will allow us to avoid extra Math.min/Math.max calls.
var PostScriptCompiler = (function PostScriptCompilerClosure() { const PostScriptCompiler = (function PostScriptCompilerClosure() {
class AstNode { class AstNode {
constructor(type) { constructor(type) {
this.type = type; this.type = type;
@ -1124,13 +1123,13 @@ var PostScriptCompiler = (function PostScriptCompilerClosure() {
return num2; // and it's 1 return num2; // and it's 1
} }
} }
var min = Math.min( const min = Math.min(
num1.min * num2.min, num1.min * num2.min,
num1.min * num2.max, num1.min * num2.max,
num1.max * num2.min, num1.max * num2.min,
num1.max * num2.max num1.max * num2.max
); );
var max = Math.max( const max = Math.max(
num1.min * num2.min, num1.min * num2.min,
num1.min * num2.max, num1.min * num2.max,
num1.max * num2.min, num1.max * num2.min,
@ -1183,13 +1182,13 @@ var PostScriptCompiler = (function PostScriptCompilerClosure() {
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
class PostScriptCompiler { class PostScriptCompiler {
compile(code, domain, range) { compile(code, domain, range) {
var stack = []; const stack = [];
var instructions = []; const instructions = [];
var inputSize = domain.length >> 1, const inputSize = domain.length >> 1,
outputSize = range.length >> 1; outputSize = range.length >> 1;
var lastRegister = 0; let lastRegister = 0;
var n, j; let n, j;
var num1, num2, ast1, ast2, tmpVar, item; let num1, num2, ast1, ast2, tmpVar, item;
for (let i = 0; i < inputSize; i++) { for (let i = 0; i < inputSize; i++) {
stack.push(new AstArgument(i, domain[i * 2], domain[i * 2 + 1])); stack.push(new AstArgument(i, domain[i * 2], domain[i * 2 + 1]));
} }
@ -1336,7 +1335,7 @@ var PostScriptCompiler = (function PostScriptCompilerClosure() {
return null; return null;
} }
var result = []; const result = [];
for (const instruction of instructions) { for (const instruction of instructions) {
const statementBuilder = new ExpressionBuilderVisitor(); const statementBuilder = new ExpressionBuilderVisitor();
instruction.visit(statementBuilder); instruction.visit(statementBuilder);
@ -1346,9 +1345,9 @@ var PostScriptCompiler = (function PostScriptCompilerClosure() {
const expr = stack[i], const expr = stack[i],
statementBuilder = new ExpressionBuilderVisitor(); statementBuilder = new ExpressionBuilderVisitor();
expr.visit(statementBuilder); expr.visit(statementBuilder);
var min = range[i * 2], const min = range[i * 2],
max = range[i * 2 + 1]; max = range[i * 2 + 1];
var out = [statementBuilder.toString()]; const out = [statementBuilder.toString()];
if (min > expr.min) { if (min > expr.min) {
out.unshift("Math.max(", min, ", "); out.unshift("Math.max(", min, ", ");
out.push(")"); out.push(")");