Repository: prebid/prebid-server
Pull request #3284 (2023-11-07 22:05:54)

Fix for null string unmarshal error


Patch:
diff --git a/config/bidderinfo.go b/config/bidderinfo.go
index 45abc852..e4015b8e 100644
--- a/config/bidderinfo.go
+++ b/config/bidderinfo.go
@@ -605,6 +605,9 @@ func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos
 			if bidderInfo.EndpointCompression == "" && fsBidderCfg.EndpointCompression != "" {
 				bidderInfo.EndpointCompression = fsBidderCfg.EndpointCompression
 			}
+			if bidderInfo.OpenRTB == nil && fsBidderCfg.OpenRTB != nil {
+				bidderInfo.OpenRTB = fsBidderCfg.OpenRTB
+			}
 
 			fsBidderInfos[string(normalizedBidderName)] = bidderInfo
 		} else {
diff --git a/exchange/bidder.go b/exchange/bidder.go
index db654bf4..610122fb 100644
--- a/exchange/bidder.go
+++ b/exchange/bidder.go
@@ -406,7 +406,7 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde
 
 func addNativeTypes(bid *openrtb2.Bid, request *openrtb2.BidRequest) (*nativeResponse.Response, []error) {
 	var errs []error
-	var nativeMarkup *nativeResponse.Response
+	var nativeMarkup nativeResponse.Response
 	if err := jsonutil.UnmarshalValid(json.RawMessage(bid.AdM), &nativeMarkup); err != nil || len(nativeMarkup.Assets) == 0 {
 		// Some bidders are returning non-IAB compliant native markup. In this case Prebid server will not be able to add types. E.g Facebook
 		return nil, errs
@@ -429,7 +429,7 @@ func addNativeTypes(bid *openrtb2.Bid, request *openrtb2.BidRequest) (*nativeRes
 		}
 	}
 
-	return nativeMarkup, errs
+	return &nativeMarkup, errs
 }
 
 func setAssetTypes(asset nativeResponse.Asset, nativePayload nativeRequests.Request) error {


Test patch:
diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go
index ad242bd0..afb48c2f 100644
--- a/config/bidderinfo_test.go
+++ b/config/bidderinfo_test.go
@@ -1649,6 +1649,18 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) {
 			givenConfigBidderInfos: BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}},
 			expectedBidderInfos:    BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}},
 		},
+		{
+			description:            "Don't override OpenRTB",
+			givenFsBidderInfos:     BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}},
+			givenConfigBidderInfos: BidderInfos{"a": {}},
+			expectedBidderInfos:    BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}},
+		},
+		{
+			description:            "Override OpenRTB",
+			givenFsBidderInfos:     BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}},
+			givenConfigBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v2", GPPSupported: false}}},
+			expectedBidderInfos:    BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v2", GPPSupported: false}}},
+		},
 	}
 	for _, test := range testCases {
 		bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName)
diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go
index 824aecc8..6db61d0d 100644
--- a/exchange/bidder_test.go
+++ b/exchange/bidder_test.go
@@ -1568,6 +1568,46 @@ func TestMobileNativeTypes(t *testing.T) {
 	}
 }
 
+func TestAddNativeTypes(t *testing.T) {
+	testCases := []struct {
+		description      string
+		bidderRequest    *openrtb2.BidRequest
+		bid              *openrtb2.Bid
+		expectedResponse *nativeResponse.Response
+		expectedErrors   []error
+	}{
+		{
+			description: "Null in bid.Adm in response",
+			bidderRequest: &openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{
+						ID: "some-imp-id",
+						Native: &openrtb2.Native{
+							Request: "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}}]}",
+						},
+					},
+				},
+				App: &openrtb2.App{},
+			},
+			bid: &openrtb2.Bid{
+				ImpID: "some-imp-id",
+				AdM:   "null",
+				Price: 10,
+			},
+			expectedResponse: nil,
+			expectedErrors:   nil,
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.description, func(t *testing.T) {
+			resp, errs := addNativeTypes(tt.bid, tt.bidderRequest)
+			assert.Equal(t, tt.expectedResponse, resp, "response")
+			assert.Equal(t, tt.expectedErrors, errs, "errors")
+		})
+	}
+}
+
 func TestRequestBidsStoredBidResponses(t *testing.T) {
 	respBody := "{\"bid\":false}"
 	respStatus := 200