From 654e3cd86a82b3eeb5a2da2921da25453fb047b9 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Wed, 22 Mar 2023 16:11:31 -0400 Subject: [PATCH] fix parse_frac bug for leading space leading to infinite recursion --- strings.scad | 35 +++++++++++++++++------------------ tests/test_strings.scad | 6 ++++++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/strings.scad b/strings.scad index cef528e..032a40f 100644 --- a/strings.scad +++ b/strings.scad @@ -468,24 +468,23 @@ function parse_float(str) = // parse_frac("-2 12/4",mixed=false); // Returns nan // parse_frac("2 1/4",mixed=false); // Returns nan function parse_frac(str,mixed=true,improper=true,signed=true) = - str == undef ? undef : - len(str)==0 ? 0 : - signed && str[0]=="-" ? -parse_frac(substr(str,1),mixed=mixed,improper=improper,signed=false) : - signed && str[0]=="+" ? parse_frac(substr(str,1),mixed=mixed,improper=improper,signed=false) : - mixed ? ( - !in_list(str_find(str," "), [undef,0]) || is_undef(str_find(str,"/"))? ( - let(whole = str_split(str,[" "])) - _parse_int_recurse(whole[0],10,len(whole[0])-1) + parse_frac(whole[1], mixed=false, improper=improper, signed=false) - ) : parse_frac(str,mixed=false, improper=improper) - ) : ( - let(split = str_split(str,"/")) - len(split)!=2 ? (0/0) : - let( - numerator = _parse_int_recurse(split[0],10,len(split[0])-1), - denominator = _parse_int_recurse(split[1],10,len(split[1])-1) - ) !improper && numerator>=denominator? (0/0) : - denominator<0 ? (0/0) : numerator/denominator - ); + str == undef ? undef + : len(str)==0 ? 0 + : str[0]==" " ? NAN + : signed && str[0]=="-" ? -parse_frac(substr(str,1),mixed=mixed,improper=improper,signed=false) + : signed && str[0]=="+" ? parse_frac(substr(str,1),mixed=mixed,improper=improper,signed=false) + : mixed && (str_find(str," ")!=undef || str_find(str,"/")==undef)? // Mixed allowed and there is a space or no slash + let(whole = str_split(str,[" "])) + _parse_int_recurse(whole[0],10,len(whole[0])-1) + parse_frac(whole[1], mixed=false, improper=improper, signed=false) + : let(split = str_split(str,"/")) + len(split)!=2 ? NAN + : let( + numerator = _parse_int_recurse(split[0],10,len(split[0])-1), + denominator = _parse_int_recurse(split[1],10,len(split[1])-1) + ) + !improper && numerator>=denominator? NAN + : denominator<0 ? NAN + : numerator/denominator; // Function: parse_num() diff --git a/tests/test_strings.scad b/tests/test_strings.scad index 09aa4d6..97c7683 100644 --- a/tests/test_strings.scad +++ b/tests/test_strings.scad @@ -215,6 +215,12 @@ module test_parse_frac() { assert(parse_frac("3/0") == INF); assert(parse_frac("-3/0") == -INF); assert(is_nan(parse_frac("0/0"))); + assert(is_nan(parse_frac("-77/9", improper=false))); + assert(is_nan(parse_frac("-2 12/4",improper=false))); + assert(is_nan(parse_frac("-2 12/4",signed=false))); + assert(is_nan(parse_frac("-2 12/4",mixed=false))); + assert(is_nan(parse_frac("2 1/4",mixed=false))); + assert(is_nan(parse_frac("2", mixed=false))); } test_parse_frac();