From 8ca916f6a276af625a1c547e12338a45edc317f3 Mon Sep 17 00:00:00 2001 From: Russell Date: Fri, 21 Jun 2024 13:32:45 -0700 Subject: [PATCH] prevent panic when writing a block --- src/bin/hq.rs | 4 ++-- src/write.rs | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/bin/hq.rs b/src/bin/hq.rs index 547f6ad..87e7939 100644 --- a/src/bin/hq.rs +++ b/src/bin/hq.rs @@ -1,7 +1,7 @@ use std::{ error::Error, - io::{self, Read, Write}, fs, + io::{self, Read, Write}, }; use clap::{Parser, Subcommand}; @@ -75,7 +75,7 @@ fn main() -> Result<(), Box> { let expr: Expression = value.parse()?; if let Some(filter) = args.filter { let fields = parse_filter(&filter)?; - write(fields, &mut body, &expr); + write(fields, &mut body, &expr)?; print!("{body}"); io::stdout().flush()?; } else { diff --git a/src/write.rs b/src/write.rs index f92a188..2942e4f 100644 --- a/src/write.rs +++ b/src/write.rs @@ -1,3 +1,5 @@ +use std::error::Error; + use hcl_edit::{expr::Expression, structure::Body, visit_mut::VisitMut}; use crate::parser::Field; @@ -6,6 +8,7 @@ struct HclEditor<'a> { fields: Vec, next: Option, value: &'a Expression, + error: Option>, } impl<'a> HclEditor<'a> { @@ -14,6 +17,7 @@ impl<'a> HclEditor<'a> { fields, next: None, value, + error: None, } } @@ -43,6 +47,10 @@ impl<'a> VisitMut for HclEditor<'a> { if let Some(next) = next { if node.ident.as_str() == next.name { if next.labels.is_empty() { + if self.fields.is_empty() { + self.error = Some("unable to write expr as block body".into()); + return; + } // the block is a match if its name matches and there are no labels // traverse to the next field self.next = Some(self.fields.remove(0)); @@ -52,6 +60,10 @@ impl<'a> VisitMut for HclEditor<'a> { for filter_label in &next.labels { for block_label in &node.labels { if block_label.as_str() == filter_label { + if self.fields.is_empty() { + self.error = Some("unable to write expr as block body".into()); + return; + } // the block name and this label match the filters // traverse to the next field self.next = Some(self.fields.remove(0)); @@ -66,7 +78,15 @@ impl<'a> VisitMut for HclEditor<'a> { } } -pub fn write(fields: Vec, body: &mut Body, value: &Expression) { +pub fn write( + fields: Vec, + body: &mut Body, + value: &Expression, +) -> Result<(), Box> { let mut visitor = HclEditor::new(fields, value); visitor.visit_body_mut(body); + if let Some(err) = visitor.error { + return Err(err); + } + Ok(()) }