Skip to content

Commit 41adec0

Browse files
[Bugfix]: Loader can panic when handling nested maps (#415)
* fixing issue where loader can panick when handling nested maps * adding test case for previous crashing test case * addressing new clippy lints
1 parent aa9694b commit 41adec0

File tree

10 files changed

+39
-21
lines changed

10 files changed

+39
-21
lines changed

guard/resources/validate/data-dir/s3-server-side-encryption-template-compliant.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ Resources:
1616
- ServerSideEncryptionByDefault:
1717
SSEAlgorithm: AES256
1818
VersioningConfiguration:
19-
Status: Enabled
19+
Status: Enabled
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# ---
2+
# AWSTemplateFormatVersion: 2010-09-09
3+
# Description: CloudFormation - Server Side Encryption
4+
5+
Resources:
6+
MyBucket:
7+
Type: AWS::S3::Bucket
8+
Properties:
9+
PublicAccessBlockConfiguration:
10+
BlockPublicAcls: true
11+
BlockPublicPolicy: true
12+
IgnorePublicAcls: true
13+
RestrictPublicBuckets: true
14+
BucketEncryption:
15+
ServerSideEncryptionConfiguration:
16+
- ServerSideEncryptionByDefault:
17+
SSEAlgorithm: { { CRASH } }
18+
VersioningConfiguration:
19+
Status: Enabled

guard/resources/validate/rules-dir/s3_bucket_server_side_encryption_enabled.guard

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ rule S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED when %s3_buckets_server_side_encry
1010
Violation: S3 Bucket must enable server-side encryption.
1111
Fix: Set the S3 Bucket property BucketEncryption.ServerSideEncryptionConfiguration.ServerSideEncryptionByDefault.SSEAlgorithm to either "aws:kms" or "AES256"
1212
>>
13-
}
13+
}

guard/src/commands/test.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ or failure testing.
154154
.parent()
155155
.map_or("".to_string(), |p| format!("{}", p.display())),
156156
)
157-
.or_insert(vec![])
157+
.or_default()
158158
.push(GuardFile {
159159
prefix,
160160
file,
@@ -356,14 +356,15 @@ fn test_with_data(
356356
eval_rules_file(rules, &mut root_scope, None)?; // we never use data file name in the output
357357
let top = root_scope.reset_recorder().extract();
358358

359-
let by_rules = top.children.iter().fold(HashMap::new(), |mut acc, rule| {
360-
if let Some(RecordType::RuleCheck(NamedStatus { name, .. })) =
361-
rule.container
362-
{
363-
acc.entry(name).or_insert(vec![]).push(&rule.container)
364-
}
365-
acc
366-
});
359+
let by_rules: HashMap<&str, Vec<&Option<RecordType<'_>>>> =
360+
top.children.iter().fold(HashMap::new(), |mut acc, rule| {
361+
if let Some(RecordType::RuleCheck(NamedStatus { name, .. })) =
362+
rule.container
363+
{
364+
acc.entry(name).or_default().push(&rule.container)
365+
}
366+
acc
367+
});
367368

368369
for (rule_name, rule) in by_rules {
369370
let expected = match each.expectations.rules.get(rule_name) {

guard/src/commands/validate/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -709,12 +709,12 @@ pub(super) fn insert_into_trees<'report, 'value: 'report>(
709709

710710
if let Some(from) = clause.value_from() {
711711
let path = from.self_path().0.to_string();
712-
path_tree.entry(path).or_insert(vec![]).push(node.clone());
712+
path_tree.entry(path).or_default().push(node.clone());
713713
}
714714

715715
if let Some(from) = clause.value_to() {
716716
let path = from.self_path().0.to_string();
717-
path_tree.entry(path).or_insert(vec![]).push(node);
717+
path_tree.entry(path).or_default().push(node);
718718
}
719719
}
720720

guard/src/rules/functions/converters.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ pub(crate) fn parse_float(
2727
}
2828
PathAwareValue::Char((path, val)) => {
2929
aggr.push(Some(PathAwareValue::Float((path.clone(), {
30-
let path = path;
3130
val.to_digit(10).ok_or(crate::Error::ParseError(format!(
3231
"failed to convert a character: {val} into a float at {path}"
3332
)))
@@ -69,7 +68,6 @@ pub(crate) fn parse_int(args: &[QueryResult]) -> crate::rules::Result<Vec<Option
6968
}
7069
PathAwareValue::Char((path, val)) => {
7170
aggr.push(Some(PathAwareValue::Int((path.clone(), {
72-
let path = path;
7371
val.to_digit(10).ok_or(crate::Error::ParseError(format!(
7472
"failed to convert a character: {val} into an integer at {path}"
7573
)))

guard/src/rules/libyaml/loader.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ impl Loader {
157157
let value = key_values.remove(0);
158158
let key_str = match key {
159159
MarkedValue::String(val, loc) => (val, loc),
160+
MarkedValue::Map(..) => continue,
160161
_ => unreachable!(),
161162
};
163+
162164
map.insert(key_str, value);
163165
}
164166
}

guard/src/rules/path_value_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ fn merge_values_test() -> Result<(), Error> {
393393
_ => unreachable!(),
394394
};
395395
assert_eq!(resources_map.values.len(), 2);
396-
assert!(matches!(resources_map.values.get("PARAMETERS"), Some(_)),);
396+
assert!(resources_map.values.get("PARAMETERS").is_some());
397397

398398
let parameters = PathAwareValue::try_from(serde_yaml::from_str::<serde_yaml::Value>(
399399
r#"

guard/tests/test_command.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ mod test_command_tests {
104104
args.push(String::from(self.rules_and_test_file.unwrap()));
105105
}
106106

107-
if self.directory_only {}
108-
109107
if self.alphabetical {
110108
args.push(format!("-{}", ALPHABETICAL.1));
111109
}

guard/tests/validate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,13 @@ mod validate_tests {
195195
#[case(vec!["blank-template.yaml"], vec!["s3_bucket_server_side_encryption_enabled_2.guard"], StatusCode::INTERNAL_FAILURE)]
196196
#[case(
197197
vec!["blank-template.yaml", "s3-server-side-encryption-template-non-compliant-2.yaml"],
198-
vec!["s3_bucket_server_side_encryption_enabled_2.guard"],
199-
StatusCode::INTERNAL_FAILURE
200-
)]
198+
vec!["s3_bucket_server_side_encryption_enabled_2.guard"], StatusCode::INTERNAL_FAILURE)]
201199
#[case(vec!["dne.yaml"], vec!["rules-dir/s3_bucket_public_read_prohibited.guard"], StatusCode::INTERNAL_FAILURE)]
202200
#[case(vec!["data-dir/s3-public-read-prohibited-template-non-compliant.yaml"], vec!["dne.guard"], StatusCode::INTERNAL_FAILURE)]
203201
#[case(vec!["blank.yaml"], vec!["rules-dir/s3_bucket_public_read_prohibited.guard"], StatusCode::INTERNAL_FAILURE)]
204202
#[case(vec!["s3-server-side-encryption-template-non-compliant-2.yaml"], vec!["comments.guard"], StatusCode::SUCCESS)]
203+
#[case(vec!["s3-server-side-encryption-template-non-compliant-2.yaml"], vec!["comments.guard"], StatusCode::SUCCESS)]
204+
#[case(vec!["nested_crash.yaml"], vec!["s3_bucket_server_side_encryption_enabled_2.guard"], StatusCode::VALIDATION_ERROR)]
205205
fn test_single_data_file_single_rules_file_status(
206206
#[case] data_arg: Vec<&str>,
207207
#[case] rules_arg: Vec<&str>,

0 commit comments

Comments
 (0)