From 6afba957f13913b69447701ce3658f20a1e36be6 Mon Sep 17 00:00:00 2001 From: Kashiwa <13825170+ksw2000@users.noreply.github.com> Date: Sun, 2 Mar 2025 01:14:50 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A9=B9=20Fix:=20sorting=20error=20in=20so?= =?UTF-8?q?rtAcceptedTypes=20(#3331)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🩹 Fix: correct sorting error in sortAcceptedTypes. * ♻️ Refactor: remove redundant branch --------- Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> --- helpers.go | 11 +++-------- helpers_test.go | 8 ++++---- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/helpers.go b/helpers.go index 18728e56..a452e13c 100644 --- a/helpers.go +++ b/helpers.go @@ -483,7 +483,7 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head if len(acceptedTypes) > 1 { // Sort accepted types by quality and specificity, preserving order of equal elements - sortAcceptedTypes(&acceptedTypes) + sortAcceptedTypes(acceptedTypes) } // Find the first offer that matches the accepted types @@ -511,19 +511,14 @@ func getOffer(header []byte, isAccepted func(spec, offer string, specParams head // A type with parameters has higher priority than an equivalent one without parameters. // e.g., text/html;a=1;b=2 comes before text/html;a=1 // See: https://www.rfc-editor.org/rfc/rfc9110#name-content-negotiation-fields -func sortAcceptedTypes(acceptedTypes *[]acceptedType) { - if acceptedTypes == nil || len(*acceptedTypes) < 2 { - return - } - at := *acceptedTypes - +func sortAcceptedTypes(at []acceptedType) { for i := 1; i < len(at); i++ { lo, hi := 0, i-1 for lo <= hi { mid := (lo + hi) / 2 if at[i].quality < at[mid].quality || (at[i].quality == at[mid].quality && at[i].specificity < at[mid].specificity) || - (at[i].quality == at[mid].quality && at[i].specificity < at[mid].specificity && len(at[i].params) < len(at[mid].params)) || + (at[i].quality == at[mid].quality && at[i].specificity == at[mid].specificity && len(at[i].params) < len(at[mid].params)) || (at[i].quality == at[mid].quality && at[i].specificity == at[mid].specificity && len(at[i].params) == len(at[mid].params) && at[i].order > at[mid].order) { lo = mid + 1 } else { diff --git a/helpers_test.go b/helpers_test.go index 5664bc48..5e56bade 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -354,7 +354,6 @@ func Test_Utils_SortAcceptedTypes(t *testing.T) { {spec: "text/html", quality: 1, specificity: 3, order: 0}, {spec: "text/*", quality: 0.5, specificity: 2, order: 1}, {spec: "*/*", quality: 0.1, specificity: 1, order: 2}, - {spec: "application/json", quality: 0.999, specificity: 3, order: 3}, {spec: "application/xml", quality: 1, specificity: 3, order: 4}, {spec: "application/pdf", quality: 1, specificity: 3, order: 5}, {spec: "image/png", quality: 1, specificity: 3, order: 6}, @@ -363,8 +362,9 @@ func Test_Utils_SortAcceptedTypes(t *testing.T) { {spec: "image/gif", quality: 1, specificity: 3, order: 9}, {spec: "text/plain", quality: 1, specificity: 3, order: 10}, {spec: "application/json", quality: 0.999, specificity: 3, params: headerParams{"a": []byte("1")}, order: 11}, + {spec: "application/json", quality: 0.999, specificity: 3, order: 3}, } - sortAcceptedTypes(&acceptedTypes) + sortAcceptedTypes(acceptedTypes) require.Equal(t, []acceptedType{ {spec: "text/html", quality: 1, specificity: 3, order: 0}, {spec: "application/xml", quality: 1, specificity: 3, order: 4}, @@ -390,7 +390,7 @@ func Benchmark_Utils_SortAcceptedTypes_Sorted(b *testing.B) { acceptedTypes[0] = acceptedType{spec: "text/html", quality: 1, specificity: 1, order: 0} acceptedTypes[1] = acceptedType{spec: "text/*", quality: 0.5, specificity: 1, order: 1} acceptedTypes[2] = acceptedType{spec: "*/*", quality: 0.1, specificity: 1, order: 2} - sortAcceptedTypes(&acceptedTypes) + sortAcceptedTypes(acceptedTypes) } require.Equal(b, "text/html", acceptedTypes[0].spec) require.Equal(b, "text/*", acceptedTypes[1].spec) @@ -414,7 +414,7 @@ func Benchmark_Utils_SortAcceptedTypes_Unsorted(b *testing.B) { acceptedTypes[8] = acceptedType{spec: "image/*", quality: 1, specificity: 2, order: 8} acceptedTypes[9] = acceptedType{spec: "image/gif", quality: 1, specificity: 3, order: 9} acceptedTypes[10] = acceptedType{spec: "text/plain", quality: 1, specificity: 3, order: 10} - sortAcceptedTypes(&acceptedTypes) + sortAcceptedTypes(acceptedTypes) } require.Equal(b, []acceptedType{ {spec: "text/html", quality: 1, specificity: 3, order: 0},