shithub: hugo

Download patch

ref: 4f72e79120a4f964330d10c8ebe9aceb2b5761a7
parent: fe6676c775b8d917a661238f24fd4a9088f25d50
author: Cameron Moore <[email protected]>
date: Mon Sep 10 10:16:05 EDT 2018

tpl: Show error on union or intersect of uncomparable types

Fixes #3820

--- a/tpl/collections/collections.go
+++ b/tpl/collections/collections.go
@@ -298,8 +298,16 @@
 		case reflect.Array, reflect.Slice:
 			for i := 0; i < l1v.Len(); i++ {
 				l1vv := l1v.Index(i)
+				if !l1vv.Type().Comparable() {
+					return make([]interface{}, 0), errors.New("intersect does not support slices or arrays of uncomparable types")
+				}
+
 				for j := 0; j < l2v.Len(); j++ {
 					l2vv := l2v.Index(j)
+					if !l2vv.Type().Comparable() {
+						return make([]interface{}, 0), errors.New("intersect does not support slices or arrays of uncomparable types")
+					}
+
 					ins.handleValuePair(l1vv, l2vv)
 				}
 			}
@@ -609,6 +617,11 @@
 
 			for i := 0; i < l1v.Len(); i++ {
 				l1vv, isNil = indirectInterface(l1v.Index(i))
+
+				if !l1vv.Type().Comparable() {
+					return []interface{}{}, errors.New("union does not support slices or arrays of uncomparable types")
+				}
+
 				if !isNil {
 					ins.appendIfNotSeen(l1vv)
 				}
--- a/tpl/collections/collections_test.go
+++ b/tpl/collections/collections_test.go
@@ -360,10 +360,6 @@
 		{[]int{1, 2, 4}, []int{3, 6}, []int{}},
 		{[]float64{2.2, 4.4}, []float64{1.1, 2.2, 4.4}, []float64{2.2, 4.4}},
 
-		// errors
-		{"not array or slice", []string{"a"}, false},
-		{[]string{"a"}, "not array or slice", false},
-
 		// []interface{} ∩ []interface{}
 		{[]interface{}{"a", "b", "c"}, []interface{}{"a", "b", "b"}, []interface{}{"a", "b"}},
 		{[]interface{}{1, 2, 3}, []interface{}{1, 2, 2}, []interface{}{1, 2}},
@@ -404,9 +400,18 @@
 		{pagesVals{}, pagesVals{p1v, p3v, p3v}, pagesVals{}},
 		{[]interface{}{p1, p4, p2, p3}, []interface{}{}, []interface{}{}},
 		{[]interface{}{}, []interface{}{p1v, p3v, p3v}, []interface{}{}},
+
+		// errors
+		{"not array or slice", []string{"a"}, false},
+		{[]string{"a"}, "not array or slice", false},
+
+		// uncomparable types - #3820
+		{[]map[int]int{{1: 1}, {2: 2}}, []map[int]int{{2: 2}, {3: 3}}, false},
+		{[][]int{{1, 1}, {1, 2}}, [][]int{{1, 2}, {1, 2}, {1, 3}}, false},
+		{[]int{1, 1}, [][]int{{1, 2}, {1, 2}, {1, 3}}, false},
 	} {
 
-		errMsg := fmt.Sprintf("[%d]", test)
+		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Intersect(test.l1, test.l2)
 
@@ -759,6 +764,10 @@
 		// errors
 		{"not array or slice", []string{"a"}, false, true},
 		{[]string{"a"}, "not array or slice", false, true},
+
+		// uncomparable types - #3820
+		{[]map[string]int{{"K1": 1}}, []map[string]int{{"K2": 2}, {"K2": 2}}, false, true},
+		{[][]int{{1, 1}, {1, 2}}, [][]int{{2, 1}, {2, 2}}, false, true},
 	} {
 
 		errMsg := fmt.Sprintf("[%d] %v", i, test)