Skip to content

Commit

Permalink
fix(eval): do not panic when encountering an array or object as objec…
Browse files Browse the repository at this point in the history
…t key in `std.parseYaml`
  • Loading branch information
eduardosm committed Aug 2, 2024
1 parent b0365cb commit 774cf88
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 0 deletions.
Binary file added core
Binary file not shown.
16 changes: 16 additions & 0 deletions rsjsonnet-lang/src/program/eval/parse_yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub(crate) enum ParseError {
EmptyStream,
Anchor,
Tag,
KeyIsObject(libyaml_safer::Mark),
KeyIsArray(libyaml_safer::Mark),
NumberOverflow,
RepeatedFieldName(InternedStr),
}
Expand All @@ -31,6 +33,8 @@ impl std::fmt::Display for ParseError {
Self::EmptyStream => write!(f, "empty stream"),
Self::Anchor => write!(f, "anchors are not allowed"),
Self::Tag => write!(f, "tags are not allowed"),
Self::KeyIsObject(ref mark) => write!(f, "{mark}: object key is an object"),
Self::KeyIsArray(ref mark) => write!(f, "{mark}: object key is an array"),
Self::NumberOverflow => write!(f, "number overflow"),
Self::RepeatedFieldName(ref name) => {
write!(f, "repeated field name {:?}", name.value())
Expand Down Expand Up @@ -181,6 +185,12 @@ pub(super) fn parse_yaml_document(
}
event = parser.parse()?;
match event.data {
libyaml_safer::EventData::SequenceStart { .. } => {
return Err(ParseError::KeyIsArray(event.start_mark));
}
libyaml_safer::EventData::MappingStart { .. } => {
return Err(ParseError::KeyIsObject(event.start_mark));
}
libyaml_safer::EventData::MappingEnd => {
ValueData::Object(program.gc_alloc(ObjectData::new_simple(HashMap::new())))
}
Expand Down Expand Up @@ -228,6 +238,12 @@ pub(super) fn parse_yaml_document(
}

match event.data {
libyaml_safer::EventData::SequenceStart { .. } => {
return Err(ParseError::KeyIsArray(event.start_mark));
}
libyaml_safer::EventData::MappingStart { .. } => {
return Err(ParseError::KeyIsObject(event.start_mark));
}
libyaml_safer::EventData::MappingEnd => {
value = ValueData::Object(
program.gc_alloc(ObjectData::new_simple(fields)),
Expand Down
1 change: 1 addition & 0 deletions ui-tests/fail/stdlib/parseYaml/key0_is_array.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.parseYaml("{[]: 1}")
8 changes: 8 additions & 0 deletions ui-tests/fail/stdlib/parseYaml/key0_is_array.jsonnet.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: failed to parse YAML: line 0 column 1: object key is an array
note: while evaluating call to `parseYaml`
--> key0_is_array.jsonnet:1:1
|
1 | std.parseYaml("{[]: 1}")
| ------------------------
note: during top-level value evaluation

1 change: 1 addition & 0 deletions ui-tests/fail/stdlib/parseYaml/key0_is_object.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.parseYaml("{{}: 1}")
8 changes: 8 additions & 0 deletions ui-tests/fail/stdlib/parseYaml/key0_is_object.jsonnet.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: failed to parse YAML: line 0 column 1: object key is an object
note: while evaluating call to `parseYaml`
--> key0_is_object.jsonnet:1:1
|
1 | std.parseYaml("{{}: 1}")
| ------------------------
note: during top-level value evaluation

1 change: 1 addition & 0 deletions ui-tests/fail/stdlib/parseYaml/key1_is_array.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.parseYaml("{a: 1, []: 2}")
8 changes: 8 additions & 0 deletions ui-tests/fail/stdlib/parseYaml/key1_is_array.jsonnet.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: failed to parse YAML: line 0 column 7: object key is an array
note: while evaluating call to `parseYaml`
--> key1_is_array.jsonnet:1:1
|
1 | std.parseYaml("{a: 1, []: 2}")
| ------------------------------
note: during top-level value evaluation

1 change: 1 addition & 0 deletions ui-tests/fail/stdlib/parseYaml/key1_is_object.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.parseYaml("{a: 1, {}: 2}")
8 changes: 8 additions & 0 deletions ui-tests/fail/stdlib/parseYaml/key1_is_object.jsonnet.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: failed to parse YAML: line 0 column 7: object key is an object
note: while evaluating call to `parseYaml`
--> key1_is_object.jsonnet:1:1
|
1 | std.parseYaml("{a: 1, {}: 2}")
| ------------------------------
note: during top-level value evaluation

0 comments on commit 774cf88

Please sign in to comment.