Form::parse_amount: Parsen als Oktalzahlen verhindern
authorMoritz Bunkus <m.bunkus@linet-services.de>
Wed, 13 May 2015 10:16:59 +0000 (12:16 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Wed, 13 May 2015 10:16:59 +0000 (12:16 +0200)
SL/Form.pm
t/form/parse_amount.t [new file with mode: 0644]

index 0aad56e..e597786 100644 (file)
@@ -947,6 +947,10 @@ sub parse_amount {
 
   # Make sure no code wich is not a math expression ends up in eval().
   return 0 unless $amount =~ /^ [\s \d \( \) \- \+ \* \/ \. ]* $/x;
+
+  # Prevent numbers from being parsed as octals;
+  $amount =~ s{ (?<! [\d.] ) 0+ (?= [1-9] ) }{}gx;
+
   return scalar(eval($amount)) * 1 ;
 }
 
diff --git a/t/form/parse_amount.t b/t/form/parse_amount.t
new file mode 100644 (file)
index 0000000..4e29eb2
--- /dev/null
@@ -0,0 +1,129 @@
+use strict;
+use Test::More;
+
+use lib 't';
+use Support::TestSetup;
+
+Support::TestSetup::login();
+
+my $config = {};
+
+# Positive numbers
+$config->{numberformat} = '1.000,00';
+
+is($::form->parse_amount($config, '12345'),        12345,     '12345 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '1.234,5'),      1234.5,    '1.234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '9.871.234,5'),  9871234.5, '9.871.234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '1234,5'),       1234.5,    '1234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '012345'),       12345,     '012345 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '01.234,5'),     1234.5,    '01.234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '01234,5'),      1234.5,    '01234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '09.871.234,5'), 9871234.5, '09.871.234,5 (numberformat: 1.000,00)');
+
+$config->{numberformat} = '1000,00';
+
+is($::form->parse_amount($config, '12345'),        12345,     '12345 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '1.234,5'),      1234.5,    '1.234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '9.871.234,5'),  9871234.5, '9.871.234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '1234,5'),       1234.5,    '1234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '012345'),       12345,     '012345 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '01.234,5'),     1234.5,    '01.234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '01234,5'),      1234.5,    '01234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '09.871.234,5'), 9871234.5, '09.871.234,5 (numberformat: 1000,00)');
+
+$config->{numberformat} = '1,000.00';
+
+is($::form->parse_amount($config, '12345'),        12345,     '12345 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '1,234.5'),      1234.5,    '1,234.5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '9,871,234.5'),  9871234.5, '9,871,234,5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '1234.5'),       1234.5,    '1234.5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '012345'),       12345,     '012345 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '01,234.5'),     1234.5,    '01,234.5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '01234.5'),      1234.5,    '01234.5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '09,871,234.5'), 9871234.5, '09,871,234,5 (numberformat: 1,000.00)');
+
+$config->{numberformat} = '1000.00';
+
+is($::form->parse_amount($config, '12345'),        12345,     '12345 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '1,234.5'),      1234.5,    '1,234.5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '9,871,234.5'),  9871234.5, '9,871,234,5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '1234.5'),       1234.5,    '1234.5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '012345'),       12345,     '012345 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '01,234.5'),     1234.5,    '01,234.5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '01234.5'),      1234.5,    '01234.5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '09,871,234.5'), 9871234.5, '09,871,234,5 (numberformat: 1000.00)');
+
+# Negative numbers
+$config->{numberformat} = '1.000,00';
+
+is($::form->parse_amount($config, '-12345'),        -12345,     '-12345 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '-1.234,5'),      -1234.5,    '-1.234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '-9.871.234,5'),  -9871234.5, '-9.871.234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '-1234,5'),       -1234.5,    '-1234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '-012345'),       -12345,     '-012345 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '-01.234,5'),     -1234.5,    '-01.234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '-01234,5'),      -1234.5,    '-01234,5 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '-09.871.234,5'), -9871234.5, '-09.871.234,5 (numberformat: 1.000,00)');
+
+$config->{numberformat} = '1000,00';
+
+is($::form->parse_amount($config, '-12345'),        -12345,     '-12345 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '-1.234,5'),      -1234.5,    '-1.234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '-9.871.234,5'),  -9871234.5, '-9.871.234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '-1234,5'),       -1234.5,    '-1234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '-012345'),       -12345,     '-012345 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '-01.234,5'),     -1234.5,    '-01.234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '-01234,5'),      -1234.5,    '-01234,5 (numberformat: 1000,00)');
+is($::form->parse_amount($config, '-09.871.234,5'), -9871234.5, '-09.871.234,5 (numberformat: 1000,00)');
+
+$config->{numberformat} = '1,000.00';
+
+is($::form->parse_amount($config, '-12345'),        -12345,     '-12345 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '-1,234.5'),      -1234.5,    '-1,234.5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '-9,871,234.5'),  -9871234.5, '-9,871,234,5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '-1234.5'),       -1234.5,    '-1234.5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '-012345'),       -12345,     '-012345 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '-01,234.5'),     -1234.5,    '-01,234.5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '-01234.5'),      -1234.5,    '-01234.5 (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '-09,871,234.5'), -9871234.5, '-09,871,234,5 (numberformat: 1,000.00)');
+
+$config->{numberformat} = '1000.00';
+
+is($::form->parse_amount($config, '-12345'),        -12345,     '-12345 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '-1,234.5'),      -1234.5,    '-1,234.5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '-9,871,234.5'),  -9871234.5, '-9,871,234,5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '-1234.5'),       -1234.5,    '-1234.5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '-012345'),       -12345,     '-012345 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '-01,234.5'),     -1234.5,    '-01,234.5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '-01234.5'),      -1234.5,    '-01234.5 (numberformat: 1000.00)');
+is($::form->parse_amount($config, '-09,871,234.5'), -9871234.5, '-09,871,234,5 (numberformat: 1000.00)');
+
+# Calculations
+$config->{numberformat} = '1.000,00';
+
+is($::form->parse_amount($config, '47/2+3,5*(4+5)'),                  55,    '47/2+3,5*(4+5) (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '047/002+003,05*(04+000005)'),      50.95, '047/002+003,05*(04+000005) (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '47 / 2+       3,5*( 4 + 5)'),      55,    '47 / 2+       3.,*( 4 + 5) (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '047/ 002+ 003,05 * (04 +000005)'), 50.95, '047/ 002+ 003,05 * (04 +000005) (numberformat: 1.000,00)');
+
+$config->{numberformat} = '1,000.00';
+
+is($::form->parse_amount($config, '47/2+3.5*(4+5)'),                  55,    '47/2+3.5*(4+5) (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '047/002+003.05*(04+000005)'),      50.95, '047/002+003.05*(04+000005) (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '47 / 2+       3.5*( 4 + 5)'),      55,    '47 / 2+       3.5*( 4 + 5) (numberformat: 1,000.00)');
+is($::form->parse_amount($config, '047/ 002+ 003.05 * (04 +000005)'), 50.95, '047/ 002+ 003.05 * (04 +000005) (numberformat: 1,000.00)');
+
+# Weird edge cases
+
+$config->{numberformat} = '1.000,00';
+
+is($::form->parse_amount($config, '-0+1'), 1, '-0+1 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '-0+9'), 9, '-0+9 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '20*0'), 0, '20*0 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '20*0123'), 2460, '20*0123 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '010+010'), 20, '010+010 (numberformat: 1.000,00)');
+is($::form->parse_amount($config, '+(010*2)'), 20, '+(010*2) (numberformat: 1.000,00)');
+
+done_testing;
+
+1;