Skip to content

Commit 5764611

Browse files
committed
jsonpath: validate array indices are within int32 range
This commit adds validation to ensure JSONPath array indices are within the int32 range, matching Postgres' behaviour. Now, we return an error for indices outside the int32 range. Release note: None
1 parent 30bcd20 commit 5764611

File tree

3 files changed

+32
-6
lines changed

3 files changed

+32
-6
lines changed

pkg/sql/logictest/testdata/logic_test/jsonb_path_query

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,3 +1406,25 @@ query T
14061406
SELECT jsonb_path_query('{"a": {"b": [{"c": 1}, {"c": 2}]}}', '($.a.b[1]).c');
14071407
----
14081408
2
1409+
1410+
statement error pgcode 22033 pq: jsonpath array subscript is out of integer range
1411+
SELECT jsonb_path_query('[1]', 'lax $[10000000000000000]');
1412+
1413+
statement error pgcode 22033 pq: jsonpath array subscript is out of integer range
1414+
SELECT jsonb_path_query('[1]', 'lax $[-10000000000000000]');
1415+
1416+
# MaxInt32
1417+
query empty
1418+
SELECT jsonb_path_query('[1]', '$[2147483647]');
1419+
1420+
# MaxInt32 + 1
1421+
statement error pgcode 22033 pq: jsonpath array subscript is out of integer range
1422+
SELECT jsonb_path_query('[1]', '$[2147483648]');
1423+
1424+
# MinInt32
1425+
query empty
1426+
SELECT jsonb_path_query('[1]', '$[-2147483648]');
1427+
1428+
# MinInt32 - 1
1429+
statement error pgcode 22033 pq: jsonpath array subscript is out of integer range
1430+
SELECT jsonb_path_query('[1]', '$[-2147483649]');

pkg/util/jsonpath/eval/array.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
package eval
77

88
import (
9+
"math"
10+
911
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
1012
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
1113
"github.com/cockroachdb/cockroach/pkg/util/json"
@@ -18,6 +20,7 @@ var (
1820
errIndexOnNonArray = pgerror.Newf(pgcode.SQLJSONArrayNotFound, "jsonpath array accessor can only be applied to an array")
1921
errIndexOutOfBounds = pgerror.Newf(pgcode.InvalidSQLJSONSubscript, "jsonpath array subscript is out of bounds")
2022
errIndexNotSingleNumValue = pgerror.Newf(pgcode.InvalidSQLJSONSubscript, "jsonpath array subscript is not a single numeric value")
23+
errInvalidSubscript = pgerror.Newf(pgcode.InvalidSQLJSONSubscript, "jsonpath array subscript is out of integer range")
2124
)
2225

2326
func (ctx *jsonpathCtx) evalArrayWildcard(jsonValue json.JSON) ([]json.JSON, error) {
@@ -110,23 +113,25 @@ func (ctx *jsonpathCtx) resolveArrayIndex(
110113
if len(evalResults) != 1 || evalResults[0].Type() != json.NumberJSONType {
111114
return -1, errIndexNotSingleNumValue
112115
}
113-
// TODO(normanchenn): Postgres returns an error if the index is outside int32
114-
// range. (ex. `select jsonb_path_query('[1]', 'lax $[10000000000000000]');
115116
i, err := asInt(evalResults[0])
116117
if err != nil {
117-
return -1, errIndexNotSingleNumValue
118+
return -1, err
118119
}
119120
return i, nil
120121
}
121122

122123
func asInt(j json.JSON) (int, error) {
123124
d, ok := j.AsDecimal()
124125
if !ok {
125-
return 0, errInternal
126+
return 0, errIndexNotSingleNumValue
126127
}
127128
i64, err := d.Int64()
128129
if err != nil {
129-
return 0, err
130+
return 0, errIndexNotSingleNumValue
131+
}
132+
// Postgres returns an error if the index is outside int32 range.
133+
if i64 < math.MinInt32 || i64 > math.MaxInt32 {
134+
return 0, errInvalidSubscript
130135
}
131136
return int(i64), nil
132137
}

pkg/util/jsonpath/eval/eval.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818

1919
var (
2020
errUnimplemented = unimplemented.NewWithIssue(22513, "unimplemented")
21-
errInternal = errors.New("internal error")
2221
errSingleBooleanRequired = pgerror.Newf(pgcode.SingletonSQLJSONItemRequired, "single boolean result is expected")
2322
)
2423

0 commit comments

Comments
 (0)