| 174 | } |
| 175 | |
| 176 | func FuzzUnmarshalFieldIsolation(f *testing.F) { |
| 177 | // Add seed corpus. |
| 178 | f.Add("other", "value") |
| 179 | f.Add("safe", "overwrite") |
| 180 | f.Add("safe\x00", "attack") |
| 181 | |
| 182 | f.Fuzz(func(t *testing.T, key, val string) { |
| 183 | // Generate valid JSON with the fuzzed key and value. |
| 184 | var buf bytes.Buffer |
| 185 | enc := json.NewEncoder(&buf) |
| 186 | enc.SetEscapeHTML(false) |
| 187 | if err := enc.Encode(key); err != nil { |
| 188 | return |
| 189 | } |
| 190 | encodedKey := buf.Bytes() |
| 191 | buf.Reset() |
| 192 | if err := enc.Encode(val); err != nil { |
| 193 | return |
| 194 | } |
| 195 | encodedVal := buf.Bytes() |
| 196 | |
| 197 | jsonData := fmt.Sprintf(`{"safe": "value", %s: %s}`, encodedKey, encodedVal) |
| 198 | |
| 199 | type Target struct { |
| 200 | Safe string `json:"safe"` |
| 201 | } |
| 202 | |
| 203 | var got Target |
| 204 | if err := Unmarshal([]byte(jsonData), &got); err != nil { |
| 205 | return |
| 206 | } |
| 207 | |
| 208 | if got.Safe != "value" && key != "safe" { |
| 209 | t.Errorf("Field 'safe' improperly modified by key %q (JSON: %s). Got %q, want %q", key, encodedKey, got.Safe, "value") |
| 210 | } |
| 211 | }) |
| 212 | } |