From 260559d48bc1442799f2affbd2476747fa9011e6 Mon Sep 17 00:00:00 2001 From: youdie006 Date: Mon, 28 Sep 2026 21:48:10 +0900 Subject: [PATCH] edit: skip values in HasKey HasKey read each key but not the value after it, so on the next pass it read the value as a key. A key after the first was missed and a string value matched as a key. Skip the value as locate and locateKV do. --- msgp/edit.go | 4 ++++ msgp/edit_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/msgp/edit.go b/msgp/edit.go index e5d86f93..fd90dc99 100644 --- a/msgp/edit.go +++ b/msgp/edit.go @@ -66,6 +66,10 @@ func HasKey(key string, raw []byte) bool { if UnsafeString(field) == key { return true } + bts, err = Skip(bts) + if err != nil { + return false + } } return false } diff --git a/msgp/edit_test.go b/msgp/edit_test.go index 77e69394..974dd838 100644 --- a/msgp/edit_test.go +++ b/msgp/edit_test.go @@ -83,6 +83,32 @@ func TestLocate(t *testing.T) { } } +func TestHasKey(t *testing.T) { + var buf bytes.Buffer + en := NewWriter(&buf) + en.WriteMapHeader(3) + en.WriteString("thing_one") + en.WriteString("value_one") + en.WriteString("thing_two") + en.WriteFloat64(2.0) + en.WriteString("thing_three") + en.WriteMapHeader(1) + en.WriteString("nested") + en.WriteInt(1) + en.Flush() + + for _, key := range []string{"thing_one", "thing_two", "thing_three"} { + if !HasKey(key, buf.Bytes()) { + t.Errorf("HasKey(%q) = false; want true", key) + } + } + for _, key := range []string{"value_one", "nested", "nope"} { + if HasKey(key, buf.Bytes()) { + t.Errorf("HasKey(%q) = true; want false", key) + } + } +} + func TestReplace(t *testing.T) { // there are 4 cases that need coverage: // - new value is smaller than old value