- compiled classes being binary files, you should do a binmode(),
otherwise the buffer position can go higher than expected, and later do
a crash of this style:
Uncaught exception from user code:
unknown constant type 0 in pool!
at Java/JVM/Classfile.pm line 382
Java::JVM::Classfile::read_constant_pool('Java::JVM::Classfile=HASH(0x18de46c)')
called at Java/JVM/Classfile.pm line 254
Java::JVM::Classfile::_parse('Java::JVM::Classfile=HASH(0x18de46c)')
called at Java/JVM/Classfile.pm line 242
- in as_text there might be possible undef when grabbing @{$self->args}
- METHODACCESS[7] is native while I believe this should be at index [8]
- why are METHODACCESS[6] and METHODACCESS[8] undef ?
- access_flags being an u2, doing a pack("c*") on it might not work when
the value exceeds 256. May I suggest a pack("c2") with explicit bit
manipulations ?
Please find attached a proposed patch.
Best Regards, Jean-Damien.
Subject: | ClassFile.pm.diff |
--- /T_DRIVE/perl-5.12/perl/site/lib/Java/JVM/Classfile.pm 2011-07-01 13:02:14.802824400 +0200
+++ /C_DRIVE/SVN/Apsys_dev_code/trunk/CodeReview/Java/JVM/Classfile.pm 2011-10-27 16:59:59.275106100 +0200
@@ -121,7 +121,7 @@
my $self = shift;
my $label = $self->label;
my $op = $self->op;
- my @args = @{$self->args};
+ my @args = @{$self->args} || ();
my $output;
$output .= 'L' . $label . ':' if defined $label;
@@ -203,9 +203,11 @@
$METHODACCESS[3] = "static";
$METHODACCESS[4] = "final";
$METHODACCESS[5] = "synchronized";
-$METHODACCESS[7] = "native";
-$METHODACCESS[9] = "abstract";
-$METHODACCESS[10] = "strict";
+$METHODACCESS[6] = "volatile";
+$METHODACCESS[7] = "transient";
+$METHODACCESS[8] = "native";
+$METHODACCESS[9] = "interface";
+$METHODACCESS[10] = "abstract";
my @ACCESS = (
"public", "private", "protected", "static", "final", "synchronized",
@@ -247,6 +249,7 @@
sub _parse {
my $self = shift;
$self->{FH} = IO::File->new($self->{FILENAME}) or croak("Couldn't read class " . $self->{FILENAME} . "!");
+ $self->{FH}->binmode();
my $magic = $self->check_magic;
my $version = $self->read_version;
@@ -431,7 +434,9 @@
}
# print "Access flags: $access_flags = ";
- my $bits = reverse unpack("B*", pack ("c*" ,$access_flags));
+ my $bits = reverse unpack("B*", pack ("c2" ,
+ ($access_flags >> 8) & 0xFF,
+ ($access_flags >> 0) & 0xFF));
# print "($bits) is ";
foreach my $index (0..length($bits)) {
# print $CLASSACCESS[$index] if substr($bits, $index, 1);
@@ -512,9 +517,11 @@
sub read_access_flags {
my $self = shift;
my $access_flags = $self->read_u2;
- my @access_flags;
+ my @access_flags = ();
- my $bits = reverse unpack("B*", pack ("c*" ,$access_flags));
+ my $bits = reverse unpack("B*", pack ("c2" ,
+ ($access_flags >> 8) & 0xFF,
+ ($access_flags >> 0) & 0xFF));
foreach my $index (0..length($bits)) {
push @access_flags, $METHODACCESS[$index] if substr($bits, $index, 1);
}