Skip to content

select() reacts improperly to UTF8-flagged strings #19882

Closed
@FGasper

Description

@FGasper

Description
Perl’s select() has the “Unicode bug”.

The impact is low, but the fix is trivial.

The potential for breakage seems low enough that this one is OK to fix.

Steps to Reproduce

#!/usr/bin/env perl

use strict;
use warnings;

use Test::More;

use File::Temp;

my $mask;
my @fhs;

while (!defined $mask) {
    push @fhs, scalar File::Temp::tempfile();
    vec( my $curmask, fileno($fhs[-1]), 1 ) = 1;

    if ($curmask =~ m<[\x80-\xff]>) {
        $mask = $curmask;
    }
}

print "FD: " . fileno($fhs[-1]) . $/;

my $result = select $mask, undef, undef, 0;
print "error: $!" if $result == -1;

is($result, 1, 'file is readable (downgraded input to select)');

utf8::upgrade($mask);

$result = select $mask, undef, undef, 0;

is($result, 1, 'file is readable (upgraded input to select)');

done_testing;

Expected behavior
The strace output of the 2nd one-liner should match that of the first one.

Perl configuration
This happens in blead as of now.

This fixes it:

diff --git a/pp_sys.c b/pp_sys.c
index a3bc0794a2..6bfa98f14f 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1165,7 +1165,10 @@ PP(pp_sselect)
                 Perl_croak_no_modify();
         }
         else if (SvIsCOW(sv)) sv_force_normal_flags(sv, 0);
-        if (!SvPOK(sv)) {
+        if (SvPOK(sv)) {
+            if (SvUTF8(sv)) sv_utf8_downgrade(sv, FALSE);
+        }
+        else {
             if (!SvPOKp(sv))
                 Perl_ck_warner(aTHX_ packWARN(WARN_MISC),
                                     "Non-string passed as bitmask");

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions