From 840cdc99a1638be90c342099da90583eb565eb74 Mon Sep 17 00:00:00 2001 From: Zaahir Moolla Date: Wed, 25 Jan 2017 15:00:10 -0500 Subject: [PATCH] Revert "calculator: trigger/safe" (#3890) --- lib/DDG/Goodie/Calculator.pm | 78 ++++++++++++++---------------------- t/Calculator.t | 4 -- 2 files changed, 31 insertions(+), 51 deletions(-) diff --git a/lib/DDG/Goodie/Calculator.pm b/lib/DDG/Goodie/Calculator.pm index 028f612dd02..29857c2cd1a 100644 --- a/lib/DDG/Goodie/Calculator.pm +++ b/lib/DDG/Goodie/Calculator.pm @@ -5,23 +5,34 @@ use strict; use DDG::Goodie; with 'DDG::GoodieRole::NumberStyler'; -use List::Util 'max'; +use List::Util qw( max ); use Math::Trig; use Math::BigInt; -use Safe; - use utf8; -zci answer_type => 'calc'; +zci answer_type => "calc"; zci is_cached => 1; -triggers query_nowhitespace => qr' - (?: [() x X × ∙ ⋅ * % + \- ÷ / \^ \$ 0-9 \. ,] | - times | divided by | plus | minus | fact | factorial | cos | - sin | tan | cotan | log | ln | log_?\d{1,3} | exp | tanh | - sec | csc | squared | sqrt | pi | e | gross | dozen | pi | - | score){2,} -'xi; +triggers query_nowhitespace => qr< + ^ + ( what is | calculate | solve | math )? + + [\( \) x X × ∙ ⋅ * % + ÷ / \^ \$ -]* + + (?: [0-9 \. ,]* ) + (?: gross | dozen | pi | e | c | squared | score |) + [\( \) x X × ∙ ⋅ * % + ÷ / \^ 0-9 \. , _ \$ -]* + + (?(1) (?: -? [0-9 \. , _ ]+ |) |) + (?: [\( \) x X × ∙ ⋅ * % + ÷ / \^ \$ -] | times | divided by | plus | minus | fact | factorial | cos | sin | tan | cotan | log | ln | log[_]?\d{1,3} | exp | tanh | sec | csc | squared | sqrt | pi | e )+ + + (?: [0-9 \. ,]* ) + (?: gross | dozen | pi | e | c | squared | score |) + + [\( \) x X × ∙ ⋅ * % + ÷ / \^ 0-9 \. , _ \$ -]* =? + + $ + >xi; my $number_re = number_style_regex(); my $funcy = qr/[[a-z]+\(|log[_]?\d{1,3}\(|\^|\*|\/|squared|divided/; # Stuff that looks like functions. @@ -57,28 +68,6 @@ my $ip4_regex = qr/(?:$ip4_octet\.){3}$ip4_octet/; # Th my $up_to_32 = qr/([1-2]?[0-9]{1}|3[1-2])/; # 0-32 my $network = qr#^$ip4_regex\s*/\s*(?:$up_to_32|$ip4_regex)\s*$#; # Looks like network notation, either CIDR or subnet mask -my $safe = new Safe; -$safe->permit_only(qw' - :base_core :base_math - rv2gv require caller padany -'); - -$safe->deny(qw'warn die'); - -$safe->share_from('Math::Trig', [qw'csc sec tanh tan cotan']); -$safe->share_from('main', [qw' - Math::BigInt::modify - Math::BigInt::bzero - Math::BigInt::bfac - Math::BigInt::bstr - Math::BigInt::new - Math::BigInt::round - Math::BigInt::Calc::_new - Math::BigInt::Calc::_str - Math::BigInt::Calc::_zero - Math::BigInt::Calc::_fac -']); - handle query_nowhitespace => sub { my $query = $_; @@ -88,11 +77,12 @@ handle query_nowhitespace => sub { return if ($query =~ /^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/); # Probably are searching for a phone number, not making a calculation $query =~ s/^(?:whatis|calculate|solve|math)//; - $query =~ s/factorial/fact/; #replace factorial with fact + $query =~ s/(factorial)/fact/; #replace factorial with fact # Grab expression. my $tmp_expr = spacing($query, 1); + return if $tmp_expr eq $query; # If it didn't get spaced out, there are no operations to be done. # First replace named operations with their computable equivalents. @@ -118,15 +108,10 @@ handle query_nowhitespace => sub { return unless $style; $tmp_expr = $style->for_computation($tmp_expr); - $tmp_expr =~ s/Math::BigInt->new\(([^)]+)\)/Math::BigInt->new\($1\)->bfac->bstr/g; #correct expression for fact + $tmp_expr =~ s/(Math::BigInt->new\((.*)\))/(Math::BigInt->new\($2\))->bfac()/g; #correct expression for fact # Using functions makes us want answers with more precision than our inputs indicate. my $precision = ($query =~ $funcy) ? undef : ($query =~ /^\$/) ? 2 : max(map { $style->precision_of($_) } @numbers); - - my $tmp_result; - # e.g. sin(100000)/100000 completely makes this go haywire. - $tmp_result = $safe->reval($tmp_expr); - # if you want to see why $tmp_expr wasn't evaluated, uncomment the following - # warn "reval failed: $@"; + my $tmp_result = eval($tmp_expr); # Guard against non-result results return unless (defined $tmp_result && $tmp_result ne 'inf' && $tmp_result ne ''); @@ -155,18 +140,17 @@ sub prepare_for_display { $query =~ s/(\d)[ _](\d)/$1$2/g; # Squeeze out spaces and underscores. # Show them how 'E' was interpreted. This should use the number styler, too. $query =~ s/((?:\d+?|\s))E(-?\d+)/\($1 * 10^$2\)/i; - $query =~ s/\s*\*\*\s*/^/g; # Use prettier exponentiation. - $query =~ s/Math::BigInt->new\(([^)]+)\)/fact\($1\)/g; #replace Math::BigInt->new( with fact( + $query =~ s/\s*\*{2}\s*/^/g; # Use prettier exponentiation. + $query =~ s/(Math::BigInt->new\((.*)\))/fact\($2\)/g; #replace Math::BigInt->new( with fact( $result = $style->for_display($result); foreach my $name (keys %named_constants) { $query =~ s#\($name\)#$name#xig; } - my $spaced_query = spacing($query); return +{ - text => $spaced_query . ' = ' . $result, + text => spacing($query) . ' = ' . $result, structured => { - input => [$spaced_query], + input => [spacing($query)], operation => 'Calculate', result => "" . $style->with_html($result) . "" }, @@ -182,7 +166,7 @@ sub spacing { $text =~ s/(\s*(? undef, '01780-111-111x400' => undef, '(01780) 111 111' => undef, - 'warn "hi"; 1 + 1' => undef, - 'die "killed"; 1 + 3' => undef, - '1 + 1; die' => undef, - '`ls -al /`; 3 * 4' => undef ); done_testing;