diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index cb60948768..7b73d31867 100644 --- a/openrtb_ext/request_wrapper.go +++ b/openrtb_ext/request_wrapper.go @@ -1278,9 +1278,7 @@ func (re *RegExt) unmarshal(extJson json.RawMessage) error { gpcJson, hasGPC := re.ext[gpcKey] if hasGPC && gpcJson != nil { - if err := jsonutil.Unmarshal(gpcJson, &re.gpc); err != nil { - return err - } + return jsonutil.ParseIntoString(gpcJson, &re.gpc) } return nil diff --git a/openrtb_ext/request_wrapper_test.go b/openrtb_ext/request_wrapper_test.go index 73851238d0..e4c14b6031 100644 --- a/openrtb_ext/request_wrapper_test.go +++ b/openrtb_ext/request_wrapper_test.go @@ -2344,6 +2344,20 @@ func TestRegExtUnmarshal(t *testing.T) { expectGPC: ptrutil.ToPtr("some_value"), expectError: false, }, + { + name: `valid_gpc_json_"1"`, + regExt: &RegExt{}, + extJson: json.RawMessage(`{"gpc": "1"}`), + expectGPC: ptrutil.ToPtr("1"), + expectError: false, + }, + { + name: `valid_gpc_json_1`, + regExt: &RegExt{}, + extJson: json.RawMessage(`{"gpc": 1}`), + expectGPC: ptrutil.ToPtr("1"), + expectError: false, + }, { name: "malformed_gpc_json", regExt: &RegExt{}, @@ -2377,6 +2391,7 @@ func TestRegExtUnmarshal(t *testing.T) { assert.Equal(t, tt.expectDSA, tt.regExt.dsa) assert.Equal(t, tt.expectGDPR, tt.regExt.gdpr) assert.Equal(t, tt.expectUSPrivacy, tt.regExt.usPrivacy) + assert.Equal(t, tt.expectGPC, tt.regExt.gpc) }) } } diff --git a/util/jsonutil/forcestring.go b/util/jsonutil/forcestring.go new file mode 100644 index 0000000000..64ce2a6795 --- /dev/null +++ b/util/jsonutil/forcestring.go @@ -0,0 +1,20 @@ +package jsonutil + +import ( + "errors" + + "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/tidwall/gjson" +) + +// ParseIntoString Parse json bytes into a string pointer +func ParseIntoString(b []byte, ppString **string) error { + if ppString == nil { + return errors.New("ppString is nil") + } + result := gjson.ParseBytes(b) + if result.Exists() && result.Raw != `null` { + *ppString = ptrutil.ToPtr(result.String()) + } + return nil +} diff --git a/util/jsonutil/forcestring_test.go b/util/jsonutil/forcestring_test.go new file mode 100644 index 0000000000..60f87fafa4 --- /dev/null +++ b/util/jsonutil/forcestring_test.go @@ -0,0 +1,61 @@ +package jsonutil + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/stretchr/testify/assert" +) + +func Test_ParseIntoString(t *testing.T) { + tests := []struct { + name string + b []byte + want *string + wantErr bool + }{ + { + name: "empty", + }, + { + name: "quoted_1", + b: []byte(`"1"`), + want: ptrutil.ToPtr("1"), + }, + { + name: "unquoted_1", + b: []byte(`1`), + want: ptrutil.ToPtr("1"), + }, + { + name: "null", + b: []byte(`null`), + }, + { + name: "quoted_null", + b: []byte(`"null"`), + want: ptrutil.ToPtr("null"), + }, + { + name: "quoted_hello", + b: []byte(`"hello"`), + want: ptrutil.ToPtr("hello"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got *string + err := ParseIntoString(tt.b, &got) + if tt.wantErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} + +func Test_ParseIntoNilStringError(t *testing.T) { + assert.Error(t, ParseIntoString([]byte(`"123"`), nil)) +}