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
1 change: 1 addition & 0 deletions docs/about/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Release history of PerlOnJava. See [Roadmap](roadmap.md) for future plans.
- Fix localization of numbered regex captures.
- Fix IO-handle type checks and uninitialized-value warning locations.
- Fix numeric-zero results from failed `s///` substitutions.
- Preserve references in `utf8::downgrade`.
- Bundle the complete CPAN `File::Path` 2.18 implementation, including modern
`rmtree`/`remove_tree` options such as `keep_root`, `error`, `result`,
`safe`, and `verbose`.
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/perlonjava/runtime/perlmodule/Utf8.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ public static RuntimeList downgrade(RuntimeArray args, int ctx) {
RuntimeScalar scalar = args.get(0);
boolean wasTainted = GlobalContext.isTaintModeActive() && scalar.isTainted();
boolean failOk = args.size() == 2 && args.get(1).getBoolean();

// References do not have a UTF-8 flag. Perl treats downgrade() on a
// reference as a successful no-op; converting it through toString()
// would replace the reference with its stringified form.
if (RuntimeScalarType.isReference(scalar)) {
return RuntimeScalarCache.scalarTrue.getList();
}

String string = scalar.toString();

// Check if the string can be represented in ISO-8859-1
Expand Down
23 changes: 23 additions & 0 deletions src/test/resources/unit/utf8_downgrade_references.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use strict;
use warnings;
use Test::More;

my $scalar = 'value';
my $object = bless {}, 'Local::Downgrade::Object';
my @references = (
[ CODE => sub { 42 } ],
[ ARRAY => [] ],
[ HASH => {} ],
[ SCALAR => \$scalar ],
[ 'Local::Downgrade::Object' => $object ],
);

for my $case (@references) {
my ($expected_type, $value) = @$case;
is(utf8::downgrade($value, 1), 1, "downgrade succeeds for $expected_type reference");
is(ref($value), $expected_type, "downgrade preserves $expected_type reference");
}

is($references[0][1]->(), 42, 'downgrade preserves a callable code reference');

done_testing;
Loading