Browse Source

Deprecate the `isValidUrl` utility function and replace it with `createValidAbsoluteUrl`/`isValidProtocal` functions instead, since the main URL validation is now done using the `new URL` constructor

Jonas Jenwald 9 years ago
parent
commit
71a781ee5c
  1. 12
      src/core/obj.js
  2. 9
      src/display/dom_utils.js
  3. 2
      src/display/global.js
  4. 4
      src/main_loader.js
  5. 4
      src/pdf.js
  6. 46
      src/shared/util.js
  7. 3
      web/download_manager.js

12
src/core/obj.js

@ -48,7 +48,7 @@ var shadow = sharedUtil.shadow;
var stringToPDFString = sharedUtil.stringToPDFString; var stringToPDFString = sharedUtil.stringToPDFString;
var stringToUTF8String = sharedUtil.stringToUTF8String; var stringToUTF8String = sharedUtil.stringToUTF8String;
var warn = sharedUtil.warn; var warn = sharedUtil.warn;
var isValidUrl = sharedUtil.isValidUrl; var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
var Util = sharedUtil.Util; var Util = sharedUtil.Util;
var Ref = corePrimitives.Ref; var Ref = corePrimitives.Ref;
var RefSet = corePrimitives.RefSet; var RefSet = corePrimitives.RefSet;
@ -694,13 +694,9 @@ var Catalog = (function CatalogClosure() {
if (isString(url)) { if (isString(url)) {
url = tryConvertUrlEncoding(url); url = tryConvertUrlEncoding(url);
var absoluteUrl; var absoluteUrl = createValidAbsoluteUrl(url);
try { if (absoluteUrl) {
absoluteUrl = new URL(url).href; resultObj.url = absoluteUrl.href;
} catch (ex) { /* `new URL()` will throw on incorrect data. */ }
if (isValidUrl(absoluteUrl, /* allowRelative = */ false)) {
resultObj.url = absoluteUrl;
} }
resultObj.unsafeUrl = url; resultObj.unsafeUrl = url;
} }

9
src/display/dom_utils.js

@ -28,6 +28,8 @@
var removeNullCharacters = sharedUtil.removeNullCharacters; var removeNullCharacters = sharedUtil.removeNullCharacters;
var warn = sharedUtil.warn; var warn = sharedUtil.warn;
var deprecated = sharedUtil.deprecated;
var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
/** /**
* Optimised CSS custom property getter/setter. * Optimised CSS custom property getter/setter.
@ -229,9 +231,16 @@ function isExternalLinkTargetSet() {
} }
} }
function isValidUrl(url, allowRelative) {
deprecated('isValidUrl(), please use createValidAbsoluteUrl() instead.');
var baseUrl = allowRelative ? 'http://example.com' : null;
return createValidAbsoluteUrl(url, baseUrl) !== null;
}
exports.CustomStyle = CustomStyle; exports.CustomStyle = CustomStyle;
exports.addLinkAttributes = addLinkAttributes; exports.addLinkAttributes = addLinkAttributes;
exports.isExternalLinkTargetSet = isExternalLinkTargetSet; exports.isExternalLinkTargetSet = isExternalLinkTargetSet;
exports.isValidUrl = isValidUrl;
exports.getFilenameFromUrl = getFilenameFromUrl; exports.getFilenameFromUrl = getFilenameFromUrl;
exports.LinkTarget = LinkTarget; exports.LinkTarget = LinkTarget;
exports.hasCanvasTypedArrays = hasCanvasTypedArrays; exports.hasCanvasTypedArrays = hasCanvasTypedArrays;

2
src/display/global.js

@ -76,7 +76,7 @@
PDFJS.VERBOSITY_LEVELS = sharedUtil.VERBOSITY_LEVELS; PDFJS.VERBOSITY_LEVELS = sharedUtil.VERBOSITY_LEVELS;
PDFJS.OPS = sharedUtil.OPS; PDFJS.OPS = sharedUtil.OPS;
PDFJS.UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES; PDFJS.UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES;
PDFJS.isValidUrl = sharedUtil.isValidUrl; PDFJS.isValidUrl = displayDOMUtils.isValidUrl;
PDFJS.shadow = sharedUtil.shadow; PDFJS.shadow = sharedUtil.shadow;
PDFJS.createBlob = sharedUtil.createBlob; PDFJS.createBlob = sharedUtil.createBlob;
PDFJS.createObjectURL = function PDFJS_createObjectURL(data, contentType) { PDFJS.createObjectURL = function PDFJS_createObjectURL(data, contentType) {

4
src/main_loader.js

@ -55,12 +55,12 @@
exports.UnexpectedResponseException = sharedUtil.UnexpectedResponseException; exports.UnexpectedResponseException = sharedUtil.UnexpectedResponseException;
exports.OPS = sharedUtil.OPS; exports.OPS = sharedUtil.OPS;
exports.UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES; exports.UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES;
exports.isValidUrl = sharedUtil.isValidUrl; exports.isValidUrl = displayDOMUtils.isValidUrl;
exports.createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
exports.createObjectURL = sharedUtil.createObjectURL; exports.createObjectURL = sharedUtil.createObjectURL;
exports.removeNullCharacters = sharedUtil.removeNullCharacters; exports.removeNullCharacters = sharedUtil.removeNullCharacters;
exports.shadow = sharedUtil.shadow; exports.shadow = sharedUtil.shadow;
exports.createBlob = sharedUtil.createBlob; exports.createBlob = sharedUtil.createBlob;
exports.getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl; exports.getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl;
exports.addLinkAttributes = displayDOMUtils.addLinkAttributes; exports.addLinkAttributes = displayDOMUtils.addLinkAttributes;
})); }));

4
src/pdf.js

@ -64,7 +64,9 @@
exports.OPS = pdfjsLibs.pdfjsSharedUtil.OPS; exports.OPS = pdfjsLibs.pdfjsSharedUtil.OPS;
exports.UNSUPPORTED_FEATURES = exports.UNSUPPORTED_FEATURES =
pdfjsLibs.pdfjsSharedUtil.UNSUPPORTED_FEATURES; pdfjsLibs.pdfjsSharedUtil.UNSUPPORTED_FEATURES;
exports.isValidUrl = pdfjsLibs.pdfjsSharedUtil.isValidUrl; exports.isValidUrl = pdfjsLibs.pdfjsDisplayDOMUtils.isValidUrl;
exports.createValidAbsoluteUrl =
pdfjsLibs.pdfjsSharedUtil.createValidAbsoluteUrl;
exports.createObjectURL = pdfjsLibs.pdfjsSharedUtil.createObjectURL; exports.createObjectURL = pdfjsLibs.pdfjsSharedUtil.createObjectURL;
exports.removeNullCharacters = exports.removeNullCharacters =
pdfjsLibs.pdfjsSharedUtil.removeNullCharacters; pdfjsLibs.pdfjsSharedUtil.removeNullCharacters;

46
src/shared/util.js

@ -332,30 +332,42 @@ function isSameOrigin(baseUrl, otherUrl) {
return base.origin === other.origin; return base.origin === other.origin;
} }
// Validates if URL is safe and allowed, e.g. to avoid XSS. // Checks if URLs use one of the whitelisted protocols, e.g. to avoid XSS.
function isValidUrl(url, allowRelative) { function isValidProtocol(url) {
if (!url || typeof url !== 'string') { if (!url) {
return false; return false;
} }
// RFC 3986 (http://tools.ietf.org/html/rfc3986#section-3.1) switch (url.protocol) {
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) case 'http:':
var protocol = /^[a-z][a-z0-9+\-.]*(?=:)/i.exec(url); case 'https:':
if (!protocol) { case 'ftp:':
return allowRelative; case 'mailto:':
} case 'tel:':
protocol = protocol[0].toLowerCase();
switch (protocol) {
case 'http':
case 'https':
case 'ftp':
case 'mailto':
case 'tel':
return true; return true;
default: default:
return false; return false;
} }
} }
/**
* Attempts to create a valid absolute URL (utilizing `isValidProtocol`).
* @param {URL|string} url - An absolute, or relative, URL.
* @param {URL|string} baseUrl - An absolute URL.
* @returns Either a valid {URL}, or `null` otherwise.
*/
function createValidAbsoluteUrl(url, baseUrl) {
if (!url) {
return null;
}
try {
var absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);
if (isValidProtocol(absoluteUrl)) {
return absoluteUrl;
}
} catch (ex) { /* `new URL()` will throw on incorrect data. */ }
return null;
}
function shadow(obj, prop, value) { function shadow(obj, prop, value) {
Object.defineProperty(obj, prop, { value: value, Object.defineProperty(obj, prop, { value: value,
enumerable: true, enumerable: true,
@ -2431,7 +2443,7 @@ exports.isNum = isNum;
exports.isString = isString; exports.isString = isString;
exports.isSpace = isSpace; exports.isSpace = isSpace;
exports.isSameOrigin = isSameOrigin; exports.isSameOrigin = isSameOrigin;
exports.isValidUrl = isValidUrl; exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
exports.isLittleEndian = isLittleEndian; exports.isLittleEndian = isLittleEndian;
exports.isEvalSupported = isEvalSupported; exports.isEvalSupported = isEvalSupported;
exports.loadJpegStream = loadJpegStream; exports.loadJpegStream = loadJpegStream;

3
web/download_manager.js

@ -67,10 +67,9 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC || CHROME')) {
DownloadManager.prototype = { DownloadManager.prototype = {
downloadUrl: function DownloadManager_downloadUrl(url, filename) { downloadUrl: function DownloadManager_downloadUrl(url, filename) {
if (!pdfjsLib.isValidUrl(url, true)) { if (!pdfjsLib.createValidAbsoluteUrl(url, 'http://example.com')) {
return; // restricted/invalid URL return; // restricted/invalid URL
} }
download(url + '#pdfjs.action=download', filename); download(url + '#pdfjs.action=download', filename);
}, },

Loading…
Cancel
Save