From 476baa27e3c14751808b38daa018612cf860555e Mon Sep 17 00:00:00 2001 From: HampusM Date: Fri, 10 May 2024 21:05:02 +0200 Subject: fix(engine): check Wavefront obj statement argument counts --- engine/src/file_format/wavefront/obj.rs | 87 ++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 7 deletions(-) (limited to 'engine/src/file_format/wavefront') diff --git a/engine/src/file_format/wavefront/obj.rs b/engine/src/file_format/wavefront/obj.rs index 29fc985..7dab37c 100644 --- a/engine/src/file_format/wavefront/obj.rs +++ b/engine/src/file_format/wavefront/obj.rs @@ -47,13 +47,29 @@ pub fn parse(obj_content: &str) -> Result return None; } + if statement.arguments.len() == 4 { + return Some(Err(Error::UnsupportedArgumentCount { + keyword: statement.keyword.to_string(), + arg_count: statement.arguments.len(), + line_no: *line_no, + })); + } + + if statement.arguments.len() > 4 { + return Some(Err(Error::InvalidArgumentCount { + keyword: statement.keyword.to_string(), + arg_count: statement.arguments.len(), + line_no: *line_no, + })); + } + let x = try_option!(statement.get_float_arg(0, *line_no)); let y = try_option!(statement.get_float_arg(1, *line_no)); let z = try_option!(statement.get_float_arg(2, *line_no)); Some(Ok(Vec3 { x, y, z })) }) - .collect::, _>>()?; + .collect::, Error>>()?; let texture_positions = statements .iter() @@ -62,13 +78,28 @@ pub fn parse(obj_content: &str) -> Result return None; } + if statement.arguments.len() == 3 { + return Some(Err(Error::UnsupportedArgumentCount { + keyword: statement.keyword.to_string(), + arg_count: statement.arguments.len(), + line_no: *line_no, + })); + } + + if statement.arguments.len() > 3 { + return Some(Err(Error::InvalidArgumentCount { + keyword: statement.keyword.to_string(), + arg_count: statement.arguments.len(), + line_no: *line_no, + })); + } + let u = try_option!(statement.get_float_arg(0, *line_no)); let v = try_option!(statement.get_float_arg(1, *line_no)); - // let w = try_option!(statement.get_float_arg(2, *line_no)); Some(Ok(Vec2 { x: u, y: v })) }) - .collect::, _>>()?; + .collect::, Error>>()?; let vertex_normals = statements .iter() @@ -77,13 +108,21 @@ pub fn parse(obj_content: &str) -> Result return None; } + if statement.arguments.len() > 3 { + return Some(Err(Error::InvalidArgumentCount { + keyword: statement.keyword.to_string(), + arg_count: statement.arguments.len(), + line_no: *line_no, + })); + } + let i = try_option!(statement.get_float_arg(0, *line_no)); let j = try_option!(statement.get_float_arg(1, *line_no)); let k = try_option!(statement.get_float_arg(2, *line_no)); Some(Ok(Vec3 { x: i, y: j, z: k })) }) - .collect::, _>>()?; + .collect::, Error>>()?; let material_specifiers = statements .iter() @@ -92,6 +131,14 @@ pub fn parse(obj_content: &str) -> Result return None; } + if statement.arguments.len() > 1 { + return Some(Err(Error::InvalidArgumentCount { + keyword: statement.keyword.to_string(), + arg_count: statement.arguments.len(), + line_no: *line_no, + })); + } + let material_name = try_option!(statement.get_text_arg(0, *line_no)); Some(Ok(MaterialSpecifier { @@ -99,7 +146,7 @@ pub fn parse(obj_content: &str) -> Result line_no: *line_no, })) }) - .collect::, _>>()?; + .collect::, Error>>()?; let faces = statements .iter() @@ -108,6 +155,14 @@ pub fn parse(obj_content: &str) -> Result return None; } + if statement.arguments.len() > 3 { + return Some(Err(Error::UnsupportedArgumentCount { + keyword: statement.keyword.to_string(), + arg_count: statement.arguments.len(), + line_no: *line_no, + })); + } + let vertex_a = try_option!(statement.get_triplet_arg(0, *line_no)).into(); let vertex_b = try_option!(statement.get_triplet_arg(1, *line_no)).into(); let vertex_c = try_option!(statement.get_triplet_arg(2, *line_no)).into(); @@ -121,7 +176,7 @@ pub fn parse(obj_content: &str) -> Result material_name, })) }) - .collect::, _>>()?; + .collect::, Error>>()?; let mtl_libs = statements .iter() @@ -139,7 +194,7 @@ pub fn parse(obj_content: &str) -> Result Some(Ok(mtl_lib_paths)) }) - .collect::, _>>()?; + .collect::, Error>>()?; Ok(Obj { vertex_positions, @@ -295,6 +350,24 @@ pub enum Error #[error("Face vertices without normals are not yet supported")] NoFaceVertexNormalNotSupported, + + #[error( + "Unsupported number of arguments ({arg_count}) to {keyword} at line {line_no}" + )] + UnsupportedArgumentCount + { + keyword: String, + arg_count: usize, + line_no: usize, + }, + + #[error("Invalid number of arguments ({arg_count}) to {keyword} at line {line_no}")] + InvalidArgumentCount + { + keyword: String, + arg_count: usize, + line_no: usize, + }, } keyword! { -- cgit v1.2.3-18-g5258