Browse Source

Ensure char and byte position never goes beyond the end of the string

labels
J. King 6 years ago
parent
commit
6fd50f0681
  1. 8
      lib/UTF8String.php
  2. 30
      tests/cases/TestCodec.php

8
lib/UTF8String.php

@ -31,7 +31,9 @@ class UTF8String {
public function nextChr(): string {
// get the byte at the current position
$b = @$this->string[$this->posByte];
if (ord($b) < 0x80) {
if ($b === "") {
return "";
} elseif (ord($b) < 0x80) {
// if the byte is an ASCII character or end of input, simply return it
$this->posChar++;
$this->posByte++;
@ -50,16 +52,16 @@ class UTF8String {
// this function effectively implements https://encoding.spec.whatwg.org/#utf-8-decoder
// though it differs from a slavish implementation because it operates on only a single
// character rather than a whole stream
$this->posChar++;
// optimization for ASCII characters
$b = @$this->string[$this->posByte];
if ($b=="") {
$this->posByte++;
return false;
} elseif (($b = ord($b)) < 0x80) {
$this->posChar++;
$this->posByte++;
return $b;
}
$this->posChar++;
$point = 0;
$seen = 0;
$needed = 1;

30
tests/cases/TestCodec.php

@ -107,6 +107,36 @@ class TestConf extends \PHPUnit\Framework\TestCase {
$this->assertSame(0, $s->posChr());
$this->assertSame(0, $s->posByte());
}
/**
* @covers \MensBeam\UTF8\UTF8String::posChr
* @covers \MensBeam\UTF8\UTF8String::posByte
*/
public function testTraversePastTheEndOfAString() {
$s = new UTF8String("a");
$this->assertSame(0, $s->posChr());
$this->assertSame(0, $s->posByte());
$this->assertSame("a", $s->nextChr());
$this->assertSame(1, $s->posChr());
$this->assertSame(1, $s->posByte());
$this->assertSame("", $s->nextChr());
$this->assertSame(1, $s->posChr());
$this->assertSame(1, $s->posByte());
$s = new UTF8String("a");
$this->assertSame(0, $s->posChr());
$this->assertSame(0, $s->posByte());
$this->assertSame(ord("a"), $s->nextOrd());
$this->assertSame(1, $s->posChr());
$this->assertSame(1, $s->posByte());
$this->assertSame(false, $s->nextOrd());
$this->assertSame(1, $s->posChr());
$this->assertSame(1, $s->posByte());
}
public function provideStrings() {
return [

Loading…
Cancel
Save