forked from mirrors/gecko-dev
Bug 1900410 - Add filename option to ChromeUtils.compileScript a=dmeehan
This option enables internal callers to specify a different file name, which we will rely upon for redacting the extension URL and filenames. Original Revision: https://phabricator.services.mozilla.com/D214295 Differential Revision: https://phabricator.services.mozilla.com/D214815
This commit is contained in:
parent
aad7f1bca5
commit
6c54b9b35e
5 changed files with 64 additions and 6 deletions
|
|
@ -966,6 +966,11 @@ dictionary CompileScriptOptionsDictionary {
|
||||||
*/
|
*/
|
||||||
DOMString charset = "utf-8";
|
DOMString charset = "utf-8";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The filename to associate with the script. Defaults to the source's URL.
|
||||||
|
*/
|
||||||
|
DOMString filename;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, certain parts of the script may be parsed lazily, the first time
|
* If true, certain parts of the script may be parsed lazily, the first time
|
||||||
* they are used, rather than eagerly parsed at load time.
|
* they are used, rather than eagerly parsed at load time.
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ interface PrecompiledScript {
|
||||||
any executeInGlobal(object global, optional ExecuteInGlobalOptions options = {});
|
any executeInGlobal(object global, optional ExecuteInGlobalOptions options = {});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL that the script was loaded from.
|
* The URL that the script was loaded from. Could also be an arbitrary other
|
||||||
|
* value as specified by the "filename" option to ChromeUtils.compileScript.
|
||||||
*/
|
*/
|
||||||
[Pure]
|
[Pure]
|
||||||
readonly attribute DOMString url;
|
readonly attribute DOMString url;
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,14 @@ nsresult AsyncScriptCompiler::Start(
|
||||||
mCharset = aOptions.mCharset;
|
mCharset = aOptions.mCharset;
|
||||||
|
|
||||||
CompileOptions options(aCx);
|
CompileOptions options(aCx);
|
||||||
options.setFile(mURL.get()).setNoScriptRval(!aOptions.mHasReturnValue);
|
nsAutoCString filename;
|
||||||
|
if (aOptions.mFilename.WasPassed()) {
|
||||||
|
filename = NS_ConvertUTF16toUTF8(aOptions.mFilename.Value());
|
||||||
|
options.setFile(filename.get());
|
||||||
|
} else {
|
||||||
|
options.setFile(mURL.get());
|
||||||
|
}
|
||||||
|
options.setNoScriptRval(!aOptions.mHasReturnValue);
|
||||||
|
|
||||||
if (!aOptions.mLazilyParse) {
|
if (!aOptions.mLazilyParse) {
|
||||||
options.setForceFullParse();
|
options.setForceFullParse();
|
||||||
|
|
@ -418,7 +425,8 @@ void AsyncScriptCompiler::Reject(JSContext* aCx, const char* aMsg) {
|
||||||
nsAutoString msg;
|
nsAutoString msg;
|
||||||
msg.AppendASCII(aMsg);
|
msg.AppendASCII(aMsg);
|
||||||
msg.AppendLiteral(": ");
|
msg.AppendLiteral(": ");
|
||||||
AppendUTF8toUTF16(mURL, msg);
|
nsDependentCString filename(mOptions.filename().c_str());
|
||||||
|
AppendUTF8toUTF16(filename, msg);
|
||||||
|
|
||||||
RootedValue exn(aCx);
|
RootedValue exn(aCx);
|
||||||
if (xpc::NonVoidStringToJsval(aCx, msg, &exn)) {
|
if (xpc::NonVoidStringToJsval(aCx, msg, &exn)) {
|
||||||
|
|
@ -501,7 +509,7 @@ PrecompiledScript::PrecompiledScript(nsISupports* aParent,
|
||||||
JS::ReadOnlyCompileOptions& aOptions)
|
JS::ReadOnlyCompileOptions& aOptions)
|
||||||
: mParent(aParent),
|
: mParent(aParent),
|
||||||
mStencil(aStencil),
|
mStencil(aStencil),
|
||||||
mURL(aOptions.filename().c_str()),
|
mPublicURL(aOptions.filename().c_str()),
|
||||||
mHasReturnValue(!aOptions.noScriptRval) {
|
mHasReturnValue(!aOptions.noScriptRval) {
|
||||||
MOZ_ASSERT(aParent);
|
MOZ_ASSERT(aParent);
|
||||||
MOZ_ASSERT(aStencil);
|
MOZ_ASSERT(aStencil);
|
||||||
|
|
@ -551,7 +559,9 @@ void PrecompiledScript::ExecuteInGlobal(JSContext* aCx, HandleObject aGlobal,
|
||||||
JS_WrapValue(aCx, aRval);
|
JS_WrapValue(aCx, aRval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrecompiledScript::GetUrl(nsAString& aUrl) { CopyUTF8toUTF16(mURL, aUrl); }
|
void PrecompiledScript::GetUrl(nsAString& aUrl) {
|
||||||
|
CopyUTF8toUTF16(mPublicURL, aUrl);
|
||||||
|
}
|
||||||
|
|
||||||
bool PrecompiledScript::HasReturnValue() { return mHasReturnValue; }
|
bool PrecompiledScript::HasReturnValue() { return mHasReturnValue; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class PrecompiledScript : public nsISupports, public nsWrapperCache {
|
||||||
nsCOMPtr<nsISupports> mParent;
|
nsCOMPtr<nsISupports> mParent;
|
||||||
|
|
||||||
RefPtr<JS::Stencil> mStencil;
|
RefPtr<JS::Stencil> mStencil;
|
||||||
nsCString mURL;
|
nsCString mPublicURL;
|
||||||
const bool mHasReturnValue;
|
const bool mHasReturnValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,48 @@ add_task(async function test_syntaxError() {
|
||||||
SyntaxError);
|
SyntaxError);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function test_Error_filename() {
|
||||||
|
// This function will be serialized as a data:-URL and called.
|
||||||
|
function getMyError() {
|
||||||
|
let err = new Error();
|
||||||
|
return {
|
||||||
|
fileName: err.fileName,
|
||||||
|
stackFirstLine: err.stack.split("\n")[0],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const scriptUrl = `data:,(${encodeURIComponent(getMyError)})()`;
|
||||||
|
const dummyFilename = "dummy filename";
|
||||||
|
let script1 = await ChromeUtils.compileScript(scriptUrl, { hasReturnValue: true });
|
||||||
|
let script2 = await ChromeUtils.compileScript(scriptUrl, { hasReturnValue: true, filename: dummyFilename });
|
||||||
|
|
||||||
|
equal(script1.url, scriptUrl, "Script URL is correct");
|
||||||
|
equal(script2.url, "dummy filename", "Script URL overridden");
|
||||||
|
|
||||||
|
let sandbox = Cu.Sandbox("http://example.com");
|
||||||
|
let err1 = script1.executeInGlobal(sandbox);
|
||||||
|
equal(err1.fileName, scriptUrl, "fileName is original script URL");
|
||||||
|
equal(err1.stackFirstLine, `getMyError@${scriptUrl}:2:15`, "Stack has original URL");
|
||||||
|
|
||||||
|
let err2 = script2.executeInGlobal(sandbox);
|
||||||
|
equal(err2.fileName, dummyFilename, "fileName is overridden filename");
|
||||||
|
equal(err2.stackFirstLine, `getMyError@${dummyFilename}:2:15`, "Stack has overridden URL");
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_invalid_url() {
|
||||||
|
// In this test we want a URL that doesn't resolve to a valid file.
|
||||||
|
// Moreover, the name is chosen such that it does not trigger the
|
||||||
|
// CheckForBrokenChromeURL check.
|
||||||
|
await Assert.rejects(
|
||||||
|
ChromeUtils.compileScript("resource:///invalid.ftl"),
|
||||||
|
/^Unable to load script: resource:\/\/\/invalid\.ftl$/
|
||||||
|
);
|
||||||
|
|
||||||
|
await Assert.rejects(
|
||||||
|
ChromeUtils.compileScript("resource:///invalid.ftl", { filename: "bye bye" }),
|
||||||
|
/^Unable to load script: bye bye$/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assert that executeInGlobal throws a special exception when the content script throws.
|
* Assert that executeInGlobal throws a special exception when the content script throws.
|
||||||
* And the content script exception is notified to the console.
|
* And the content script exception is notified to the console.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue