Closed Bug 1134112 Opened 9 years ago Closed 9 years ago

MOZ_ASSERT(mType == eUninitialized) in OwningStringOrStringSequenceOrConstrainDOMStringParameters

Categories

(Core :: DOM: Core & HTML, defect)

34 Branch
x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla38
Tracking Status
firefox38 --- fixed

People

(Reporter: jib, Assigned: bzbarsky)

References

()

Details

Attachments

(3 files)

Attached file lldb mochitest output
STR:
- Build with first two patches in Bug 1119335.
- mochitest dom/media/tests/mochitest/test_getUserMedia_constraints.html

See attached mochitest output and try [1]. From what I can tell, there's just binding code involved. Assert seems provoked by JS call mozGetUserMedia({ video: { facingMode:{ exact:'left' } }) with this new webidl union:

  typedef (DOMString or sequence<DOMString> or ConstrainDOMStringParameters) ConstrainDOMString;

[1] https://treeherder.mozilla.org/#/jobs?repo=try&revision=ac146fa48426
Hmm.  So the problem here is that we have a non-fast dictionary (e.g. a dictionary in a another dictionary or in a sequence) which has a member which is a union between a sequence and a dictionary.  Simple testcase:

  dictionary Foo {
  };
  dictionary Bar {
    (sequence<long> or Foo) m;
  };
  interface Baz {
    void func(sequence<Bar> arg);
  }

and then invoking:

  func([{ m: {} }])

What happens here is that when we'd doing the outermost sequence we append a Bar to the array.  This runs the Bar constructor (note: not the FastBar constructor), which does an Init() on Bar with a null value, so init to default values.

Unfortunately, the "m" member of Bar is a union with a default value (null, because it contains a dictionary).  So this initializes the union to contain the dictionary.

Then we go ahead and init Bar _again_ with the value we really plan to use.  This tries to init the union to a type different from the one it contains, but using the RawSetAs* version of the type setter, which asserts.

So.  Ways to fix this bug:

1)  Change the sequence-of-dictionaries case to call the non-initing dictionary constructor somehow.  Also, change dictionaries with dictionary members to call the non-initing constructor of their members when their own non-initing constructor is called.  I _think_ this should be sufficient.

2)  Change dictionary init of union members to always uninit the union before trying to init it, just to be safe.

I'd guess approach #2 is safer, while approach #1 is likely a bit faster and the part about not initing members if we're not supposed to init is less suprising.  Of course maybe we want to do both...
Or more precisely change dictionary init of union members with default values to always uninit.
Approach #1 would not have worked, because it fails if you have a union containing a dictionary containing a union containing a dictionary.  When the outer union is initialized as dictionary, it default-constructs the outer dictionary, which then inits it, which initializes the inner union.
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
Great, works! Thanks!

How good are the chances of this being reviewed and landed today or tomorrow? I was really hoping to land Bug 1119335 in 38. If this is not possible, then I should plan to compromise on the syntax a bit.
Flags: needinfo?(peterv)
Attachment #8566173 - Flags: review?(peterv) → review+
Attachment #8566175 - Flags: review?(peterv) → review+
https://hg.mozilla.org/mozilla-central/rev/18cb3176175c
https://hg.mozilla.org/mozilla-central/rev/2be7a90b66b9
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla38
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: