Bug 2024854 Part 1 - Add content policies for text modules. r=extension-reviewers,dom-worker-reviewers,tschuster,asuth,robwu

Differential Revision: https://phabricator.services.mozilla.com/D295486
This commit is contained in:
Eemeli Aro
2026-05-06 07:23:58 +00:00
committed by earo@mozilla.com
parent af1858ea0b
commit b577fd2016
8 changed files with 132 additions and 3 deletions
+3 -1
View File
@@ -69,6 +69,8 @@
NAME(TYPE_INTERNAL_XMLHTTPREQUEST_SYNC) \
NAME(TYPE_INTERNAL_EXTERNAL_RESOURCE) \
NAME(TYPE_JSON) \
NAME(TYPE_INTERNAL_JSON_PRELOAD)
NAME(TYPE_INTERNAL_JSON_PRELOAD) \
NAME(TYPE_TEXT) \
NAME(TYPE_INTERNAL_TEXT_PRELOAD)
#endif // nsContentPolicyType_h
+4
View File
@@ -3870,6 +3870,9 @@ nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType) {
case nsIContentPolicy::TYPE_INTERNAL_JSON_PRELOAD:
return ExtContentPolicy::TYPE_JSON;
case nsIContentPolicy::TYPE_INTERNAL_TEXT_PRELOAD:
return ExtContentPolicy::TYPE_TEXT;
case nsIContentPolicy::TYPE_INVALID:
case nsIContentPolicy::TYPE_OTHER:
case nsIContentPolicy::TYPE_SCRIPT:
@@ -3897,6 +3900,7 @@ nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType) {
case nsIContentPolicy::TYPE_WEB_IDENTITY:
case nsIContentPolicy::TYPE_WEB_TRANSPORT:
case nsIContentPolicy::TYPE_JSON:
case nsIContentPolicy::TYPE_TEXT:
// NOTE: When adding something here make sure the enumerator is defined!
return static_cast<ExtContentPolicyType>(aType);
+15
View File
@@ -467,6 +467,20 @@ interface nsIContentPolicy : nsISupports
*/
TYPE_INTERNAL_IMAGE_NOTIFICATION = 64,
/**
* Indicates a text module loaded through an import statement.
*/
TYPE_TEXT = 65,
/**
* Same as TYPE_TEXT but indicates an internal constant for a preloaded
* text module loaded through an import statement.
*
* This will be mapped to TYPE_TEXT before being passed to content policy
* implementations.
*/
TYPE_INTERNAL_TEXT_PRELOAD = 66,
/* When adding new content types, please update
* nsCSPContext, CSP_ContentTypeToDirective,
* DoContentSecurityChecks, all nsIContentPolicy implementations, the
@@ -614,6 +628,7 @@ enum class ExtContentPolicyType : uint8_t {
TYPE_WEB_IDENTITY = nsIContentPolicy::TYPE_WEB_IDENTITY,
TYPE_WEB_TRANSPORT = nsIContentPolicy::TYPE_WEB_TRANSPORT,
TYPE_JSON = nsIContentPolicy::TYPE_JSON,
TYPE_TEXT = nsIContentPolicy::TYPE_TEXT,
};
typedef ExtContentPolicyType ExtContentPolicy;
+3 -1
View File
@@ -391,7 +391,9 @@ static_assert(
nsIContentPolicy::TYPE_INTERNAL_EXTERNAL_RESOURCE == 61 &&
nsIContentPolicy::TYPE_JSON == 62 &&
nsIContentPolicy::TYPE_INTERNAL_JSON_PRELOAD == 63 &&
nsIContentPolicy::TYPE_INTERNAL_IMAGE_NOTIFICATION == 64,
nsIContentPolicy::TYPE_INTERNAL_IMAGE_NOTIFICATION == 64 &&
nsIContentPolicy::TYPE_TEXT == 65 &&
nsIContentPolicy::TYPE_INTERNAL_TEXT_PRELOAD == 66,
"nsContentPolicyType values are as expected");
namespace {
@@ -0,0 +1,98 @@
"use strict";
const server = createHttpServer({ hosts: ["example.com"] });
const staticImportHtml = `
<!DOCTYPE html>
<html lang="en">
<meta charset=utf-8>
<body>
<script type="module">
import text from './test.txt' with { type: 'text' };
</script>
</body></html>`;
const dynamicImportHtml = `
<!DOCTYPE html>
<html lang="en">
<meta charset=utf-8>
<body>
<script type="module">
import('./test.txt', { with: { type: 'text' } });
</script>
</body></html>`;
server.registerPathHandler("/static-import.html", (request, response) => {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "text/html", false);
response.write(staticImportHtml);
});
server.registerPathHandler("/dynamic-import.html", (request, response) => {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "text/html", false);
response.write(dynamicImportHtml);
});
server.registerPathHandler("/test.txt", (request, response) => {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "text/plain", false);
response.write("hello");
});
add_task(async function test_static_import() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
permissions: ["webRequest", "webRequestBlocking", "<all_urls>"],
},
background() {
browser.webRequest.onBeforeRequest.addListener(
async details => {
browser.test.assertEq("other", details.type);
browser.test.notifyPass("webRequest");
},
{ urls: ["*://example.com/test.txt"] },
["blocking"]
);
},
});
await extension.startup();
let contentPage = await ExtensionTestUtils.loadContentPage(
"http://example.com/static-import.html"
);
await extension.awaitFinish("webRequest");
await extension.unload();
await contentPage.close();
});
add_task(async function test_dynamic_import() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
permissions: ["webRequest", "webRequestBlocking", "<all_urls>"],
},
background() {
browser.webRequest.onBeforeRequest.addListener(
async details => {
browser.test.assertEq("http://example.com/test.txt", details.url);
browser.test.assertEq("other", details.type);
browser.test.notifyPass("webRequest");
},
{ urls: ["<all_urls>"], types: ["other"] },
["blocking"]
);
},
});
await extension.startup();
let contentPage = await ExtensionTestUtils.loadContentPage(
"http://example.com/dynamic-import.html"
);
await extension.awaitFinish("webRequest");
await extension.unload();
await contentPage.close();
});
@@ -873,6 +873,12 @@ skip-if = [
["test_ext_webRequest_type_json.js"]
["test_ext_webRequest_type_text.js"]
prefs = ["javascript.options.experimental.import_text=true"]
skip-if = [
"!nightly_build",
]
["test_ext_webRequest_userContextId.js"]
["test_ext_webRequest_viewsource.js"]
@@ -892,6 +892,7 @@ MozContentPolicyType GetContentPolicyType(ExtContentPolicyType aType) {
return MozContentPolicyType::Speculative;
case ExtContentPolicy::TYPE_JSON:
return MozContentPolicyType::Json;
case ExtContentPolicy::TYPE_TEXT:
case ExtContentPolicy::TYPE_PROXIED_WEBRTC_MEDIA:
case ExtContentPolicy::TYPE_INVALID:
case ExtContentPolicy::TYPE_OTHER:
+2 -1
View File
@@ -1951,7 +1951,8 @@ declare enum nsIContentPolicy_nsContentPolicyType {
TYPE_JSON = 62,
TYPE_INTERNAL_JSON_PRELOAD = 63,
TYPE_INTERNAL_IMAGE_NOTIFICATION = 64,
TYPE_END = 65,
TYPE_TEXT = 65,
TYPE_INTERNAL_TEXT_PRELOAD = 66,
}
declare global {