Skip to content

Commit bcce266

Browse files
Multibyte string support
1 parent b79da99 commit bcce266

File tree

6 files changed

+15
-9
lines changed

6 files changed

+15
-9
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
],
1414

1515
"require": {
16-
"php": ">=5.4.0"
16+
"php": ">=5.4.0",
17+
"symfony/polyfill-mbstring": "^1.4"
1718
},
1819

1920
"require-dev": {

src/FnDispatcher.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private function fn_contains(array $args)
6262
if (is_array($args[0])) {
6363
return in_array($args[1], $args[0]);
6464
} elseif (is_string($args[1])) {
65-
return strpos($args[0], $args[1]) !== false;
65+
return mb_strpos($args[0], $args[1], 0, 'UTF-8') !== false;
6666
} else {
6767
return null;
6868
}
@@ -72,7 +72,7 @@ private function fn_ends_with(array $args)
7272
{
7373
$this->validate('ends_with', $args, [['string'], ['string']]);
7474
list($search, $suffix) = $args;
75-
return $suffix === '' || substr($search, -strlen($suffix)) === $suffix;
75+
return $suffix === '' || mb_substr($search, -mb_strlen($suffix, 'UTF-8'), null, 'UTF-8') === $suffix;
7676
}
7777

7878
private function fn_floor(array $args)
@@ -112,7 +112,7 @@ private function fn_keys(array $args)
112112
private function fn_length(array $args)
113113
{
114114
$this->validate('length', $args, [['string', 'array', 'object']]);
115-
return is_string($args[0]) ? strlen($args[0]) : count((array) $args[0]);
115+
return is_string($args[0]) ? mb_strlen($args[0], 'UTF-8') : count((array) $args[0]);
116116
}
117117

118118
private function fn_max(array $args)
@@ -207,7 +207,7 @@ private function fn_starts_with(array $args)
207207
{
208208
$this->validate('starts_with', $args, [['string'], ['string']]);
209209
list($search, $prefix) = $args;
210-
return $prefix === '' || strpos($search, $prefix) === 0;
210+
return $prefix === '' || mb_strpos($search, $prefix, 0, 'UTF-8') === 0;
211211
}
212212

213213
private function fn_type(array $args)
@@ -240,7 +240,7 @@ private function fn_to_number(array $args)
240240
if ($type == 'number') {
241241
return $value;
242242
} elseif ($type == 'string' && is_numeric($value)) {
243-
return strpos($value, '.') ? (float) $value : (int) $value;
243+
return mb_strpos($value, '.', 0, 'UTF-8') ? (float) $value : (int) $value;
244244
} else {
245245
return null;
246246
}
@@ -282,7 +282,7 @@ private function fn_map(array $args)
282282

283283
private function typeError($from, $msg)
284284
{
285-
if (strpos($from, ':')) {
285+
if (mb_strpos($from, ':', 0, 'UTF-8')) {
286286
list($fn, $pos) = explode(':', $from);
287287
throw new \RuntimeException(
288288
sprintf('Argument %d of %s %s', $pos, $fn, $msg)

src/Lexer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ public function tokenize($input)
340340
eof:
341341
$tokens[] = [
342342
'type' => self::T_EOF,
343-
'pos' => strlen($input),
343+
'pos' => mb_strlen($input, 'UTF-8'),
344344
'value' => null
345345
];
346346

src/Utils.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ private static function adjustSlice($length, $start, $stop, $step)
214214
private static function sliceIndices($subject, $start, $stop, $step)
215215
{
216216
$type = gettype($subject);
217-
$len = $type == 'string' ? strlen($subject) : count($subject);
217+
$len = $type == 'string' ? mb_strlen($subject, 'UTF-8') : count($subject);
218218
list($start, $stop, $step) = self::adjustSlice($len, $start, $stop, $step);
219219

220220
$result = [];

tests/ComplianceTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public function testPassesCompliance(
6161

6262
$file = __DIR__ . '/compliance/' . $file . '.json';
6363
$failure .= "\n{$compiledStr}php bin/jp.php --file {$file} --suite {$suite} --case {$case}\n\n"
64+
. "Result: " . $this->prettyJson($evalResult) . "\n\n"
6465
. "Expected: " . $this->prettyJson($result) . "\n\n";
6566
$failure .= 'Associative? ' . var_export($asAssoc, true) . "\n\n";
6667

tests/compliance/functions.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@
179179
"expression": "length('abc')",
180180
"result": 3
181181
},
182+
{
183+
"expression": "length('✓foo')",
184+
"result": 4
185+
},
182186
{
183187
"expression": "length('')",
184188
"result": 0

0 commit comments

Comments
 (0)