Skip to content

Commit a6c2ba3

Browse files
committed
Catch and re-issue utf8 warnings at a higher level
This catches Encode::Unicode warnings and re-issues them from Encode, so that callers can disable warnings lexically with `no warnings 'utf8'`. Fixes https://rt.cpan.org/Ticket/Display.html?id=88592
1 parent 3e9fd0c commit a6c2ba3

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

Encode.pm

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,20 @@ sub encode($$;$) {
156156
require Carp;
157157
Carp::croak("Unknown encoding '$name'");
158158
}
159-
my $octets = $enc->encode( $string, $check );
159+
# For Unicode, warnings need to be caught and re-issued at this level
160+
# so that callers can disable utf8 warnings lexically.
161+
my $octets;
162+
if ( ref($enc) eq 'Encode::Unicode' ) {
163+
my $warn = '';
164+
{
165+
local $SIG{__WARN__} = sub { $warn = shift };
166+
$octets = $enc->encode( $string, $check );
167+
}
168+
warnings::warnif('utf8', $warn) if length $warn;
169+
}
170+
else {
171+
$octets = $enc->encode( $string, $check );
172+
}
160173
$_[1] = $string if $check and !ref $check and !( $check & LEAVE_SRC() );
161174
return $octets;
162175
}
@@ -172,7 +185,20 @@ sub decode($$;$) {
172185
require Carp;
173186
Carp::croak("Unknown encoding '$name'");
174187
}
175-
my $string = $enc->decode( $octets, $check );
188+
# For Unicode, warnings need to be caught and re-issued at this level
189+
# so that callers can disable utf8 warnings lexically.
190+
my $string;
191+
if ( ref($enc) eq 'Encode::Unicode' ) {
192+
my $warn = '';
193+
{
194+
local $SIG{__WARN__} = sub { $warn = shift };
195+
$string = $enc->decode( $octets, $check );
196+
}
197+
warnings::warnif('utf8', $warn) if length $warn;
198+
}
199+
else {
200+
$string = $enc->decode( $octets, $check );
201+
}
176202
$_[1] = $octets if $check and !ref $check and !( $check & LEAVE_SRC() );
177203
return $string;
178204
}

t/utf8warnings.t

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use strict;
2+
use warnings;
3+
4+
use Encode;
5+
use Test::More tests => 7;
6+
7+
my $valid = "\x61\x00\x00\x00";
8+
my $invalid = "\x78\x56\x34\x12";
9+
10+
my @warnings;
11+
$SIG{__WARN__} = sub {push @warnings, "@_"};
12+
13+
my $enc = find_encoding("UTF32-LE");
14+
15+
{
16+
@warnings = ();
17+
my $ret = Encode::Unicode::decode( $enc, $valid );
18+
is("@warnings", "", "Calling decode in Encode::Unicode on valid string produces no warnings");
19+
}
20+
21+
{
22+
@warnings = ();
23+
my $ret = Encode::Unicode::decode( $enc, $invalid );
24+
like("@warnings", qr/is not Unicode/, "Calling decode in Encode::Unicode on invalid string warns");
25+
}
26+
27+
{
28+
no warnings 'utf8';
29+
@warnings = ();
30+
my $ret = Encode::Unicode::decode( $enc, $invalid );
31+
is("@warnings", "", "Warning from decode in Encode::Unicode can be silenced via no warnings 'utf8'");
32+
}
33+
34+
{
35+
no warnings;
36+
@warnings = ();
37+
my $ret = Encode::Unicode::decode( $enc, $invalid );
38+
is("@warnings", "", "Warning from decode in Encode::Unicode can be silenced via no warnings");
39+
}
40+
41+
{
42+
@warnings = ();
43+
my $ret = Encode::decode( $enc, $invalid );
44+
like("@warnings", qr/is not Unicode/, "Calling decode in Encode on invalid string warns");
45+
}
46+
47+
{
48+
no warnings 'utf8';
49+
@warnings = ();
50+
my $ret = Encode::decode( $enc, $invalid );
51+
is("@warnings", "", "Warning from decode in Encode can be silenced via no warnings 'utf8'");
52+
};
53+
54+
{
55+
no warnings;
56+
@warnings = ();
57+
my $ret = Encode::decode( $enc, $invalid );
58+
is("@warnings", "", "Warning from decode in Encode can be silenced via no warnings 'utf8'");
59+
};
60+

0 commit comments

Comments
 (0)