Open Bug 1958378 Opened 20 days ago Updated 16 days ago

Web Accessible Resource paths are prefixed with a slash in MV3

Categories

(WebExtensions :: Compatibility, defect, P5)

Firefox 139
defect

Tracking

(Not tracked)

People

(Reporter: dotproto, Unassigned)

Details

A developer on Discourse noted that web accessible resource strings returned by browser.runtime.getManifest() have a slash (/) prefix in MV3, but do not in MV2. This creates a compatibility issue for extensions or libraries that assume that resource strings will be returned as authored.

Reproduction steps

  1. Install the dnr-redirect-url example from https://github.com/mdn/webextensions-examples/blob/main/dnr-redirect-url as a temporary extension.
  2. Using the link from about:debugging, open the extension's manifest.json file in a new tab and note that
  3. Open developer tools and execute browser.runtime.getManifest().web_accessible_resources[0].resources[0]

Expected behavior
The string returned should appear as authored in manifest.json. (This matches how Firefox handles MV2 extensions.)

Observed behavior
The string returned as a leading /.

This appears to be caused by a bug in ExtensionData.parseManifest() from toolkit/components/extensions/Extension.sys.mjs

/* 01 */      if (manifest.web_accessible_resources) {
/* 02 */        // Normalize into V3 objects
/* 03 */        let wac =
/* 04 */          this.manifestVersion >= 3
/* 05 */            ? manifest.web_accessible_resources
/* 06 */            : [{ resources: manifest.web_accessible_resources }];
/* 07 */        webAccessibleResources.push(
/* 08 */          ...wac.map(obj => {
/* 09 */            obj.resources = obj.resources.map(path =>
/* 10 */              path.replace(/^\/*/, "/")
/* 11 */            );
/* 12 */            return obj;
/* 13 */          })
/* 14 */        );
/* 15 */      }

Line 5 stores a reference to manifest.web_accessible_resources, and the resources property of that object is later mutated in line 9. I think the most direct fix would be to clone the manifest.web_accessible_resources object.

            this.manifestVersion >= 3
-             ? manifest.web_accessible_resources
+             ? structuredClone(manifest.web_accessible_resources)
              : [{ resources: manifest.web_accessible_resources }];

This alternate implementation attempts to maintain the same coding style as the original implementation while also addressing the object reuse issue.

          webAccessibleResources.push(
-           ...wac.map(obj => {
-             obj.resources = obj.resources.map(path =>
-               path.replace(/^\/*/, "/")
-             );
-             return obj;
-           })
+           ...wac.map(obj => ({
+             ...obj,
+             resources: obj.resources.map(path =>
+               path.replace(/^\/*/, "/")
+             )
+           }))
          );

In Firefox the value of getManifest() returns the normalized value.

In this specific case the transformation is likely an unintended implementation detail (introduced in bug 1696580).

Severity: -- → S4
Priority: -- → P5
You need to log in before you can comment on or make changes to this bug.