@vaadin-component-factory/vcf-pdf-viewer 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/pdfjs/dist/display_utils.js +714 -714
- package/pdfjs/dist/fetch_stream.js +293 -293
- package/pdfjs/dist/l10n_utils.js +122 -122
- package/pdfjs/dist/message_handler.js +524 -524
- package/pdfjs/dist/network.js +552 -552
- package/pdfjs/dist/network_utils.js +309 -309
- package/pdfjs/dist/node_stream.js +481 -481
- package/pdfjs/dist/pdf_link_service.js +534 -534
- package/pdfjs/dist/pdf_rendering_queue.js +154 -154
- package/pdfjs/dist/pdf_thumbnail_viewer.js +738 -738
- package/pdfjs/dist/pdf_viewer.js +3207 -3207
- package/pdfjs/dist/ui_utils.js +881 -881
- package/pdfjs/dist/util.js +991 -991
- package/pdfjs/dist/worker.js +60846 -60846
- package/src/vcf-pdf-viewer.js +11 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as stringToBytes, c as assert, M as MissingPDFException, v as UnexpectedResponseException } from './util.js';
|
|
2
|
-
import { i as isPdfFile } from './display_utils.js';
|
|
3
|
-
|
|
1
|
+
import { n as stringToBytes, c as assert, M as MissingPDFException, v as UnexpectedResponseException } from './util.js';
|
|
2
|
+
import { i as isPdfFile } from './display_utils.js';
|
|
3
|
+
|
|
4
4
|
/* Copyright 2017 Mozilla Foundation
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -14,239 +14,239 @@ import { i as isPdfFile } from './display_utils.js';
|
|
|
14
14
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
15
|
* See the License for the specific language governing permissions and
|
|
16
16
|
* limitations under the License.
|
|
17
|
-
*/
|
|
18
|
-
// https://github.com/Rob--W/open-in-browser/blob/7e2e35a38b8b4e981b11da7b2f01df0149049e92/extension/content-disposition.js
|
|
19
|
-
// with the following changes:
|
|
20
|
-
// - Modified to conform to PDF.js's coding style.
|
|
21
|
-
// - Support UTF-8 decoding when TextDecoder is unsupported.
|
|
22
|
-
// - Move return to the end of the function to prevent Babel from dropping the
|
|
23
|
-
// function declarations.
|
|
24
|
-
|
|
17
|
+
*/
|
|
18
|
+
// https://github.com/Rob--W/open-in-browser/blob/7e2e35a38b8b4e981b11da7b2f01df0149049e92/extension/content-disposition.js
|
|
19
|
+
// with the following changes:
|
|
20
|
+
// - Modified to conform to PDF.js's coding style.
|
|
21
|
+
// - Support UTF-8 decoding when TextDecoder is unsupported.
|
|
22
|
+
// - Move return to the end of the function to prevent Babel from dropping the
|
|
23
|
+
// function declarations.
|
|
24
|
+
|
|
25
25
|
/**
|
|
26
26
|
* Extract file name from the Content-Disposition HTTP response header.
|
|
27
27
|
*
|
|
28
28
|
* @param {string} contentDisposition
|
|
29
29
|
* @returns {string} Filename, if found in the Content-Disposition header.
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|
33
|
-
let needsEncodingFixup = true; // filename*=ext-value ("ext-value" from RFC 5987, referenced by RFC 6266).
|
|
34
|
-
|
|
35
|
-
let tmp = toParamRegExp("filename\\*", "i").exec(contentDisposition);
|
|
36
|
-
|
|
37
|
-
if (tmp) {
|
|
38
|
-
tmp = tmp[1];
|
|
39
|
-
let filename = rfc2616unquote(tmp);
|
|
40
|
-
filename = unescape(filename);
|
|
41
|
-
filename = rfc5987decode(filename);
|
|
42
|
-
filename = rfc2047decode(filename);
|
|
43
|
-
return fixupEncoding(filename);
|
|
44
|
-
} // Continuations (RFC 2231 section 3, referenced by RFC 5987 section 3.1).
|
|
45
|
-
// filename*n*=part
|
|
46
|
-
// filename*n=part
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
tmp = rfc2231getparam(contentDisposition);
|
|
50
|
-
|
|
51
|
-
if (tmp) {
|
|
52
|
-
// RFC 2047, section
|
|
53
|
-
const filename = rfc2047decode(tmp);
|
|
54
|
-
return fixupEncoding(filename);
|
|
55
|
-
} // filename=value (RFC 5987, section 4.1).
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
tmp = toParamRegExp("filename", "i").exec(contentDisposition);
|
|
59
|
-
|
|
60
|
-
if (tmp) {
|
|
61
|
-
tmp = tmp[1];
|
|
62
|
-
let filename = rfc2616unquote(tmp);
|
|
63
|
-
filename = rfc2047decode(filename);
|
|
64
|
-
return fixupEncoding(filename);
|
|
65
|
-
} // After this line there are only function declarations. We cannot put
|
|
66
|
-
// "return" here for readability because babel would then drop the function
|
|
67
|
-
// declarations...
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
function toParamRegExp(attributePattern, flags) {
|
|
71
|
-
return new RegExp("(?:^|;)\\s*" + attributePattern + "\\s*=\\s*" + // Captures: value = token | quoted-string
|
|
72
|
-
// (RFC 2616, section 3.6 and referenced by RFC 6266 4.1)
|
|
73
|
-
"(" + '[^";\\s][^;\\s]*' + "|" + '"(?:[^"\\\\]|\\\\"?)+"?' + ")", flags);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function textdecode(encoding, value) {
|
|
77
|
-
if (encoding) {
|
|
78
|
-
if (!/^[\x00-\xFF]+$/.test(value)) {
|
|
79
|
-
return value;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
const decoder = new TextDecoder(encoding, {
|
|
84
|
-
fatal: true
|
|
85
|
-
});
|
|
86
|
-
const buffer = stringToBytes(value);
|
|
87
|
-
value = decoder.decode(buffer);
|
|
88
|
-
needsEncodingFixup = false;
|
|
89
|
-
} catch (e) {
|
|
90
|
-
// TextDecoder constructor threw - unrecognized encoding.
|
|
91
|
-
// Or TextDecoder API is not available (in IE / Edge).
|
|
92
|
-
if (/^utf-?8$/i.test(encoding)) {
|
|
93
|
-
// UTF-8 is commonly used, try to support it in another way:
|
|
94
|
-
try {
|
|
95
|
-
value = decodeURIComponent(escape(value));
|
|
96
|
-
needsEncodingFixup = false;
|
|
97
|
-
} catch (err) {}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return value;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function fixupEncoding(value) {
|
|
106
|
-
if (needsEncodingFixup && /[\x80-\xff]/.test(value)) {
|
|
107
|
-
// Maybe multi-byte UTF-8.
|
|
108
|
-
value = textdecode("utf-8", value);
|
|
109
|
-
|
|
110
|
-
if (needsEncodingFixup) {
|
|
111
|
-
// Try iso-8859-1 encoding.
|
|
112
|
-
value = textdecode("iso-8859-1", value);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return value;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function rfc2231getparam(contentDispositionStr) {
|
|
120
|
-
const matches = [];
|
|
121
|
-
let match; // Iterate over all filename*n= and filename*n*= with n being an integer
|
|
122
|
-
// of at least zero. Any non-zero number must not start with '0'.
|
|
123
|
-
|
|
124
|
-
const iter = toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)", "ig");
|
|
125
|
-
|
|
126
|
-
while ((match = iter.exec(contentDispositionStr)) !== null) {
|
|
127
|
-
let [, n, quot, part] = match; // eslint-disable-line prefer-const
|
|
128
|
-
|
|
129
|
-
n = parseInt(n, 10);
|
|
130
|
-
|
|
131
|
-
if (n in matches) {
|
|
132
|
-
// Ignore anything after the invalid second filename*0.
|
|
133
|
-
if (n === 0) {
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
matches[n] = [quot, part];
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const parts = [];
|
|
144
|
-
|
|
145
|
-
for (let n = 0; n < matches.length; ++n) {
|
|
146
|
-
if (!(n in matches)) {
|
|
147
|
-
// Numbers must be consecutive. Truncate when there is a hole.
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
let [quot, part] = matches[n]; // eslint-disable-line prefer-const
|
|
152
|
-
|
|
153
|
-
part = rfc2616unquote(part);
|
|
154
|
-
|
|
155
|
-
if (quot) {
|
|
156
|
-
part = unescape(part);
|
|
157
|
-
|
|
158
|
-
if (n === 0) {
|
|
159
|
-
part = rfc5987decode(part);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
parts.push(part);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return parts.join("");
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function rfc2616unquote(value) {
|
|
170
|
-
if (value.startsWith('"')) {
|
|
171
|
-
const parts = value.slice(1).split('\\"'); // Find the first unescaped " and terminate there.
|
|
172
|
-
|
|
173
|
-
for (let i = 0; i < parts.length; ++i) {
|
|
174
|
-
const quotindex = parts[i].indexOf('"');
|
|
175
|
-
|
|
176
|
-
if (quotindex !== -1) {
|
|
177
|
-
parts[i] = parts[i].slice(0, quotindex);
|
|
178
|
-
parts.length = i + 1; // Truncates and stop the iteration.
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
parts[i] = parts[i].replace(/\\(.)/g, "$1");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
value = parts.join('"');
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return value;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function rfc5987decode(extvalue) {
|
|
191
|
-
// Decodes "ext-value" from RFC 5987.
|
|
192
|
-
const encodingend = extvalue.indexOf("'");
|
|
193
|
-
|
|
194
|
-
if (encodingend === -1) {
|
|
195
|
-
// Some servers send "filename*=" without encoding 'language' prefix,
|
|
196
|
-
// e.g. in https://github.com/Rob--W/open-in-browser/issues/26
|
|
197
|
-
// Let's accept the value like Firefox (57) (Chrome 62 rejects it).
|
|
198
|
-
return extvalue;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const encoding = extvalue.slice(0, encodingend);
|
|
202
|
-
const langvalue = extvalue.slice(encodingend + 1); // Ignore language (RFC 5987 section 3.2.1, and RFC 6266 section 4.1 ).
|
|
203
|
-
|
|
204
|
-
const value = langvalue.replace(/^[^']*'/, "");
|
|
205
|
-
return textdecode(encoding, value);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function rfc2047decode(value) {
|
|
209
|
-
// RFC 2047-decode the result. Firefox tried to drop support for it, but
|
|
210
|
-
// backed out because some servers use it - https://bugzil.la/875615
|
|
211
|
-
// Firefox's condition for decoding is here: https://searchfox.org/mozilla-central/rev/4a590a5a15e35d88a3b23dd6ac3c471cf85b04a8/netwerk/mime/nsMIMEHeaderParamImpl.cpp#742-748
|
|
212
|
-
// We are more strict and only recognize RFC 2047-encoding if the value
|
|
213
|
-
// starts with "=?", since then it is likely that the full value is
|
|
214
|
-
// RFC 2047-encoded.
|
|
215
|
-
// Firefox also decodes words even where RFC 2047 section 5 states:
|
|
216
|
-
// "An 'encoded-word' MUST NOT appear within a 'quoted-string'."
|
|
217
|
-
if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) {
|
|
218
|
-
return value;
|
|
219
|
-
} // RFC 2047, section 2.4
|
|
220
|
-
// encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
|
|
221
|
-
// charset = token (but let's restrict to characters that denote a
|
|
222
|
-
// possibly valid encoding).
|
|
223
|
-
// encoding = q or b
|
|
224
|
-
// encoded-text = any printable ASCII character other than ? or space.
|
|
225
|
-
// ... but Firefox permits ? and space.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
return value.replace(/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g, function (matches, charset, encoding, text) {
|
|
229
|
-
if (encoding === "q" || encoding === "Q") {
|
|
230
|
-
// RFC 2047 section 4.2.
|
|
231
|
-
text = text.replace(/_/g, " ");
|
|
232
|
-
text = text.replace(/=([0-9a-fA-F]{2})/g, function (match, hex) {
|
|
233
|
-
return String.fromCharCode(parseInt(hex, 16));
|
|
234
|
-
});
|
|
235
|
-
return textdecode(charset, text);
|
|
236
|
-
} // else encoding is b or B - base64 (RFC 2047 section 4.1)
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
try {
|
|
240
|
-
text = atob(text);
|
|
241
|
-
} catch (e) {}
|
|
242
|
-
|
|
243
|
-
return textdecode(charset, text);
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
return "";
|
|
248
|
-
}
|
|
249
|
-
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|
33
|
+
let needsEncodingFixup = true; // filename*=ext-value ("ext-value" from RFC 5987, referenced by RFC 6266).
|
|
34
|
+
|
|
35
|
+
let tmp = toParamRegExp("filename\\*", "i").exec(contentDisposition);
|
|
36
|
+
|
|
37
|
+
if (tmp) {
|
|
38
|
+
tmp = tmp[1];
|
|
39
|
+
let filename = rfc2616unquote(tmp);
|
|
40
|
+
filename = unescape(filename);
|
|
41
|
+
filename = rfc5987decode(filename);
|
|
42
|
+
filename = rfc2047decode(filename);
|
|
43
|
+
return fixupEncoding(filename);
|
|
44
|
+
} // Continuations (RFC 2231 section 3, referenced by RFC 5987 section 3.1).
|
|
45
|
+
// filename*n*=part
|
|
46
|
+
// filename*n=part
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
tmp = rfc2231getparam(contentDisposition);
|
|
50
|
+
|
|
51
|
+
if (tmp) {
|
|
52
|
+
// RFC 2047, section
|
|
53
|
+
const filename = rfc2047decode(tmp);
|
|
54
|
+
return fixupEncoding(filename);
|
|
55
|
+
} // filename=value (RFC 5987, section 4.1).
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
tmp = toParamRegExp("filename", "i").exec(contentDisposition);
|
|
59
|
+
|
|
60
|
+
if (tmp) {
|
|
61
|
+
tmp = tmp[1];
|
|
62
|
+
let filename = rfc2616unquote(tmp);
|
|
63
|
+
filename = rfc2047decode(filename);
|
|
64
|
+
return fixupEncoding(filename);
|
|
65
|
+
} // After this line there are only function declarations. We cannot put
|
|
66
|
+
// "return" here for readability because babel would then drop the function
|
|
67
|
+
// declarations...
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
function toParamRegExp(attributePattern, flags) {
|
|
71
|
+
return new RegExp("(?:^|;)\\s*" + attributePattern + "\\s*=\\s*" + // Captures: value = token | quoted-string
|
|
72
|
+
// (RFC 2616, section 3.6 and referenced by RFC 6266 4.1)
|
|
73
|
+
"(" + '[^";\\s][^;\\s]*' + "|" + '"(?:[^"\\\\]|\\\\"?)+"?' + ")", flags);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function textdecode(encoding, value) {
|
|
77
|
+
if (encoding) {
|
|
78
|
+
if (!/^[\x00-\xFF]+$/.test(value)) {
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const decoder = new TextDecoder(encoding, {
|
|
84
|
+
fatal: true
|
|
85
|
+
});
|
|
86
|
+
const buffer = stringToBytes(value);
|
|
87
|
+
value = decoder.decode(buffer);
|
|
88
|
+
needsEncodingFixup = false;
|
|
89
|
+
} catch (e) {
|
|
90
|
+
// TextDecoder constructor threw - unrecognized encoding.
|
|
91
|
+
// Or TextDecoder API is not available (in IE / Edge).
|
|
92
|
+
if (/^utf-?8$/i.test(encoding)) {
|
|
93
|
+
// UTF-8 is commonly used, try to support it in another way:
|
|
94
|
+
try {
|
|
95
|
+
value = decodeURIComponent(escape(value));
|
|
96
|
+
needsEncodingFixup = false;
|
|
97
|
+
} catch (err) {}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function fixupEncoding(value) {
|
|
106
|
+
if (needsEncodingFixup && /[\x80-\xff]/.test(value)) {
|
|
107
|
+
// Maybe multi-byte UTF-8.
|
|
108
|
+
value = textdecode("utf-8", value);
|
|
109
|
+
|
|
110
|
+
if (needsEncodingFixup) {
|
|
111
|
+
// Try iso-8859-1 encoding.
|
|
112
|
+
value = textdecode("iso-8859-1", value);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return value;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function rfc2231getparam(contentDispositionStr) {
|
|
120
|
+
const matches = [];
|
|
121
|
+
let match; // Iterate over all filename*n= and filename*n*= with n being an integer
|
|
122
|
+
// of at least zero. Any non-zero number must not start with '0'.
|
|
123
|
+
|
|
124
|
+
const iter = toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)", "ig");
|
|
125
|
+
|
|
126
|
+
while ((match = iter.exec(contentDispositionStr)) !== null) {
|
|
127
|
+
let [, n, quot, part] = match; // eslint-disable-line prefer-const
|
|
128
|
+
|
|
129
|
+
n = parseInt(n, 10);
|
|
130
|
+
|
|
131
|
+
if (n in matches) {
|
|
132
|
+
// Ignore anything after the invalid second filename*0.
|
|
133
|
+
if (n === 0) {
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
matches[n] = [quot, part];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const parts = [];
|
|
144
|
+
|
|
145
|
+
for (let n = 0; n < matches.length; ++n) {
|
|
146
|
+
if (!(n in matches)) {
|
|
147
|
+
// Numbers must be consecutive. Truncate when there is a hole.
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
let [quot, part] = matches[n]; // eslint-disable-line prefer-const
|
|
152
|
+
|
|
153
|
+
part = rfc2616unquote(part);
|
|
154
|
+
|
|
155
|
+
if (quot) {
|
|
156
|
+
part = unescape(part);
|
|
157
|
+
|
|
158
|
+
if (n === 0) {
|
|
159
|
+
part = rfc5987decode(part);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
parts.push(part);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return parts.join("");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function rfc2616unquote(value) {
|
|
170
|
+
if (value.startsWith('"')) {
|
|
171
|
+
const parts = value.slice(1).split('\\"'); // Find the first unescaped " and terminate there.
|
|
172
|
+
|
|
173
|
+
for (let i = 0; i < parts.length; ++i) {
|
|
174
|
+
const quotindex = parts[i].indexOf('"');
|
|
175
|
+
|
|
176
|
+
if (quotindex !== -1) {
|
|
177
|
+
parts[i] = parts[i].slice(0, quotindex);
|
|
178
|
+
parts.length = i + 1; // Truncates and stop the iteration.
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
parts[i] = parts[i].replace(/\\(.)/g, "$1");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
value = parts.join('"');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return value;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function rfc5987decode(extvalue) {
|
|
191
|
+
// Decodes "ext-value" from RFC 5987.
|
|
192
|
+
const encodingend = extvalue.indexOf("'");
|
|
193
|
+
|
|
194
|
+
if (encodingend === -1) {
|
|
195
|
+
// Some servers send "filename*=" without encoding 'language' prefix,
|
|
196
|
+
// e.g. in https://github.com/Rob--W/open-in-browser/issues/26
|
|
197
|
+
// Let's accept the value like Firefox (57) (Chrome 62 rejects it).
|
|
198
|
+
return extvalue;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const encoding = extvalue.slice(0, encodingend);
|
|
202
|
+
const langvalue = extvalue.slice(encodingend + 1); // Ignore language (RFC 5987 section 3.2.1, and RFC 6266 section 4.1 ).
|
|
203
|
+
|
|
204
|
+
const value = langvalue.replace(/^[^']*'/, "");
|
|
205
|
+
return textdecode(encoding, value);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function rfc2047decode(value) {
|
|
209
|
+
// RFC 2047-decode the result. Firefox tried to drop support for it, but
|
|
210
|
+
// backed out because some servers use it - https://bugzil.la/875615
|
|
211
|
+
// Firefox's condition for decoding is here: https://searchfox.org/mozilla-central/rev/4a590a5a15e35d88a3b23dd6ac3c471cf85b04a8/netwerk/mime/nsMIMEHeaderParamImpl.cpp#742-748
|
|
212
|
+
// We are more strict and only recognize RFC 2047-encoding if the value
|
|
213
|
+
// starts with "=?", since then it is likely that the full value is
|
|
214
|
+
// RFC 2047-encoded.
|
|
215
|
+
// Firefox also decodes words even where RFC 2047 section 5 states:
|
|
216
|
+
// "An 'encoded-word' MUST NOT appear within a 'quoted-string'."
|
|
217
|
+
if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) {
|
|
218
|
+
return value;
|
|
219
|
+
} // RFC 2047, section 2.4
|
|
220
|
+
// encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
|
|
221
|
+
// charset = token (but let's restrict to characters that denote a
|
|
222
|
+
// possibly valid encoding).
|
|
223
|
+
// encoding = q or b
|
|
224
|
+
// encoded-text = any printable ASCII character other than ? or space.
|
|
225
|
+
// ... but Firefox permits ? and space.
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
return value.replace(/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g, function (matches, charset, encoding, text) {
|
|
229
|
+
if (encoding === "q" || encoding === "Q") {
|
|
230
|
+
// RFC 2047 section 4.2.
|
|
231
|
+
text = text.replace(/_/g, " ");
|
|
232
|
+
text = text.replace(/=([0-9a-fA-F]{2})/g, function (match, hex) {
|
|
233
|
+
return String.fromCharCode(parseInt(hex, 16));
|
|
234
|
+
});
|
|
235
|
+
return textdecode(charset, text);
|
|
236
|
+
} // else encoding is b or B - base64 (RFC 2047 section 4.1)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
text = atob(text);
|
|
241
|
+
} catch (e) {}
|
|
242
|
+
|
|
243
|
+
return textdecode(charset, text);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return "";
|
|
248
|
+
}
|
|
249
|
+
|
|
250
250
|
/* Copyright 2012 Mozilla Foundation
|
|
251
251
|
*
|
|
252
252
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -260,81 +260,81 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|
|
260
260
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
261
261
|
* See the License for the specific language governing permissions and
|
|
262
262
|
* limitations under the License.
|
|
263
|
-
*/
|
|
264
|
-
|
|
265
|
-
function validateRangeRequestCapabilities({
|
|
266
|
-
getResponseHeader,
|
|
267
|
-
isHttp,
|
|
268
|
-
rangeChunkSize,
|
|
269
|
-
disableRange
|
|
270
|
-
}) {
|
|
271
|
-
assert(rangeChunkSize > 0, "Range chunk size must be larger than zero");
|
|
272
|
-
const returnValues = {
|
|
273
|
-
allowRangeRequests: false,
|
|
274
|
-
suggestedLength: undefined
|
|
275
|
-
};
|
|
276
|
-
const length = parseInt(getResponseHeader("Content-Length"), 10);
|
|
277
|
-
|
|
278
|
-
if (!Number.isInteger(length)) {
|
|
279
|
-
return returnValues;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
returnValues.suggestedLength = length;
|
|
283
|
-
|
|
284
|
-
if (length <= 2 * rangeChunkSize) {
|
|
285
|
-
// The file size is smaller than the size of two chunks, so it does not
|
|
286
|
-
// make any sense to abort the request and retry with a range request.
|
|
287
|
-
return returnValues;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
if (disableRange || !isHttp) {
|
|
291
|
-
return returnValues;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (getResponseHeader("Accept-Ranges") !== "bytes") {
|
|
295
|
-
return returnValues;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const contentEncoding = getResponseHeader("Content-Encoding") || "identity";
|
|
299
|
-
|
|
300
|
-
if (contentEncoding !== "identity") {
|
|
301
|
-
return returnValues;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
returnValues.allowRangeRequests = true;
|
|
305
|
-
return returnValues;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
function extractFilenameFromHeader(getResponseHeader) {
|
|
309
|
-
const contentDisposition = getResponseHeader("Content-Disposition");
|
|
310
|
-
|
|
311
|
-
if (contentDisposition) {
|
|
312
|
-
let filename = getFilenameFromContentDispositionHeader(contentDisposition);
|
|
313
|
-
|
|
314
|
-
if (filename.includes("%")) {
|
|
315
|
-
try {
|
|
316
|
-
filename = decodeURIComponent(filename);
|
|
317
|
-
} catch (ex) {}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
if (isPdfFile(filename)) {
|
|
321
|
-
return filename;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
return null;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
function createResponseStatusError(status, url) {
|
|
329
|
-
if (status === 404 || status === 0 && url.startsWith("file:")) {
|
|
330
|
-
return new MissingPDFException('Missing PDF "' + url + '".');
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return new UnexpectedResponseException(`Unexpected server response (${status}) while retrieving PDF "${url}".`, status);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function validateResponseStatus(status) {
|
|
337
|
-
return status === 200 || status === 206;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
export { validateResponseStatus as a, createResponseStatusError as c, extractFilenameFromHeader as e, validateRangeRequestCapabilities as v };
|
|
263
|
+
*/
|
|
264
|
+
|
|
265
|
+
function validateRangeRequestCapabilities({
|
|
266
|
+
getResponseHeader,
|
|
267
|
+
isHttp,
|
|
268
|
+
rangeChunkSize,
|
|
269
|
+
disableRange
|
|
270
|
+
}) {
|
|
271
|
+
assert(rangeChunkSize > 0, "Range chunk size must be larger than zero");
|
|
272
|
+
const returnValues = {
|
|
273
|
+
allowRangeRequests: false,
|
|
274
|
+
suggestedLength: undefined
|
|
275
|
+
};
|
|
276
|
+
const length = parseInt(getResponseHeader("Content-Length"), 10);
|
|
277
|
+
|
|
278
|
+
if (!Number.isInteger(length)) {
|
|
279
|
+
return returnValues;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
returnValues.suggestedLength = length;
|
|
283
|
+
|
|
284
|
+
if (length <= 2 * rangeChunkSize) {
|
|
285
|
+
// The file size is smaller than the size of two chunks, so it does not
|
|
286
|
+
// make any sense to abort the request and retry with a range request.
|
|
287
|
+
return returnValues;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (disableRange || !isHttp) {
|
|
291
|
+
return returnValues;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (getResponseHeader("Accept-Ranges") !== "bytes") {
|
|
295
|
+
return returnValues;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const contentEncoding = getResponseHeader("Content-Encoding") || "identity";
|
|
299
|
+
|
|
300
|
+
if (contentEncoding !== "identity") {
|
|
301
|
+
return returnValues;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
returnValues.allowRangeRequests = true;
|
|
305
|
+
return returnValues;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function extractFilenameFromHeader(getResponseHeader) {
|
|
309
|
+
const contentDisposition = getResponseHeader("Content-Disposition");
|
|
310
|
+
|
|
311
|
+
if (contentDisposition) {
|
|
312
|
+
let filename = getFilenameFromContentDispositionHeader(contentDisposition);
|
|
313
|
+
|
|
314
|
+
if (filename.includes("%")) {
|
|
315
|
+
try {
|
|
316
|
+
filename = decodeURIComponent(filename);
|
|
317
|
+
} catch (ex) {}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (isPdfFile(filename)) {
|
|
321
|
+
return filename;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function createResponseStatusError(status, url) {
|
|
329
|
+
if (status === 404 || status === 0 && url.startsWith("file:")) {
|
|
330
|
+
return new MissingPDFException('Missing PDF "' + url + '".');
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return new UnexpectedResponseException(`Unexpected server response (${status}) while retrieving PDF "${url}".`, status);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function validateResponseStatus(status) {
|
|
337
|
+
return status === 200 || status === 206;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export { validateResponseStatus as a, createResponseStatusError as c, extractFilenameFromHeader as e, validateRangeRequestCapabilities as v };
|