From fbfccb394b8ead6435375f9dc6ae07e9df60e860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 9 Aug 2024 17:54:14 +0200 Subject: [PATCH] Fix compare of uints and ints in eq, gt etc. Fixes #12733 --- resources/images/images_integration_test.go | 16 +++++++++ tpl/compare/compare.go | 38 +++++++++++++++++++-- tpl/compare/compare_test.go | 11 ++++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/resources/images/images_integration_test.go b/resources/images/images_integration_test.go index 156de62592f..caba42e0338 100644 --- a/resources/images/images_integration_test.go +++ b/resources/images/images_integration_test.go @@ -34,3 +34,19 @@ W/H rotated: {{ $rotated.Width }}/{{ $rotated.Height }} b := hugolib.Test(t, files) b.AssertFileContent("public/index.html", "W/H original: 80/40\n\nW/H rotated: 40/80") } + +// Issue 12733. +func TestOrientationEq(t *testing.T) { + files := ` +-- hugo.toml -- +-- assets/rotate270.jpg -- +sourcefilename: ../testdata/exif/orientation6.jpg +-- layouts/index.html -- +{{ $img := resources.Get "rotate270.jpg" }} +{{ $orientation := $img.Exif.Tags.Orientation }} +Orientation: {{ $orientation }}|eq 6: {{ eq $orientation 6 }}|Type: {{ printf "%T" $orientation }}| +` + + b := hugolib.Test(t, files) + b.AssertFileContent("public/index.html", "Orientation: 6|eq 6: true|") +} diff --git a/tpl/compare/compare.go b/tpl/compare/compare.go index 907be9b15bf..d6a764c6add 100644 --- a/tpl/compare/compare.go +++ b/tpl/compare/compare.go @@ -117,7 +117,12 @@ func (n *Namespace) Eq(first any, others ...any) bool { case reflect.Float32, reflect.Float64: return vv.Float() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return vv.Uint() + i := vv.Uint() + // If it can fit in an int, convert it. + if i <= math.MaxInt64 { + return int64(i) + } + return i case reflect.String: return vv.String() default: @@ -237,6 +242,16 @@ func (ns *Namespace) compareGet(a any, b any) (float64, float64) { return ns.compareGetWithCollator(nil, a, b) } +func (ns *Namespace) compareTwoUints(a uint64, b uint64) (float64, float64) { + if a < b { + return 1, 0 + } else if a == b { + return 0, 0 + } else { + return 0, 1 + } +} + func (ns *Namespace) compareGetWithCollator(collator *langs.Collator, a any, b any) (float64, float64) { if ac, ok := a.(compare.Comparer); ok { c := ac.Compare(b) @@ -263,12 +278,22 @@ func (ns *Namespace) compareGetWithCollator(collator *langs.Collator, a any, b a var left, right float64 var leftStr, rightStr *string av := reflect.ValueOf(a) + bv := reflect.ValueOf(b) switch av.Kind() { case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: left = float64(av.Len()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + if hreflect.IsUint(bv.Kind()) { + return ns.compareTwoUints(uint64(av.Int()), bv.Uint()) + } left = float64(av.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: + left = float64(av.Uint()) + case reflect.Uint64: + if hreflect.IsUint(bv.Kind()) { + return ns.compareTwoUints(av.Uint(), bv.Uint()) + } case reflect.Float32, reflect.Float64: left = av.Float() case reflect.String: @@ -290,13 +315,20 @@ func (ns *Namespace) compareGetWithCollator(collator *langs.Collator, a any, b a } } - bv := reflect.ValueOf(b) - switch bv.Kind() { case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: right = float64(bv.Len()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + if hreflect.IsUint(av.Kind()) { + return ns.compareTwoUints(av.Uint(), uint64(bv.Int())) + } right = float64(bv.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: + right = float64(bv.Uint()) + case reflect.Uint64: + if hreflect.IsUint(av.Kind()) { + return ns.compareTwoUints(av.Uint(), bv.Uint()) + } case reflect.Float32, reflect.Float64: right = bv.Float() case reflect.String: diff --git a/tpl/compare/compare_test.go b/tpl/compare/compare_test.go index 4c50f5f0f87..6c3f430281d 100644 --- a/tpl/compare/compare_test.go +++ b/tpl/compare/compare_test.go @@ -14,6 +14,7 @@ package compare import ( + "math" "path" "reflect" "runtime" @@ -199,6 +200,16 @@ func doTestCompare(t *testing.T, tp tstCompareType, funcUnderTest func(a, b any) {5, 5, 0}, {int(5), int64(5), 0}, {int32(5), int(5), 0}, + {int16(4), 4, 0}, + {uint8(4), 4, 0}, + {uint16(4), 4, 0}, + {uint16(4), 4, 0}, + {uint32(4), uint16(4), 0}, + {uint32(4), uint16(3), 1}, + {uint64(4), 4, 0}, + {4, uint64(4), 0}, + {uint64(math.MaxUint32), uint32(math.MaxUint32), 0}, + {uint64(math.MaxUint16), int(math.MaxUint16), 0}, {int16(4), int(5), -1}, {uint(15), uint64(15), 0}, {-2, 1, -1},