Non Pointer Unmarshal
ID |
go.non_pointer_unmarshal |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Go |
Tags |
reliability, suspicious |
Description
Reports an Unmarshal or Decode call (json.Unmarshal, xml.Unmarshal, a decoder’s
Decode, …) whose destination argument is clearly not a pointer — a composite literal or a
plain value variable passed without taking its address. These functions write the decoded
data through the destination pointer; a non-pointer destination is passed by value, so the
result is written into a copy and silently discarded.
Rationale
json.Unmarshal(data, v) where v is a value (not &v) returns an error at runtime
(json: Unmarshal(non-pointer …)), and decoder.Decode(v) behaves the same way. The
mistake is easy to make when refactoring or copying examples, and because the value compiles,
it only surfaces as an empty struct or a runtime error. Flagging the obvious non-pointer
destinations catches the bug at build time.
json.Unmarshal(data, v) // FLAW — v is a value; decode is discarded
json.Unmarshal(data, Config{}) // FLAW — composite literal can never receive the result
json.Unmarshal(data, &v) // OK — address of the destination
json.Unmarshal(data, p) // OK — p is already a pointer
Remediation
Pass the address of the destination: json.Unmarshal(data, &v). If the destination is
already a pointer, no change is needed.