@@ -302,18 +302,32 @@ private function white()
302302
303303 private function error ($ m )
304304 {
305- $ i =0 ;
306305 $ col =0 ;
306+ $ colBytes = 0 ;
307307 $ line =1 ;
308308 for ($ i = $ this ->at -1 ; $ i > 0 && @$ this ->text [$ i ] !== "\n" ; $ i --, $ col ++) {
309309 }
310+
311+ $ i = $ this ->at ;
312+ while ($ i > 0 ) {
313+ $ ch = mb_substr (mb_strcut ($ this ->text , $ i - 1 ), 0 , 1 );
314+ $ i += strlen ($ ch );
315+
316+ if ($ ch === "\n" ) {
317+ break ;
318+ }
319+
320+ $ col ++;
321+ $ colBytes += strlen ($ ch );
322+ }
323+
310324 for (; $ i > 0 ;
311325 $ i --) {
312326 if ($ this ->text [$ i ] === "\n" ) {
313327 $ line ++;
314328 }
315329 }
316- throw new HJSONException ("$ m at line $ line, $ col >>> " . mb_substr ($ this ->text , $ this ->at - $ col , 20 ) ." ... " );
330+ throw new HJSONException ("$ m at line $ line, $ col >>> " . mb_substr (mb_strcut ( $ this ->text , $ this ->at - $ colBytes ), 0 , 20 ) ." ... " );
317331 }
318332
319333 private function next ($ c = false )
@@ -327,14 +341,14 @@ private function next($c = false)
327341 // Get the next character. When there are no more characters,
328342 // return the empty string.
329343 $ this ->ch = (strlen ($ this ->text ) > $ this ->at ) ? mb_substr (mb_strcut ($ this ->text , $ this ->at ), 0 , 1 ) : null ;
330- $ this ->at = $ this -> at + strlen ($ this ->ch );
344+ $ this ->at += strlen ($ this ->ch );
331345 return $ this ->ch ;
332346 }
333347
334348 private function peek ($ offs )
335349 {
336350 // range check is not required
337- return $ this ->text [ $ this ->at + $ offs] ;
351+ return mb_substr ( mb_strcut ( $ this ->text , $ this ->at ), $ offs, 1 ) ;
338352 }
339353
340354 private function skipIndent ($ indent )
0 commit comments