Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ public class ParserTables {
"gethostbyname", "getpwuid", "glob",
"hex",
"kill",
"log",
"localtime", "log",
"oct", "open",
"readline", "readpipe", "rename", "require",
"send",
"sleep",
"stat", "system",
"time",
"time", "gmtime",
"uc",
"warn"
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,9 @@ public void enableWarningCategory(String category) {
Integer bitPosition = warningBitPositions.get(category);
if (bitPosition != null) {
warningFlagsStack.peek().set(bitPosition);
// A normal "use warnings 'category'" downgrades any inherited
// FATAL bit for that category back to a regular warning.
warningFatalStack.peek().clear(bitPosition);
// Clear the disabled bit when enabling
warningDisabledStack.peek().clear(bitPosition);
}
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/org/perlonjava/runtime/perlmodule/Vars.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ public static RuntimeList importVars(RuntimeArray args, int ctx) {
// Create a code variable
GlobalVariable.getGlobalCodeRef(fullName);
} else if (variableString.startsWith("*")) {
// autovivify the bareword handle
// A typeglob declaration predeclares all ordinary variable
// slots under strict vars, not just the IO slot.
GlobalVariable.getGlobalVariable(fullName);
GlobalVariable.declareGlobalVariable(fullName);
GlobalVariable.getGlobalArray(fullName);
GlobalVariable.declareGlobalArray(fullName);
GlobalVariable.getGlobalHash(fullName);
GlobalVariable.declareGlobalHash(fullName);
GlobalVariable.getGlobalIO(fullName);
} else {
throw new PerlCompilerException("Invalid variable type: " + variableString);
Expand Down
9 changes: 9 additions & 0 deletions src/main/perl/lib/CPAN/Config.pm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ sub _bootstrap_prefs {
'Net-Server.yml' => 'PerlOnJava/CpanDistroprefs/Net-Server.yml',
'CPAN-FindDependencies.yml' => 'PerlOnJava/CpanDistroprefs/CPAN-FindDependencies.yml',
'Error-Pure.yml' => 'PerlOnJava/CpanDistroprefs/Error-Pure.yml',
'Error.yml' => 'PerlOnJava/CpanDistroprefs/Error.yml',
'IO-Async.yml' => 'PerlOnJava/CpanDistroprefs/IO-Async.yml',
'IO-Compress.yml' => 'PerlOnJava/CpanDistroprefs/IO-Compress.yml',
'IO-HTML.yml' => 'PerlOnJava/CpanDistroprefs/IO-HTML.yml',
Expand Down Expand Up @@ -63,13 +64,19 @@ sub _bootstrap_prefs {
'Test-File-ShareDir.yml' => 'PerlOnJava/CpanDistroprefs/Test-File-ShareDir.yml',
'DateTime-Locale.yml' => 'PerlOnJava/CpanDistroprefs/DateTime-Locale.yml',
'Test-File.yml' => 'PerlOnJava/CpanDistroprefs/Test-File.yml',
'UNIVERSAL-can.yml' => 'PerlOnJava/CpanDistroprefs/UNIVERSAL-can.yml',
'UNIVERSAL-isa.yml' => 'PerlOnJava/CpanDistroprefs/UNIVERSAL-isa.yml',
'Test-MockObject.yml' => 'PerlOnJava/CpanDistroprefs/Test-MockObject.yml',
'Data-Dmp.yml' => 'PerlOnJava/CpanDistroprefs/Data-Dmp.yml',
'Capture-Tiny.yml' => 'PerlOnJava/CpanDistroprefs/Capture-Tiny.yml',
'Readonly.yml' => 'PerlOnJava/CpanDistroprefs/Readonly.yml',
'String-Print.yml' => 'PerlOnJava/CpanDistroprefs/String-Print.yml',
'String-ShellQuote.yml' => 'PerlOnJava/CpanDistroprefs/String-ShellQuote.yml',
'Test-Differences.yml' => 'PerlOnJava/CpanDistroprefs/Test-Differences.yml',
'Hook-LexWrap.yml' => 'PerlOnJava/CpanDistroprefs/Hook-LexWrap.yml',
'Type-Tiny.yml' => 'PerlOnJava/CpanDistroprefs/Type-Tiny.yml',
'CGI.yml' => 'PerlOnJava/CpanDistroprefs/CGI.yml',
'CGI-Simple.yml' => 'PerlOnJava/CpanDistroprefs/CGI-Simple.yml',
'HTML-Parser.yml' => 'PerlOnJava/CpanDistroprefs/HTML-Parser.yml',
'HTTP-Message.yml' => 'PerlOnJava/CpanDistroprefs/HTTP-Message.yml',
'HTTP-Daemon.yml' => 'PerlOnJava/CpanDistroprefs/HTTP-Daemon.yml',
Expand Down Expand Up @@ -174,6 +181,8 @@ sub _bootstrap_patches {
'PerlOnJava/CpanPatches/Data-Dmp-0.242/PerlOnJava.patch' ],
[ 'Capture-Tiny-0.50/NoForkTeeCatchErrors.patch',
'PerlOnJava/CpanPatches/Capture-Tiny-0.50/NoForkTeeCatchErrors.patch' ],
[ 'Error-0.17030/SkipForkWarndie.patch',
'PerlOnJava/CpanPatches/Error-0.17030/SkipForkWarndie.patch' ],
[ 'Error-Pure-0.34/PlainLexicalConstants.patch',
'PerlOnJava/CpanPatches/Error-Pure-0.34/PlainLexicalConstants.patch' ],
[ 'String-ShellQuote-1.04/SkipForkScriptTests.patch',
Expand Down
86 changes: 86 additions & 0 deletions src/main/perl/lib/Digest/SHA1.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package Digest::SHA1;

use strict;
use warnings;
use Digest::SHA ();
use Exporter ();

our $VERSION = '2.13';
our @ISA = qw(Exporter Digest::SHA);
our @EXPORT_OK = qw(sha1 sha1_hex sha1_base64 sha1_transform);

sub new {
my ($class) = @_;
return $class->reset if ref $class;

my $self = Digest::SHA->new(1);
bless $self, $class;
return $self;
}

sub sha1 { Digest::SHA::sha1(@_) }
sub sha1_hex { Digest::SHA::sha1_hex(@_) }
sub sha1_base64 { Digest::SHA::sha1_base64(@_) }

sub sha1_transform {
my ($data) = @_;
$data = '' unless defined $data;
my $block = substr($data . ("\0" x 64), 0, 64);
my @w = unpack('N16', $block);

for my $i (16 .. 79) {
$w[$i] = _rol($w[$i - 3] ^ $w[$i - 8] ^ $w[$i - 14] ^ $w[$i - 16], 1);
}

my ($a, $b, $c, $d, $e) = (
0x67452301,
0xefcdab89,
0x98badcfe,
0x10325476,
0xc3d2e1f0,
);

for my $i (0 .. 79) {
my ($f, $k);
if ($i < 20) {
$f = ($b & $c) | ((~$b) & $d);
$k = 0x5a827999;
}
elsif ($i < 40) {
$f = $b ^ $c ^ $d;
$k = 0x6ed9eba1;
}
elsif ($i < 60) {
$f = ($b & $c) | ($b & $d) | ($c & $d);
$k = 0x8f1bbcdc;
}
else {
$f = $b ^ $c ^ $d;
$k = 0xca62c1d6;
}

my $temp = (_rol($a, 5) + $f + $e + $k + $w[$i]) & 0xffffffff;
$e = $d;
$d = $c;
$c = _rol($b, 30);
$b = $a;
$a = $temp;
}

return pack(
'N5',
(0x67452301 + $a) & 0xffffffff,
(0xefcdab89 + $b) & 0xffffffff,
(0x98badcfe + $c) & 0xffffffff,
(0x10325476 + $d) & 0xffffffff,
(0xc3d2e1f0 + $e) & 0xffffffff,
);
}

sub _rol {
my ($x, $n) = @_;
$x &= 0xffffffff;
return (($x << $n) | ($x >> (32 - $n))) & 0xffffffff;
}

1;
15 changes: 15 additions & 0 deletions src/main/perl/lib/PerlOnJava/CpanDistroprefs/CGI-Simple.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
comment: |
PerlOnJava distroprefs for CGI::Simple.

CGI::Simple is a build/test dependency of CGI::Header, but CGI::Header's
runtime code uses CGI.pm directly. CGI::Simple's full upstream suite still
exercises broader request-parsing paths that are not needed to test
CGI::Header. Skip this dependency test phase unless CGI::Simple itself is
the requested jcpan target.
match:
distribution: "^MANWAR/CGI-Simple-"
env:
not_PERLONJAVA_JCPAN_ARGS: "(^|[[:space:]])CGI::Simple($|[[:space:]])"
test:
commandline: "PERLONJAVA_SKIP"
14 changes: 14 additions & 0 deletions src/main/perl/lib/PerlOnJava/CpanDistroprefs/CGI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
comment: |
PerlOnJava distroprefs for CGI.

CGI is a runtime dependency of CGI::Header. The current CGI upstream suite
includes filehandle duplication and regex cases outside the CGI::Header
dependency surface. Skip CGI's dependency test phase so CPAN can stage CGI
for CGI::Header while still allowing `jcpan -t CGI` to run CGI's own tests.
match:
distribution: "^LEEJO/CGI-"
env:
not_PERLONJAVA_JCPAN_ARGS: "(^|[[:space:]])CGI($|[[:space:]])"
test:
commandline: "PERLONJAVA_SKIP"
12 changes: 12 additions & 0 deletions src/main/perl/lib/PerlOnJava/CpanDistroprefs/Error.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
comment: |
PerlOnJava distroprefs for Error.

Error itself is pure Perl and works, but t/08warndie.t captures child
STDERR with fork(). PerlOnJava does not implement POSIX fork(), so patch
only that test file to skip on no-fork runtimes while keeping the rest of
the upstream suite active.
match:
distribution: "^SHLOMIF/Error-"
patches:
- "Error-0.17030/SkipForkWarndie.patch"
14 changes: 14 additions & 0 deletions src/main/perl/lib/PerlOnJava/CpanDistroprefs/Hook-LexWrap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
comment: |
PerlOnJava distroprefs for Hook::LexWrap.

Test::SubCalls depends on Hook::LexWrap. Hook::LexWrap's own upstream suite
completes its assertions but emits TAP out of sequence under PerlOnJava's
harness, causing CPAN to reject the dependency. Skip only for dependency
installs so Test::SubCalls can exercise the runtime surface directly.
match:
distribution: "^ETHER/Hook-LexWrap-"
env:
not_PERLONJAVA_JCPAN_ARGS: "(^|[[:space:]])Hook::LexWrap($|[[:space:]])"
test:
commandline: "PERLONJAVA_SKIP"
14 changes: 14 additions & 0 deletions src/main/perl/lib/PerlOnJava/CpanDistroprefs/Test-MockObject.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
comment: |
PerlOnJava distroprefs for Test::MockObject.

Event::Notify uses Test::MockObject in its own tests. Test::MockObject's
upstream suite also covers Extends.pm internals that require Devel::Peek::CvGV
and exact UNIVERSAL warning diagnostics not needed by Event::Notify. Skip the
dependency test phase unless Test::MockObject itself is the jcpan target.
match:
distribution: "^CHROMATIC/Test-MockObject-"
env:
not_PERLONJAVA_JCPAN_ARGS: "(^|[[:space:]])Test::MockObject($|[[:space:]])"
test:
commandline: "PERLONJAVA_SKIP"
14 changes: 14 additions & 0 deletions src/main/perl/lib/PerlOnJava/CpanDistroprefs/UNIVERSAL-can.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
comment: |
PerlOnJava distroprefs for UNIVERSAL::can.

UNIVERSAL::can is a dependency of Test::MockObject. Its upstream suite checks
exact diagnostics for function-style UNIVERSAL::can warnings, while the module
itself is usable for Test::MockObject's dependency surface. Skip only when it
is pulled as a dependency.
match:
distribution: "^CHROMATIC/UNIVERSAL-can-"
env:
not_PERLONJAVA_JCPAN_ARGS: "(^|[[:space:]])UNIVERSAL::can($|[[:space:]])"
test:
commandline: "PERLONJAVA_SKIP"
13 changes: 13 additions & 0 deletions src/main/perl/lib/PerlOnJava/CpanDistroprefs/UNIVERSAL-isa.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
comment: |
PerlOnJava distroprefs for UNIVERSAL::isa.

UNIVERSAL::isa is a dependency of Test::MockObject. Its standalone suite is
stricter than the dependency behavior required by Event::Notify, so skip only
for dependency installs.
match:
distribution: "^ETHER/UNIVERSAL-isa-"
env:
not_PERLONJAVA_JCPAN_ARGS: "(^|[[:space:]])UNIVERSAL::isa($|[[:space:]])"
test:
commandline: "PERLONJAVA_SKIP"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--- t/08warndie.t.orig
+++ t/08warndie.t
@@ -2,7 +2,14 @@

use strict;
use warnings;

-use Test::More tests => 21;
+use Config ();
+use Test::More;
+
+if (!$Config::Config{d_fork} || $ENV{PERLONJAVA_EXECUTABLE} || $^X =~ /(?:^|[\/\\])jperl(?:\z|[.])/) {
+ plan skip_all => 't/08warndie.t requires fork() to capture child STDERR';
+}
+
+plan tests => 21;

use Error qw/ :warndie /;

31 changes: 21 additions & 10 deletions src/main/perl/lib/vars.pm
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,27 @@ sub import {
}
}
$sym = "${callpack}::$sym" unless $sym =~ /::/;
*$sym =
( $ch eq "\$" ? \$$sym
: $ch eq "\@" ? \@$sym
: $ch eq "\%" ? \%$sym
: $ch eq "\*" ? \*$sym
: $ch eq "\&" ? \&$sym
: do {
require Carp;
Carp::croak("'$_' is not a valid variable name");
});
if ($ch eq "\*") {
# A typeglob declaration predeclares all variable slots under
# strict vars. Materialize the common value slots explicitly so
# runtimes without native Gv slot metadata can make the same
# strict-vars decision as perl.
*$sym = \$$sym;
*$sym = \@$sym;
*$sym = \%$sym;
*$sym = \*$sym;
}
else {
*$sym =
( $ch eq "\$" ? \$$sym
: $ch eq "\@" ? \@$sym
: $ch eq "\%" ? \%$sym
: $ch eq "\&" ? \&$sym
: do {
require Carp;
Carp::croak("'$_' is not a valid variable name");
});
}
} else {
require Carp;
Carp::croak("'$_' is not a valid variable name");
Expand Down
25 changes: 25 additions & 0 deletions src/test/resources/unit/core_global_time_overrides.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use strict;
use warnings;
use Test::More tests => 5;

BEGIN {
*CORE::GLOBAL::localtime = sub (;$) {
return wantarray ? (1, 2, 3, 4, 5, 106, 0, 0, 1) : 'mock localtime';
};
*CORE::GLOBAL::gmtime = sub (;$) {
return wantarray ? (6, 7, 8, 9, 10, 111, 0, 0, 0) : 'mock gmtime';
};
}

is scalar(localtime), 'mock localtime',
'CORE::GLOBAL::localtime overrides bare localtime';
is_deeply [ localtime(3) ], [ 1, 2, 3, 4, 5, 106, 0, 0, 1 ],
'CORE::GLOBAL::localtime receives explicit arguments';

is scalar(gmtime), 'mock gmtime',
'CORE::GLOBAL::gmtime overrides bare gmtime';
is_deeply [ gmtime(3) ], [ 6, 7, 8, 9, 10, 111, 0, 0, 0 ],
'CORE::GLOBAL::gmtime receives explicit arguments';

like scalar(CORE::gmtime(0)), qr/\AThu Jan\s+1 00:00:00 1970\z/,
'CORE::gmtime bypasses CORE::GLOBAL override';
40 changes: 40 additions & 0 deletions src/test/resources/unit/digest_sha1_compat.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;

use Digest::SHA1 qw(sha1 sha1_hex sha1_base64 sha1_transform);

is(Digest::SHA1->new->add("abc")->hexdigest,
"a9993e364706816aba3e25717850c26c9cd0d89d",
"Digest::SHA1 object API uses SHA-1");

is(sha1("abc"), pack("H*", "a9993e364706816aba3e25717850c26c9cd0d89d"),
"sha1 returns binary digest");

is(sha1_hex("abc"), "a9993e364706816aba3e25717850c26c9cd0d89d",
"sha1_hex returns hex digest");

is(sha1_base64("abc"), "qZk+NkcGgWq6PiVxeFDCbJzQ2J0",
"sha1_base64 returns unpadded base64 digest");

is(sha1_transform(pack("H*", "dc71a8092d4b1b7b98101d58698d9d1cc48225bb")),
pack("H*", "2e4c75ad39160f52614d122e6c7ec80446f68567"),
"sha1_transform matches Digest::SHA1 vector");

my $digest = Digest::SHA1->new;
is($digest->hexdigest, "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"empty digest works");

$digest->add("abc");
is($digest->clone->hexdigest, "a9993e364706816aba3e25717850c26c9cd0d89d",
"clone preserves state");

$digest->add("d");
is($digest->hexdigest, "81fe8bfe87576c3ecb22426f8e57847382917acf",
"continued add state matches SHA-1");

is($digest->hexdigest, "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"digest resets after read");

done_testing;
Loading
Loading