Open Bug 1023984 Opened 10 years ago Updated 3 months ago

Implement Xrays to Iterators

Categories

(Core :: XPConnect, task)

x86
macOS
task

Tracking

()

REOPENED

People

(Reporter: bholley, Unassigned)

References

(Blocks 3 open bugs)

Details

Right now, we don't have any special Xray support for iterators, so they end up creating objects in the target scope. This is a problem for iterators that produce things like [key, value] pairs, because the resulting Array gets Xrayed, and our filtering policy for Arrays ends up denying access to elements in pair.

This means that the following:

for (let [key, value] of someMap.entries())

can return various degenerate values, depending on what's in the Map. We should probably just not return such entries from the iterator, and adjust the size() of the Map appropriately.
Tom, do you want to take a stab at this one too?
Flags: needinfo?(evilpies)
I looked into this before and it's definitely annoying. Currently the iterators don't have ProtoKeys. The behavior of skipping values that aren't Xray described in comment 0 definitely needs special code as well. I would help anyone who wants to try this, but I will probably not do this before summer.
Flags: needinfo?(evilpies)
Per policy at https://wiki.mozilla.org/Bug_Triage/Projects/Bug_Handling/Bug_Husbandry#Inactive_Bugs. If this bug is not an enhancement request or a bug not present in a supported release of Firefox, then it may be reopened.
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → INACTIVE
Status: RESOLVED → REOPENED
Resolution: INACTIVE → ---
See Also: → 1770592
Severity: normal → S3

I haven't seen anyone commenting on workarounds.
For me, encountering the inability to iterate over URLSearchParameters.keys(), the alternative is to use URLSearchParameters.forEach().

That is, with code here that failed in a content script:

for (const k of url.searchParams.keys()) {
  console.log(k);
}

with TypeError: url.searchParams.keys() is not iterable

Instead the workaround was to use:

url.searchParams.forEach(v, k) => { console.log(k); });

It wasn't obvious to me that forEach() would work where keys() failed.

I also kind of wonder if it makes sense to mention this in
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/is_not_iterable
which doesn't seem to talk about bugs, or even in
https://discourse.mozilla.org/t/issue-with-the-urlsearchparams-interface-in-content-scripts/49253
which is easier to search for (at least for me).

Hopefully this is helpful to someone.

(In reply to Tom S [:evilpie] from comment #2)

I looked into this before and it's definitely annoying. Currently the
iterators don't have ProtoKeys. The behavior of skipping values that aren't
Xray described in comment 0 definitely needs special code as well. I would
help anyone who wants to try this, but I will probably not do this before
summer.

Tom, it's been a while but it looks like you were the last one to have a look at that. Because of this, we have to unwrap xrays from time to time in DevTools code, which we'd rather not do.
Would you have any time to look into that, or if not, some kind of plan for fixing this? Thanks!

Flags: needinfo?(evilpies)

We hit this issue once again when working around HighlightRegistry object, which is using MapLikeHelpers:
https://phabricator.services.mozilla.com/D184551#inline-1029198

I currently don't plan to work on this.

Flags: needinfo?(evilpies)
Type: defect → task

This affects Greasemonkey, which executes user scripts in a content script via tabs.executeScript().

  1. Install Greasemonkey if necessary ( https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ )
  2. Open its menu, select 'new user script'
  3. Copy the example from https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/values#examples ; append it to the end of this new script, save
  4. Open the console and (re)load any page

Result, e.g.:

Script error in [Greasemonkey script null/Unnamed Script 701753; version 1]:
TypeError: searchParams.values() is not iterable

(and at that point an uncaught error causes the script to fail) There's no way I know of for any similar iterator JS API to work in such a context. It would be very nice for this to work as expected.

Greasemonkey prepends some helper code/boiler plate then passes the user script to executeScript() as is ( https://github.com/greasemonkey/greasemonkey/blob/master/src/bg/execute.js#L20 ). We do this to A) be able to support higher-than-web-content privileged APIs in user scripts and B) guarantee that these do not leak to the actual web content. I'm not aware of any other way we could do this.

You need to log in before you can comment on or make changes to this bug.