Skip to content

Commit

Permalink
disallow creating Uni with out-of-range codepoints
Browse files Browse the repository at this point in the history
  • Loading branch information
moon-chilled committed Sep 2, 2021
1 parent ffde2ba commit c56c578
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
9 changes: 9 additions & 0 deletions src/core.c/Exception.pm6
Expand Up @@ -3327,6 +3327,15 @@ my class X::CompUnit::UnsatisfiedDependency is Exception {
}
}

my class X::InvalidCodepoint is Exception {
has $.code;
method message() {
$.code > 0x10ffff
?? "Invalid codepoint $.code; must not exceed 0x10ffff (1114111)"
!! "Invalid surrogate codepoint $.code"
}
}

my class Exceptions::JSON {
method process($ex) {
$*ERR.print: Rakudo::Internals::JSON.to-json($ex);
Expand Down
10 changes: 8 additions & 2 deletions src/core.c/Uni.pm6
Expand Up @@ -3,18 +3,24 @@ my class NFD is repr('VMArray') is array_type(uint32) { ... }
my class NFKC is repr('VMArray') is array_type(uint32) { ... }
my class NFKD is repr('VMArray') is array_type(uint32) { ... }

my class X::InvalidCodepoint { ... }

my class Uni does Positional[uint32] does Stringy is repr('VMArray') is array_type(uint32) {

multi method new(Uni:) { nqp::create(self) }
multi method new(Uni: *@codes) {
@codes.elems; # reify and test for lazy sequences
my $uni := nqp::create(self);
my $codepoints := nqp::getattr(@codes,List,'$!reified');
my $code;

nqp::while(
nqp::elems($codepoints),
nqp::push_i($uni,nqp::shift($codepoints))
);
nqp::if(nqp::isgt_i($code = nqp::shift($codepoints), 0x10ffff)
|| (nqp::isle_i(0xd800, $code) && nqp::isle_i($code, 0xdfff))
|| nqp::islt_i($code, 0),
X::InvalidCodepoint.new(:$code).throw,
nqp::push_i($uni,$code)));

$uni
}
Expand Down
7 changes: 6 additions & 1 deletion src/core.c/core_epilogue.pm6
Expand Up @@ -67,10 +67,15 @@ augment class Uni {
my $uni := nqp::create(self);
my int $elems = nqp::elems(codepoints);
my int $i = -1;
my int $code;

nqp::while(
nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
nqp::push_i($uni,nqp::atpos_i(codepoints,$i))
nqp::if(nqp::isgt_i($code = nqp::atpos_i(codepoints,$i), 0x10ffff)
|| (nqp::isle_i(0xd800, $code) && nqp::isle_i($code, 0xdfff))
|| nqp::islt_i($code, 0),
X::InvalidCodepoint.new(:$code).throw,
nqp::push_i($uni,$code))
);

$uni
Expand Down

0 comments on commit c56c578

Please sign in to comment.