Skip to content

starlarkstruct Freeze() can cause a stack overflow if circular references are involved #566

Closed
@oprypin

Description

@oprypin

If starlarkstruct.Struct is exposed to the starlark environment, and one creates a struct with a circular reference, and causes it to be frozen, then there will be a stack overflow.

A module with this Starlark content should reproduce the issue, but I haven't double-checked that it actually does:

def make_struct():
    items = []
    foo = struct(items=items)
    foo.items.append(foo)
    return foo

toplevel = make_struct()

A fix for this issue could be done as follows:

--- a/starlarkstruct/struct.go
+++ b/starlarkstruct/struct.go
@@ -99,6 +99,7 @@ func FromStringDict(constructor starlark
 type Struct struct {
        constructor starlark.Value
        entries     entries // sorted by name
+       frozen      bool
 }
 
 // Default is the default constructor for structs.
@@ -172,8 +173,11 @@ func (s *Struct) Hash() (uint32, error) 
        return x, nil
 }
 func (s *Struct) Freeze() {
-       for _, e := range s.entries {
-               e.value.Freeze()
+       if !s.frozen {
+               s.frozen = true
+               for _, e := range s.entries {
+                       e.value.Freeze()
+               }
        }
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions