Closed Bug 1433502 Opened 6 years ago Closed 6 years ago

Assertion failure: getDenseCapacity() == 0, at js/src/vm/NativeObject-inl.h:356 with OOM

Categories

(Core :: JavaScript Engine, defect, P1)

x86_64
Linux
defect

Tracking

()

VERIFIED FIXED
mozilla62
Tracking Status
firefox-esr52 --- unaffected
firefox-esr60 --- wontfix
firefox60 --- wontfix
firefox61 --- wontfix
firefox62 --- verified

People

(Reporter: decoder, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: assertion, sec-moderate, testcase, Whiteboard: [jsbugmon:update,ignore][adv-main62+])

Attachments

(1 file)

The following testcase crashes on mozilla-central revision 329bfa4b804a (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --disable-profiling --enable-debug --enable-optimize, run with --fuzzing-safe):

var lfLogBuffer = `
//corefuzz-dcd-selectmode 7
//corefuzz-dcd-endofdata
Array(17000).join("\\n") +
"last = Error().lineNumber;"
//corefuzz-dcd-endofdata
//corefuzz-dcd-endofdata
//corefuzz-dcd-selectmode 11
Array.prototype.push(1);
Object.freeze([].__proto__);
`;
lfLogBuffer = lfLogBuffer.split('\n');
let lfPreamble = `
  Object.defineProperty(this, "fuzzutils", {});
  function untemplate(s) {
    return s.replace(/\\\\/g, '\\\\\\\\').replace(/\`/g, '\\\\\`').replace(/\\\$/g, '\\\\\$'); 
  }
`;
evaluate(lfPreamble);
var lfCodeBuffer = "";
var lfAccumulatedCode = lfPreamble;
while (true) {
    var line = lfLogBuffer.shift();
    if (line == null) {
        break;
    } else if (line == "//corefuzz-dcd-endofdata") {
        loadFile(lfCodeBuffer);
        lfCodeBuffer = "";
    } else if (line.indexOf("//corefuzz-dcd-selectmode ") === 0) {
        loadFile(line);
    } else {
        lfCodeBuffer += line + "\n";
    }
}
if (lfCodeBuffer) loadFile(lfCodeBuffer);
function loadFile(lfVarx) {
    if (lfVarx.indexOf("//corefuzz-dcd-selectmode ") === 0) {
        lfRunTypeId = parseInt(lfVarx.split(" ")[1]);
    } else {
        switch (lfRunTypeId) {
            case 7:
                eval(lfAccumulatedCode);
            case 11:
                oomTest(new Function(lfVarx));
        }
    }
    lfVarx = untemplate(lfVarx);
}


Backtrace:

received signal SIGSEGV, Segmentation fault.
0x0000000000547e30 in js::NativeObject::extendDenseElements (extra=1, requiredCapacity=7, cx=0x7ffff5f16000, this=0x7ffff4490080) at js/src/vm/NativeObject-inl.h:356
#0  0x0000000000547e30 in js::NativeObject::extendDenseElements (extra=1, requiredCapacity=7, cx=0x7ffff5f16000, this=0x7ffff4490080) at js/src/vm/NativeObject-inl.h:356
#1  js::NativeObject::ensureDenseElements (this=0x7ffff4490080, cx=0x7ffff5f16000, index=6, extra=1) at js/src/vm/NativeObject-inl.h:420
#2  0x0000000000547ff0 in js::NativeObject::setOrExtendDenseElements (this=0x7ffff4490080, cx=0x7ffff5f16000, start=6, vp=0x7ffff404a1c0, count=<optimized out>, updateTypes=<optimized out>) at js/src/vm/NativeObject-inl.h:443
#3  0x00000000005368a0 in js::array_push (cx=0x7ffff5f16000, argc=<optimized out>, vp=<optimized out>) at js/src/jsarray.cpp:2307
#4  0x00000000005782d1 in js::CallJSNative (cx=0x7ffff5f16000, native=0x536740 <js::array_push(JSContext*, unsigned int, JS::Value*)>, args=...) at js/src/jscntxtinlines.h:291
#5  0x000000000056c81f in js::InternalCallOrConstruct (cx=cx@entry=0x7ffff5f16000, args=..., construct=construct@entry=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:473
#6  0x000000000056cbfd in InternalCall (cx=0x7ffff5f16000, args=...) at js/src/vm/Interpreter.cpp:522
#7  0x0000000000560515 in js::CallFromStack (args=..., cx=<optimized out>) at js/src/vm/Interpreter.cpp:528
#8  Interpret (cx=0x7ffff5f16000, state=...) at js/src/vm/Interpreter.cpp:3096
#9  0x000000000056c3b5 in js::RunScript (cx=0x7ffff5f16000, state=...) at js/src/vm/Interpreter.cpp:423
#10 0x000000000056c8e7 in js::InternalCallOrConstruct (cx=cx@entry=0x7ffff5f16000, args=..., construct=construct@entry=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:495
#11 0x000000000056cbfd in InternalCall (cx=0x7ffff5f16000, args=...) at js/src/vm/Interpreter.cpp:522
#12 0x000000000056cd70 in js::Call (cx=<optimized out>, fval=..., fval@entry=..., thisv=..., thisv@entry=..., args=..., rval=...) at js/src/vm/Interpreter.cpp:541
#13 0x00000000009c17ab in JS_CallFunction (cx=0x7ffff5f16000, obj=..., fun=..., fun@entry=..., args=..., rval=..., rval@entry=...) at js/src/jsapi.cpp:2997
#14 0x00000000008c0610 in OOMTest (cx=0x7ffff5f16000, argc=<optimized out>, vp=<optimized out>) at js/src/builtin/TestingFunctions.cpp:1653
#15 0x00000000005782d1 in js::CallJSNative (cx=0x7ffff5f16000, native=0x8c0270 <OOMTest(JSContext*, unsigned int, JS::Value*)>, args=...) at js/src/jscntxtinlines.h:291
[...]
#24 0x00000000006557f3 in js::jit::DoCallFallback (cx=0x7ffff5f16000, frame=0x7fffffffc6e8, stub_=<optimized out>, argc=<optimized out>, vp=0x7fffffffc698, res=...) at js/src/jit/BaselineIC.cpp:2560
#25 0x00001a3724d0b62f in ?? ()
[...]
#47 0x0000000000000000 in ?? ()
rax	0x0	0
rbx	0x7ffff4490080	140737291812992
rcx	0x7ffff6c282ad	140737333330605
rdx	0x0	0
rsi	0x7ffff6ef7770	140737336276848
rdi	0x7ffff6ef6540	140737336272192
rbp	0x7fffffffa9c0	140737488333248
rsp	0x7fffffffa990	140737488333200
r8	0x7ffff6ef7770	140737336276848
r9	0x7ffff7fe4780	140737354024832
r10	0x58	88
r11	0x7ffff6b9e7a0	140737332766624
r12	0x6	6
r13	0x1	1
r14	0x7ffff5f16000	140737319624704
r15	0x7	7
rip	0x547e30 <js::NativeObject::ensureDenseElements(JSContext*, unsigned int, unsigned int)+272>
=> 0x547e30 <js::NativeObject::ensureDenseElements(JSContext*, unsigned int, unsigned int)+272>:	movl   $0x0,0x0
   0x547e3b <js::NativeObject::ensureDenseElements(JSContext*, unsigned int, unsigned int)+283>:	ud2



Not exactly sure what's going on here but assertions about dense and capacity sound potentially dangerous, so I'm marking this s-s until it has been triaged by JS devs. I was also not able to greatly simplify this testcase further.
Flags: needinfo?(jdemooij)
Blegh, this is similar to bug 1363150 and is the situation I mentioned in bug 1363150 comment 2: "we can end up with a non-extensible object with non-frozen elements".

So what's happening is that we OOM between calling PreventExtensions and ObjectElements::FreezeElements. Then later in NativeObject::extendDenseElements, we assert that non-extensible without frozen elements means capacity == 0.

I'm not sure how to fix this. Maybe SetIntegrityLevel should save the object's old shape and on OOM just restore it - that will hopefully ensure consistent behavior...
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:update]
JSBugMon: Bisection requested, result:
autoBisect shows this is probably related to the following changeset:

The first bad revision is:
changeset:   https://hg.mozilla.org/mozilla-central/rev/48078fb0fcc2
user:        André Bargull
date:        Fri Jun 02 12:04:31 2017 +0200
summary:     Bug 1368963 - Avoid extra calls to GetPropertyKeys() in Object.freeze/seal/preventExtensions. r=jandem

This iteration took 1.864 seconds to run.
André, would you please take a look?
Flags: needinfo?(andrebargull)
Priority: -- → P1
Is it possible to undo this call [1] to recover the old shape (and any other state which needs to be rolled back, if there are any additional changes which need to be undone, I don't really know what needs to be done here...) after OOM? Btw bug 1368963 only showed up as the regressor because it changed the allocation pattern, the original issue goes way back when the frozen-elements optimization was added.

[1] https://searchfox.org/mozilla-central/rev/74b7ffee403c7ffd05b8b476c411cbf11d134eb9/js/src/vm/JSObject.cpp#2734
Flags: needinfo?(andrebargull) → needinfo?(jorendorff)
This bug and bug 1394523 are somewhat similar. They're both complicated. When freezing an object, SetIntegrityLevel does this:

(1) Call PreventExtensions
(2) Freeze the (non-dense) properties
(3) Call FreezeElements

This can break in multiple ways:

(a) Bug 1394523: we OOM "between" (1) and (2). That results in a non-extensible but non-frozen object, confusing ProcessCallSiteObjOperation.
(b) This bug: OOM in (2) breaks the invariant that non-extensible objects have: frozen-elements || no-elements

I still think the simplest fix is probably for SetIntegrityLevel to record the object's old shape and then on all OOM paths restore that Shape, at least for native objects. One caveat here is that if we seal, PreventExtensions will *sparsify* dense elements so restoring the old shape would be invalid (it would lose all our elements). Fixable but requires some thought. One interesting fix/optimization here would be to just support sealed elements so we never have to sparsify :)
Attached patch PatchSplinter Review
Restoring the Shape (for native objects) on OOM fixes this bug and bug 1394523. Can you think of any cases where this would be wrong?
Assignee: nobody → jdemooij
Status: NEW → ASSIGNED
Flags: needinfo?(jdemooij)
Attachment #8973987 - Flags: review?(andrebargull)
Comment on attachment 8973987 [details] [diff] [review]
Patch

Review of attachment 8973987 [details] [diff] [review]:
-----------------------------------------------------------------

Pre-existing:
How problematic are these two lines for OOM situations? <https://searchfox.org/mozilla-central/rev/f30847c12e5fb13791401ed4330ced3e1b9c8d81/js/src/vm/JSObject.cpp#510-511>
Do we also need to roll back the MarkTypePropertyNonWritable call?


Clearing review for now, because of the two assertions below.

::: js/src/vm/JSObject.cpp
@@ +484,5 @@
> +    // On OOM, restore the object's old shape. See bug 1394523 and bug 1433502.
> +    auto restoreShape = MakeScopeExit([&] {
> +        if (cx->isThrowingOutOfMemory() && oldNativeShape) {
> +            NativeObject* nobj = &obj->as<NativeObject>();
> +            MOZ_ASSERT(nobj->lastProperty()->slotSpan() == oldNativeShape->slotSpan());

We can't call Shape::slotSpan() for dictionary objects here:
---
function f(a) {
    return arguments;
}
oomTest(function() {
    var mapped = f(1,2,3,4,5,6,7,8,9,0);
    try { Object.freeze(mapped); } catch {}
    assertEq(mapped[0], 1);
});
---

Asserts with:
---
0x0000000000549ff0 in js::Shape::slotSpan (this=0x7ffff4fb2970, clasp=0x2979670 <js::MappedArgumentsObject::class_>) at /home/andre/hg/mozilla-inbound/js/src/vm/Shape.h:1018
1018            MOZ_ASSERT(!inDictionary());
(gdb) bt
#0  0x0000000000549ff0 in js::Shape::slotSpan(js::Class const*) const (this=0x7ffff4fb2970, clasp=0x2979670 <js::MappedArgumentsObject::class_>) at /home/andre/hg/mozilla-inbound/js/src/vm/Shape.h:1018
#1  0x0000000000549ce5 in js::Shape::slotSpan() const (this=0x7ffff4fb2970) at /home/andre/hg/mozilla-inbound/js/src/vm/Shape.h:1027
#2  0x0000000000fcece0 in js::SetIntegrityLevel(JSContext*, JS::Handle<JSObject*>, js::IntegrityLevel)::$_0::operator()() const (this=0x7fffffff60f8)
    at /home/andre/hg/mozilla-inbound/js/src/vm/JSObject.cpp:488
#3  0x0000000000fb5177 in mozilla::ScopeExit<js::SetIntegrityLevel(JSContext*, JS::Handle<JSObject*>, js::IntegrityLevel)::$_0>::~ScopeExit() (this=0x7fffffff60f8)
    at /home/andre/hg/mozilla-inbound/js/src/build-debug-obj/dist/include/mozilla/ScopeExit.h:113
...
---

@@ +485,5 @@
> +    auto restoreShape = MakeScopeExit([&] {
> +        if (cx->isThrowingOutOfMemory() && oldNativeShape) {
> +            NativeObject* nobj = &obj->as<NativeObject>();
> +            MOZ_ASSERT(nobj->lastProperty()->slotSpan() == oldNativeShape->slotSpan());
> +            nobj->setShape(oldNativeShape);

I'm not sure resetting the shape will work correctly for all objects, for example MappedArgumentsObject come to my mind. 

Later...

This test with functions seems to break.
---
var descs = {
    a: {configurable: true},
    b: {configurable: true},
    c: {configurable: true},
    d: {configurable: true},
    e: {configurable: true},
    f: {configurable: true},
    g: {configurable: true},
    h: {configurable: true},
    i: {configurable: true},
    j: {configurable: true},
    k: {configurable: true},
    l: {configurable: true},
    m: {configurable: true},
    n: {configurable: true},
    o: {configurable: true},
    p: {configurable: true},
    q: {configurable: true},
};

function test() {
    function fn(){}
    Object.defineProperties(fn, descs);
    delete fn.i;

    var frozen;
    try { Object.freeze(fn); frozen = true; } catch { frozen = false; }
    if (!frozen) {
        // dumpObject(fn);
    }
}

oomTest(test);
---


Asserts with:
---
0x00000000006b42ca in js::BaseShape::slotSpan (this=0x7ffff4f89160) at /home/andre/hg/mozilla-inbound/js/src/vm/Shape.h:552
552         uint32_t slotSpan() const { MOZ_ASSERT(isOwned()); return slotSpan_; }
(gdb) bt
#0  0x00000000006b42ca in js::BaseShape::slotSpan() const (this=0x7ffff4f89160) at /home/andre/hg/mozilla-inbound/js/src/vm/Shape.h:552
#1  0x00000000006b417f in js::NativeObject::slotSpan() const (this=(const js::NativeObject *) 0x7ffff7e015a0 [object Function "fn"]) at /home/andre/hg/mozilla-inbound/js/src/vm/NativeObject.h:723
#2  0x0000000000908605 in js::NativeObject::numDynamicSlots() const (this=(const js::NativeObject *) 0x7ffff7e015a0 [object Function "fn"])
    at /home/andre/hg/mozilla-inbound/js/src/vm/NativeObject-inl.h:585
#3  0x000000000154f82a in js::TenuringTracer::moveSlotsToTenured(js::NativeObject*, js::NativeObject*) (this=0x7fffffffcde0, dst=(js::NativeObject *) 0x7ffff4faf840 [object Function "fn"], src=(js::NativeObject *) 0x7ffff7e015a0 [object Function "fn"]) at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:3133
#4  0x000000000154e100 in js::TenuringTracer::moveToTenuredSlow(JSObject*) (this=0x7fffffffcde0, src=(JSObject *) 0x7ffff7e015a0 [object Function "fn"])
    at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:3062
#5  0x000000000154dddc in js::TenuringTracer::traverse<JSObject>(JSObject**) (this=0x7fffffffcde0, objp=0x7fffffffcb08) at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:2717
#6  0x000000000159a504 in js::TenuringTraversalFunctor<JS::Value>::operator()<JSObject>(JSObject*, js::TenuringTracer*) (this=0x7fffffffcb80, t=(JSObject *) 0x7ffff7e015a0 [object Function "fn"], trc=0x7fffffffcde0) at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:2735
#7  0x000000000159a2d3 in _ZN2js13DispatchTypedINS_24TenuringTraversalFunctorIN2JS5ValueEEEJPNS_14TenuringTracerEEEEDTclfp_scP8JSObjectLDnEspclsr7mozillaE7ForwardIT0_Efp1_EEET_RKS3_DpOS9_ (f=..., val=..., args=<unknown type in /home/andre/hg/mozilla-inbound/js/src/build-debug-obj/dist/bin/js, CU 0x43fafd5, DIE 0x449fa15>)
    at /home/andre/hg/mozilla-inbound/js/src/build-debug-obj/dist/include/js/Value.h:1374
#8  0x00000000015877b8 in js::TenuringTracer::traverse<JS::Value>(JS::Value*) (this=0x7fffffffcde0, thingp=0x7ffff4c6a840) at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:2744
#9  0x000000000154f577 in js::TenuringTracer::traceSlots(JS::Value*, JS::Value*) (this=0x7fffffffcde0, vp=0x7ffff4c6a840, end=0x7ffff4c6a848) at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:2967
#10 0x000000000154eb4e in js::TenuringTracer::traceObjectSlots(js::NativeObject*, unsigned int, unsigned int) (this=0x7fffffffcde0, nobj=(js::NativeObject *) 0x7ffff4f8e220 [object Object], start=0, length=1) at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:2960
#11 0x000000000154e912 in js::gc::StoreBuffer::SlotsEdge::trace(js::TenuringTracer&) const (this=0x7ffff5baa188, mover=...) at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:2801
#12 0x0000000001586baa in js::gc::StoreBuffer::MonoTypeBuffer<js::gc::StoreBuffer::SlotsEdge>::trace(js::gc::StoreBuffer*, js::TenuringTracer&) (this=0x7ffff5b1c4f8, owner=0x7ffff5b1c448, mover=...)
    at /home/andre/hg/mozilla-inbound/js/src/gc/Marking.cpp:2758
#13 0x000000000158d357 in js::gc::StoreBuffer::traceSlots(js::TenuringTracer&) (this=0x7ffff5b1c448, mover=...) at /home/andre/hg/mozilla-inbound/js/src/gc/StoreBuffer.h:495
#14 0x0000000001557432 in js::Nursery::doCollection(JS::gcreason::Reason, js::gc::TenureCountCache&) (this=0x7ffff5b1c078, reason=JS::gcreason::DESTROY_RUNTIME, tenureCounts=...)
    at /home/andre/hg/mozilla-inbound/js/src/gc/Nursery.cpp:879
#15 0x0000000001556902 in js::Nursery::collect(JS::gcreason::Reason) (this=0x7ffff5b1c078, reason=JS::gcreason::DESTROY_RUNTIME) at /home/andre/hg/mozilla-inbound/js/src/gc/Nursery.cpp:736
#16 0x00000000014d1528 in js::gc::GCRuntime::minorGC(JS::gcreason::Reason, js::gcstats::PhaseKind) (this=0x7ffff5b19700, reason=JS::gcreason::DESTROY_RUNTIME, phase=js::gcstats::PhaseKind::EVICT_NURSERY_FOR_MAJOR_GC) at /home/andre/hg/mozilla-inbound/js/src/gc/GC.cpp:7820
#17 0x00000000014d0ee8 in js::gc::GCRuntime::gcCycle(bool, js::SliceBudget&, JS::gcreason::Reason) (this=0x7ffff5b19700, nonincrementalByAPI=true, budget=..., reason=JS::gcreason::DESTROY_RUNTIME)
    at /home/andre/hg/mozilla-inbound/js/src/gc/GC.cpp:7425
#18 0x00000000014d1dd4 in js::gc::GCRuntime::collect(bool, js::SliceBudget, JS::gcreason::Reason) (this=0x7ffff5b19700, nonincrementalByAPI=true, budget=..., reason=JS::gcreason::DESTROY_RUNTIME)
    at /home/andre/hg/mozilla-inbound/js/src/gc/GC.cpp:7616
#19 0x00000000014b2a47 in js::gc::GCRuntime::gc(JSGCInvocationKind, JS::gcreason::Reason) (this=0x7ffff5b19700, gckind=GC_NORMAL, reason=JS::gcreason::DESTROY_RUNTIME)
    at /home/andre/hg/mozilla-inbound/js/src/gc/GC.cpp:7686
#20 0x00000000010a9a9d in JSRuntime::destroyRuntime() (this=0x7ffff5b19000) at /home/andre/hg/mozilla-inbound/js/src/vm/Runtime.cpp:315
#21 0x0000000000fa14eb in js::DestroyContext(JSContext*) (cx=0x7ffff5b17000) at /home/andre/hg/mozilla-inbound/js/src/vm/JSContext.cpp:201
#22 0x0000000000d8d8a5 in JS_DestroyContext(JSContext*) (cx=0x7ffff5b17000) at /home/andre/hg/mozilla-inbound/js/src/jsapi.cpp:496
#23 0x000000000044c1ff in main(int, char**, char**) (argc=2, argv=0x7fffffffd8a8, envp=0x7fffffffd8c0) at /home/andre/hg/mozilla-inbound/js/src/shell/js.cpp:9301
---

@@ +584,3 @@
>      // Finally, freeze the dense elements.
> +    if (level == IntegrityLevel::Frozen && obj->isNative())
> +        ObjectElements::FreezeElements(cx, obj.as<NativeObject>());

Does it make sense to use |&obj->as<NativeObject>()| to avoid creating a temporary HandleObject?

@@ +2785,5 @@
> +
> +        // Before we make observable changes to this native object, record the
> +        // current shape so the caller can use it to recover from OOM.
> +        if (oldShape)
> +            *oldShape = obj.as<NativeObject>()->shape();

Nit: Switch `->` and `.`? I.e. |*oldShape = obj->as<NativeObject>().shape();|
Attachment #8973987 - Flags: review?(andrebargull)
(In reply to André Bargull [:anba] from comment #8)
> Pre-existing:
> How problematic are these two lines for OOM situations?
> <https://searchfox.org/mozilla-central/rev/
> f30847c12e5fb13791401ed4330ced3e1b9c8d81/js/src/vm/JSObject.cpp#510-511>
> Do we also need to roll back the MarkTypePropertyNonWritable call?

Worst-case we tell TI the property *might* be non-writable but then we OOM and don't actually have an object with a non-writable property there. That's fine (it's similar to having 2 objects with the same ObjectGroup and same properties, then freezing one of them but not the other).

Thanks for the thorough review!
(In reply to Jan de Mooij [:jandem] from comment #9)
> Worst-case we tell TI the property *might* be non-writable but then we OOM
> and don't actually have an object with a non-writable property there. That's
> fine (it's similar to having 2 objects with the same ObjectGroup and same
> properties, then freezing one of them but not the other).

Ah, I see. Thanks for the explanation!
Rolling back the shape is probably not the right approach considering cases like MappedArgumentsObject...

It feels to me like a lot of the complexity comes from the fact that dense elements can only be *frozen* but not made non-extensible or sealed. I think if PreventExtensions immediately marked the elements as non-extensible, a lot of this would be simpler. It would also be much faster when using preventExtensions/seal on objects with elements.

I'll try this now.
Supporting non-extensible (and sealed) elements makes this a lot nicer. PreventExtensions then just sets the object flag + (infallibly) sets the non-extensible flag on the ObjectElements. Then SetIntegrityLevel will additionally mark the elements as sealed (and frozen if needed).

Then the "non-extensible object with extensible elements" issue can no longer happen and it really simplifies the code IMO, in addition to being faster.

Will file a public bug later today.
Whiteboard: [jsbugmon:update] → [jsbugmon:update,ignore]
JSBugMon: The testcase found in this bug no longer reproduces (tried revision a7461494a7a0).
(In reply to Fuzzing Team from comment #14)
> JSBugMon: The testcase found in this bug no longer reproduces (tried
> revision a7461494a7a0).

Yeah this was fixed by bug 1460381. I don't think this OOM bug was actually security sensitive so that patch should just ride the trains.
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Status: RESOLVED → VERIFIED
JSBugMon: This bug has been automatically verified fixed.
Flags: needinfo?(jorendorff)
Target Milestone: --- → mozilla62
Group: javascript-core-security → core-security-release
Whiteboard: [jsbugmon:update,ignore] → [jsbugmon:update,ignore][adv-main62+]
Group: core-security-release
Assignee: jdemooij → nobody
Keywords: bugmon
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: