Merge pull request #7794 from Snuffleupagus/JavaScript-white-listed-actions
[api-minor] Add support for a couple of white-listed `JavaScript` actions that contains valid URLs (issue 3897, bug 843699)
This commit is contained in:
commit
c23f124051
@ -695,6 +695,33 @@ var Catalog = (function CatalogClosure() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'JavaScript':
|
||||||
|
var jsAction = action.get('JS'), js;
|
||||||
|
if (isStream(jsAction)) {
|
||||||
|
js = bytesToString(jsAction.getBytes());
|
||||||
|
} else if (isString(jsAction)) {
|
||||||
|
js = jsAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (js) {
|
||||||
|
// Attempt to recover valid URLs from 'JS' entries with certain
|
||||||
|
// white-listed formats, e.g.
|
||||||
|
// - window.open('http://example.com')
|
||||||
|
// - app.launchURL('http://example.com', true)
|
||||||
|
var URL_OPEN_METHODS = [
|
||||||
|
'app.launchURL',
|
||||||
|
'window.open'
|
||||||
|
];
|
||||||
|
var regex = new RegExp('^(?:' + URL_OPEN_METHODS.join('|') + ')' +
|
||||||
|
'\\((?:\'|\")(\\S+)(?:\'|\")(?:,|\\))');
|
||||||
|
|
||||||
|
var jsUrl = regex.exec(stringToPDFString(js), 'i');
|
||||||
|
if (jsUrl && jsUrl[1]) {
|
||||||
|
url = jsUrl[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* falls through */
|
||||||
default:
|
default:
|
||||||
warn('Catalog_parseDestDictionary: Unrecognized link type "' +
|
warn('Catalog_parseDestDictionary: Unrecognized link type "' +
|
||||||
linkType + '".');
|
linkType + '".');
|
||||||
|
@ -544,6 +544,60 @@ describe('Annotation layer', function() {
|
|||||||
expect(data.newWindow).toEqual(true);
|
expect(data.newWindow).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should recover valid URLs from JavaScript actions having certain ' +
|
||||||
|
'white-listed formats', function () {
|
||||||
|
function checkJsAction(params) {
|
||||||
|
var jsEntry = params.jsEntry;
|
||||||
|
var expectedUrl = params.expectedUrl;
|
||||||
|
var expectedUnsafeUrl = params.expectedUnsafeUrl;
|
||||||
|
|
||||||
|
var actionDict = new Dict();
|
||||||
|
actionDict.set('Type', Name.get('Action'));
|
||||||
|
actionDict.set('S', Name.get('JavaScript'));
|
||||||
|
actionDict.set('JS', jsEntry);
|
||||||
|
|
||||||
|
var annotationDict = new Dict();
|
||||||
|
annotationDict.set('Type', Name.get('Annot'));
|
||||||
|
annotationDict.set('Subtype', Name.get('Link'));
|
||||||
|
annotationDict.set('A', actionDict);
|
||||||
|
|
||||||
|
var annotationRef = new Ref(46, 0);
|
||||||
|
var xref = new XRefMock([
|
||||||
|
{ ref: annotationRef, data: annotationDict, }
|
||||||
|
]);
|
||||||
|
|
||||||
|
var annotation = annotationFactory.create(xref, annotationRef,
|
||||||
|
pdfManagerMock);
|
||||||
|
var data = annotation.data;
|
||||||
|
expect(data.annotationType).toEqual(AnnotationType.LINK);
|
||||||
|
|
||||||
|
expect(data.url).toEqual(expectedUrl);
|
||||||
|
expect(data.unsafeUrl).toEqual(expectedUnsafeUrl);
|
||||||
|
expect(data.dest).toBeUndefined();
|
||||||
|
expect(data.newWindow).toBeFalsy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that we reject a 'JS' entry containing arbitrary JavaScript.
|
||||||
|
checkJsAction({
|
||||||
|
jsEntry: 'function someFun() { return "qwerty"; } someFun();',
|
||||||
|
expectedUrl: undefined,
|
||||||
|
expectedUnsafeUrl: undefined,
|
||||||
|
});
|
||||||
|
// Check that we accept a white-listed {string} 'JS' entry.
|
||||||
|
checkJsAction({
|
||||||
|
jsEntry: 'window.open(\'http://www.example.com/test.pdf\')',
|
||||||
|
expectedUrl: new URL('http://www.example.com/test.pdf').href,
|
||||||
|
expectedUnsafeUrl: 'http://www.example.com/test.pdf',
|
||||||
|
});
|
||||||
|
// Check that we accept a white-listed {Stream} 'JS' entry.
|
||||||
|
checkJsAction({
|
||||||
|
jsEntry: new StringStream(
|
||||||
|
'app.launchURL("http://www.example.com/test.pdf", true)'),
|
||||||
|
expectedUrl: new URL('http://www.example.com/test.pdf').href,
|
||||||
|
expectedUnsafeUrl: 'http://www.example.com/test.pdf',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should correctly parse a Named action', function() {
|
it('should correctly parse a Named action', function() {
|
||||||
var actionDict = new Dict();
|
var actionDict = new Dict();
|
||||||
actionDict.set('Type', Name.get('Action'));
|
actionDict.set('Type', Name.get('Action'));
|
||||||
|
Loading…
Reference in New Issue
Block a user