From e17fb0e0740d92acfdcb83d61c081180b14c8e7b Mon Sep 17 00:00:00 2001 From: Gabriele Cimato Date: Mon, 2 Dec 2024 15:20:44 -0600 Subject: [PATCH] test: add coverage for mem check on setOwnStr --- object.go | 2 +- object_test.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/object.go b/object.go index 3ac2df1d..1bfd6a5f 100644 --- a/object.go +++ b/object.go @@ -548,7 +548,7 @@ func (o *baseObject) setOwnStr(name unistring.String, val Value, throw bool) boo o.val.runtime.typeErrorResult(throw, "Cannot add property %s, object is not extensible", name) return false } else { - if o.val.runtime.shouldForceMemCheck { + if o.val != nil && o.val.runtime != nil && o.val.runtime.shouldForceMemCheck { memCtx := newMemUsageContextClone() if memCtx != nil { memUsage, err := val.MemUsage(memCtx) diff --git a/object_test.go b/object_test.go index 1bfd35c7..4842b391 100644 --- a/object_test.go +++ b/object_test.go @@ -1,6 +1,7 @@ package goja import ( + "context" "fmt" "reflect" "strings" @@ -829,3 +830,63 @@ func TestPrimitiveValueObjectMemUsage(t *testing.T) { }) } } + +func TestSetOwnStr(t *testing.T) { + for _, tc := range []struct { + name string + memLimit uint64 + expectedPanic bool + shouldForceMemCheck bool + }{ + { + name: "should not panic when setting a value in an object", + memLimit: 1000, + expectedPanic: false, + shouldForceMemCheck: false, + }, + { + name: "should panic when setting a value in an object over the mem limit and mem usage check is forced", + memLimit: 0, + expectedPanic: true, + shouldForceMemCheck: true, + }, + { + name: "should not panic when setting a value in an object over the mem limit and mem usage check is not forced", + memLimit: 0, + expectedPanic: false, + shouldForceMemCheck: false, + }, + { + name: "should not panic when setting a value in an object under the mem limit and mem usage check is forced", + memLimit: 1000, + expectedPanic: false, + shouldForceMemCheck: true, + }, + } { + t.Run(tc.name, func(t *testing.T) { + defer func() { + r := recover() + if tc.expectedPanic && r == nil { + t.Error("The code is expected to panic, but it didn't") + } + if !tc.expectedPanic && r != nil { + t.Errorf("The code panicked, but it should not have: %v", r) + } + }() + v := &Object{ + runtime: NewWithContext(context.Background(), tc.shouldForceMemCheck), + } + o := &baseObject{ + val: v, + extensible: true, + } + o.init() + v.self = o + + // Creating a mem usage context so it populates the package variable + NewMemUsageContext(100, tc.memLimit, 100, 100, 0.5, nil) + + o.setOwnStr("test", valueInt(123), false) + }) + } +}