Skip to content

Commit 488eaa4

Browse files
committed
fix: Properly check array/object indexing (closes #10)
How an object or an array is indexed is now checked. If an object is indexed with a number or an array is indexed with a string, an error is thrown. Four old tests were modified because the new check caught indexing errors within them
1 parent b71d686 commit 488eaa4

File tree

5 files changed

+81
-14
lines changed

5 files changed

+81
-14
lines changed

pkg/src/traverse-get.sh

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ bash_object.traverse-get() {
6767
# Start traversing at the root object
6868
local current_object_name="$root_object_name"
6969
local -n __current_object="$root_object_name"
70+
local vmd_dtype=
7071

7172
# A stack of all the evaluated querytree elements
7273
# local -a querytree_stack=()
@@ -92,11 +93,19 @@ bash_object.traverse-get() {
9293

9394
bash_object.trace_loop
9495

96+
# If the past vmd_dtype is an array and 'key' is not a number
97+
if [[ $vmd_dtype == 'array' && $key == *[!0-9]* ]]; then
98+
bash_object.util.die 'ERROR_ARGUMENTS_INCORRECT_TYPE' "Cannot index an array with a non-integer ($key)"
99+
return
100+
# If the past vmd_dtype is an array and 'key' is a number
101+
elif [[ $vmd_dtype == 'object' && $key != *[!0-9]* ]]; then
102+
bash_object.util.die 'ERROR_ARGUMENTS_INCORRECT_TYPE' "Cannot index an object with an integer ($key)"
103+
return
95104
# If 'key' is not a member of object or index of array, error
96-
if [ -z "${__current_object[$key]+x}" ]; then
105+
elif [ -z "${__current_object[$key]+x}" ]; then
97106
bash_object.util.die 'ERROR_NOT_FOUND' "Key or index '$key' (querytree index '$i') does not exist"
98107
return
99-
# If 'key' is a member of an object or index of array
108+
# If 'key' is a valid member of an object or index of array
100109
else
101110
local key_value="${__current_object[$key]}"
102111

pkg/src/traverse-set.sh

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ bash_object.traverse-set() {
208208
# Start traversing at the root object
209209
local current_object_name="$root_object_name"
210210
local -n __current_object="$root_object_name"
211+
local vmd_dtype=
211212

212213
# A stack of all the evaluated querytree elements
213214
local -a querytree_stack=()
@@ -233,8 +234,16 @@ bash_object.traverse-set() {
233234

234235
bash_object.trace_loop
235236

237+
# If the past vmd_dtype is an array and 'key' is not a number
238+
if [[ $vmd_dtype == 'array' && $key == *[!0-9]* ]]; then
239+
bash_object.util.die 'ERROR_ARGUMENTS_INCORRECT_TYPE' "Cannot index an array with a non-integer ($key)"
240+
return
241+
# If the past vmd_dtype is an array and 'key' is a number
242+
elif [[ $vmd_dtype == 'object' && $key != *[!0-9]* ]]; then
243+
bash_object.util.die 'ERROR_ARGUMENTS_INCORRECT_TYPE' "Cannot index an object with an integer ($key)"
244+
return
236245
# If 'key' is not a member of object or index of array, error
237-
if [ -z "${__current_object[$key]+x}" ]; then
246+
elif [ -z "${__current_object[$key]+x}" ]; then
238247
# If we are before the last element in the query, then error
239248
if ((i+1 < ${#REPLIES[@]})); then
240249
bash_object.util.die 'ERROR_NOT_FOUND' "Key or index '$key' (querytree index '$i') does not exist"
@@ -293,7 +302,7 @@ bash_object.traverse-set() {
293302
return
294303
fi
295304
fi
296-
# If 'key' is already a member of object or index of array
305+
# If 'key' is a valid member of an object or index of array
297306
else
298307
local key_value="${__current_object[$key]}"
299308

pkg/src/util/util.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# shellcheck shell=bash
22

3-
# shellcheck disable=SC2192
3+
# shellcheck disable=SC2192,SC2034
44
declare -gA ERRORS_BASH_OBJECT=(
55
[ERROR_NOT_FOUND]=
66
[ERROR_INTERNAL]=
77
[ERROR_SELF_REFERENCE]="A virtual object cannot reference itself"
88

99
[ERROR_ARGUMENTS_INVALID]="Wrong number, empty, or missing required arguments to function"
1010
[ERROR_ARGUMENTS_INVALID_TYPE]="The type of the final value specified by the user is neither 'object', 'array', nor 'string'"
11-
[ERROR_ARGUMENTS_INCORRECT_TYPE]="The type of the final value does not match that of the actual final value (at end of query string)"
11+
[ERROR_ARGUMENTS_INCORRECT_TYPE]="The type of the final value does not match that of the actual final value (at end of query string). Or, the type implied by your query string does not match up with the queried object"
1212

1313
[ERROR_QUERYTREE_INVALID]="The querytree could not be parsed"
1414

tests/errors-bad-index.bats

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env bats
2+
3+
load './util/init.sh'
4+
5+
# object
6+
@test "Correctly errors when indexing an object with an integer (get)" {
7+
declare -A OBJECT=()
8+
9+
bobject set-object --value 'OBJECT' '.uwu' -- one two three four
10+
11+
run bobject get-string --value 'OBJECT' '.["uwu"].[3]'
12+
assert_failure
13+
assert_line -p "ERROR_ARGUMENTS_INCORRECT_TYPE"
14+
assert_line -p "Cannot index an object with an integer"
15+
}
16+
17+
@test "Correctly errors when indexing an object with an integer (set)" {
18+
declare -A OBJECT=()
19+
20+
bobject set-object --value 'OBJECT' '.uwu' -- one two three four
21+
22+
run bobject set-string --value 'OBJECT' '.["uwu"].[3]' -- value
23+
assert_failure
24+
assert_line -p "ERROR_ARGUMENTS_INCORRECT_TYPE"
25+
assert_line -p "Cannot index an object with an integer"
26+
}
27+
28+
# array
29+
@test "Correctly errors when indexing an array with a non-integer (get)" {
30+
declare -A OBJECT=()
31+
32+
bobject set-array --value 'OBJECT' '.uwu' -- one two three
33+
34+
run bobject get-string --value 'OBJECT' '.["uwu"].["f"]'
35+
assert_failure
36+
assert_line -p "ERROR_ARGUMENTS_INCORRECT_TYPE"
37+
assert_line -p "Cannot index an array with a non-integer"
38+
}
39+
40+
@test "Correctly errors when indexing an array with a non-integer (set)" {
41+
declare -A OBJECT=()
42+
43+
bobject set-array --value 'OBJECT' '.uwu' -- one two three
44+
45+
run bobject set-string --value 'OBJECT' '.["uwu"].["f"]' -- value
46+
assert_failure
47+
assert_line -p "ERROR_ARGUMENTS_INCORRECT_TYPE"
48+
assert_line -p "Cannot index an array with a non-integer"
49+
}

tests/errors-circular-reference.bats

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,21 @@ load './util/init.sh'
2626
}
2727

2828
@test "get-array stops on circular reference" {
29-
declare -a SUB_ARRAY=([nested]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
29+
declare -a SUB_ARRAY=($'\x1C\x1Dtype=array;&SUB_ARRAY')
3030
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
3131

32-
run bobject get-array --value OBJECT '.my_key.nested'
32+
run bobject get-array --value OBJECT '.["my_key"].[0]'
3333

3434
assert_failure
3535
assert_line -p "ERROR_SELF_REFERENCE"
3636
assert_line -p "Virtual object 'SUB_ARRAY' cannot reference itself"
3737
}
3838

3939
@test "get-array stops on circular reference 2" {
40-
declare -a SUB_ARRAY=([nested]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
40+
declare -a SUB_ARRAY=($'\x1C\x1Dtype=array;&SUB_ARRAY')
4141
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
4242

43-
run bobject get-array --value OBJECT '.my_key.nested.nested'
43+
run bobject get-array --value OBJECT '.["my_key"].[0].[0]'
4444

4545
assert_failure
4646
assert_line -p "ERROR_SELF_REFERENCE"
@@ -73,23 +73,23 @@ load './util/init.sh'
7373
}
7474

7575
@test "set-array stops on circular reference" {
76-
declare -a SUB_ARRAY=([nested]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
76+
declare -a SUB_ARRAY=($'\x1C\x1Dtype=array;&SUB_ARRAY')
7777
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
7878
declare -a arr=()
7979

80-
run bobject set-array OBJECT --ref '.my_key.nested' arr
80+
run bobject set-array OBJECT --ref '.["my_key"].[0]' arr
8181

8282
assert_failure
8383
assert_line -p "ERROR_SELF_REFERENCE"
8484
assert_line -p "Virtual object 'SUB_ARRAY' cannot reference itself"
8585
}
8686

8787
@test "set-array stops on circular reference 2" {
88-
declare -a SUB_ARRAY=([nested]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
88+
declare -a SUB_ARRAY=($'\x1C\x1Dtype=array;&SUB_ARRAY')
8989
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
9090
declare -a arr=()
9191

92-
run bobject set-array OBJECT --ref '.my_key.nested.gone' arr
92+
run bobject set-array OBJECT --ref '.["my_key"].[0].[0]' arr
9393

9494
assert_failure
9595
assert_line -p "ERROR_SELF_REFERENCE"

0 commit comments

Comments
 (0)