Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl: Should Math64::Int64 work inside a "Safe" Compartment?

(My first post to stack overflow, hope I am using the right format)

I have a need to evaluate code that manipulates 64-bit integers in a "Safe" compartment. Since I supply both the script and the code to be evaluated, I could do a normal eval, but I wanted to try to make things more robust from unintentional errors by using 'Safe".

Should I expect that Math::Int64 should work properly inside a "Safe" compartment? I get conflicting results across different bitness of Perl versions, integer bit-width, and OSes. (See below).

All fail in the same way inside the debugger.

I am sure I am making some incorrect assumption some place, but can't figure out where.

Thanks for any help you can give.

Code Example (dummy.pl)

use strict;
use warnings;
use Exporter;
use Safe;
use Math::Int64 qw(int64 hex_to_int64);
#use Math::Int64 ':native_if_available';

my $safe = new Safe 'Root';
$safe->permit( qw(:browse) );
$safe->share( qw/int64 hex_to_int64 my_sprintf/ );

my $X = 0xFF & (hex_to_int64("0xAA12345678") >> 4);
print my_sprintf("X ",$X);

my $Z = evalme('$X = 0xFF & (hex_to_int64("0xAA12345678") >> 4)', $safe);
print my_sprintf("Z ",$Z);

print evalme('my_sprintf("Xe", $X)',$safe);

exit;


sub my_sprintf {
    my ($string, $value) = @_;
    return sprintf( "Value of %s: %X,\tType: %s\n",
                    $string, $value, ref($value) || "scalar"
           );
}

sub evalme {
    my($expr, $safe) = @_;
    my $retval = $safe->reval($expr);
    die "Error: $@\n" if ($@);
    return $retval;
}

Execution Examples

% perl -w dummy.pl

=== "Win7 x64 SP1, Strawberry Perl 5.12.3" ===
Value of X : 67,        Type: Math::Int64
Can't locate package Exporter for @Math::Int64::ISA at (eval 5) line 1.
...
Can't locate package Exporter for @Math::Int64::ISA at (eval 5) line 1.
Value of Z : 67,        Type: Math::Int64
Value of Xe: 67,        Type: Math::Int64

=== "Win XP SP3 32-bit Strawberry Perl 5.16.0" ===
Value of X : 67,        Type: Math::Int64
Value of Z : 8E,        Type: scalar
Value of Xe: 8E,        Type: scalar


(No ':native-if-available')
=== "Ubuntu 10.04 x86_64 Server, Perl 5.10.1" ===
Value of X : 67,        Type: Math::Int64
Value of Z : 4D,        Type: scalar
Value of Xe: 4D,        Type: scalar

(':native-if-available')
=== "Ubuntu 10.04 x86_64 Server, Perl 5.10.1" ===
Value of X : 67,        Type: scalar
Value of Z : 71,        Type: scalar
Value of Xe: 71,        Type: scalar



% perl -wd dummy.pl

All versions return effectively:

Value of X : 67,        Type: Math::Int64
Error: Undefined subroutine &Math::Int64::hex_to_int64 called at c:/.../perl5db.

 at dummy.pl line 35
        main::evalme('$X = 0xFF & (hex_to_int64("0xAA12345678") >> 4)',
                     'Safe=HASH(xxxxxxxx)'

Versions

"Win7 x64 SP1, Strawberry Perl 5.12.3":
  Platform:
    osname=MSWin32, osvers=6.1, archname=MSWin32-x64-multi-thread
    uname='Win32 strawberryperl 5.12.3.0 #1 Sun May 15 09:43:50 2011 x64'
    use64bitint=define, use64bitall=undef, uselongdouble=undef
  Compiler:
    intsize=4, longsize=4, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='long long',
  Characteristics of this binary (from libperl):
     Compile-time options: ... USE_64_BIT_INT

"Win XP 32-bit Strawberry Perl 5.16.0":
  Platform:
    osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
    uname='Win32 strawberry-perl 5.16.0.1 #1 Mon May 21 22:07:30 2012 i386'
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
  Compiler:
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long long',
  Characteristics of this binary (from libperl):
     Compile-time options: ...

"Ubuntu 10.04 x86_64 Server, Perl 5.10.1":
  Linux 2.6.32-31-server,
  Platform:
    use64bitint=define, use64bitall=define, uselongdouble=undef
  Compiler:
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
  Characteristics of this binary (from libperl):
     Compile-time options: ... USE_64_BIT_ALL USE_64_BIT_INT
like image 860
rbrunner Avatar asked Jul 06 '12 22:07

rbrunner


1 Answers

It seems that the issue is caused by overloading not working inside Safe compartments.

Overloading was one of the ways to circumvent Safe so it may be disabled on purpose. You can ask on the perl5-porters mailing list if you really want to know.

I don't think this could be solved from Math::Int64 (BTW, I am its author).

On the other hand, you can try compiling Perl with native 64bit support.

like image 153
salva Avatar answered Oct 16 '22 19:10

salva