Skip to content

encoding/json/v2: WithinArshalCall check does not work for nested calls #80116

Description

@dsnet

There's an internal WithinArshalCall flag that the "json" implementation sets whenever calling a user-provided marshaler or unmarshaler. The purpose of this flag is as a sanity check that causes Encoder.Reset and Decoder.Reset to panic.

This check doesn't work for nested marshaler calls since inner call will clear the flag. We should either drop the check (since it's only as a sanity protection) or fix it such that it only clears the flag if it was able to set it in the first place.

Thus instead of:

https://github.com/go-json-experiment/json/blob/60a0516c28953eb838073b7951a726fa12003537/arshal_methods.go#L195-L197

It'd be something like:

if !xe.Flags.Get(jsonflags.WithinArshalCall) {
     xe.Flags.Set(jsonflags.WithinArshalCall | 1) 
     defer func() { xe.Flags.Set(jsonflags.WithinArshalCall | 0) }
}
err := va.Addr().Interface().(MarshalerTo).MarshalJSONTo(enc, mo) 

Overall, this is a pretty minor bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Post-proposal

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions