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";
|
||||
|
||||
/**
|
||||
* 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
|
||||
* they are used, rather than eagerly parsed at load time.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ interface PrecompiledScript {
|
|||
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]
|
||||
readonly attribute DOMString url;
|
||||
|
|
|
|||
|
|
@ -292,7 +292,14 @@ nsresult AsyncScriptCompiler::Start(
|
|||
mCharset = aOptions.mCharset;
|
||||
|
||||
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) {
|
||||
options.setForceFullParse();
|
||||
|
|
@ -418,7 +425,8 @@ void AsyncScriptCompiler::Reject(JSContext* aCx, const char* aMsg) {
|
|||
nsAutoString msg;
|
||||
msg.AppendASCII(aMsg);
|
||||
msg.AppendLiteral(": ");
|
||||
AppendUTF8toUTF16(mURL, msg);
|
||||
nsDependentCString filename(mOptions.filename().c_str());
|
||||
AppendUTF8toUTF16(filename, msg);
|
||||
|
||||
RootedValue exn(aCx);
|
||||
if (xpc::NonVoidStringToJsval(aCx, msg, &exn)) {
|
||||
|
|
@ -501,7 +509,7 @@ PrecompiledScript::PrecompiledScript(nsISupports* aParent,
|
|||
JS::ReadOnlyCompileOptions& aOptions)
|
||||
: mParent(aParent),
|
||||
mStencil(aStencil),
|
||||
mURL(aOptions.filename().c_str()),
|
||||
mPublicURL(aOptions.filename().c_str()),
|
||||
mHasReturnValue(!aOptions.noScriptRval) {
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(aStencil);
|
||||
|
|
@ -551,7 +559,9 @@ void PrecompiledScript::ExecuteInGlobal(JSContext* aCx, HandleObject aGlobal,
|
|||
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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class PrecompiledScript : public nsISupports, public nsWrapperCache {
|
|||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
RefPtr<JS::Stencil> mStencil;
|
||||
nsCString mURL;
|
||||
nsCString mPublicURL;
|
||||
const bool mHasReturnValue;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,48 @@ add_task(async function test_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.
|
||||
* And the content script exception is notified to the console.
|
||||
|
|
|
|||
Loading…
Reference in a new issue