@@ -578,6 +578,7 @@ static php_iconv_err_t _php_iconv_strlen(size_t *pretval, const char *str, size_
578
578
size_t out_left ;
579
579
580
580
size_t cnt ;
581
+ int more ;
581
582
582
583
* pretval = (size_t )-1 ;
583
584
@@ -593,25 +594,23 @@ static php_iconv_err_t _php_iconv_strlen(size_t *pretval, const char *str, size_
593
594
594
595
errno = 0 ;
595
596
out_left = 0 ;
597
+ more = nbytes > 0 ;
596
598
597
- for (in_p = str , in_left = nbytes , cnt = 0 ; in_left > 0 ; cnt += 2 ) {
598
- size_t prev_in_left ;
599
+ for (in_p = str , in_left = nbytes , cnt = 0 ; more ;) {
599
600
out_p = buf ;
600
601
out_left = sizeof (buf );
601
602
602
- prev_in_left = in_left ;
603
+ more = in_left > 0 ;
603
604
604
- if (iconv (cd , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
605
- if (prev_in_left == in_left ) {
606
- break ;
607
- }
605
+ iconv (cd , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
606
+ if (out_left == sizeof (buf )) {
607
+ break ;
608
+ } else {
609
+ ZEND_ASSERT ((sizeof (buf ) - out_left ) % GENERIC_SUPERSET_NBYTES == 0 );
610
+ cnt += (sizeof (buf ) - out_left ) / GENERIC_SUPERSET_NBYTES ;
608
611
}
609
612
}
610
613
611
- if (out_left > 0 ) {
612
- cnt -= out_left / GENERIC_SUPERSET_NBYTES ;
613
- }
614
-
615
614
switch (errno ) {
616
615
case EINVAL :
617
616
err = PHP_ICONV_ERR_ILLEGAL_CHAR ;
@@ -656,6 +655,7 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval,
656
655
657
656
size_t cnt ;
658
657
size_t total_len ;
658
+ int more ;
659
659
660
660
err = _php_iconv_strlen (& total_len , str , nbytes , enc );
661
661
if (err != PHP_ICONV_ERR_SUCCESS ) {
@@ -706,18 +706,17 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval,
706
706
707
707
cd2 = (iconv_t )NULL ;
708
708
errno = 0 ;
709
+ more = nbytes > 0 && len > 0 ;
709
710
710
- for (in_p = str , in_left = nbytes , cnt = 0 ; in_left > 0 && len > 0 ; ++ cnt ) {
711
- size_t prev_in_left ;
711
+ for (in_p = str , in_left = nbytes , cnt = 0 ; more ; ++ cnt ) {
712
712
out_p = buf ;
713
713
out_left = sizeof (buf );
714
714
715
- prev_in_left = in_left ;
715
+ more = in_left > 0 && len > 0 ;
716
716
717
- if (iconv (cd1 , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
718
- if (prev_in_left == in_left ) {
719
- break ;
720
- }
717
+ iconv (cd1 , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
718
+ if (out_left == sizeof (buf )) {
719
+ break ;
721
720
}
722
721
723
722
if ((zend_long )cnt >= offset ) {
@@ -799,6 +798,8 @@ static php_iconv_err_t _php_iconv_strpos(size_t *pretval,
799
798
size_t ndl_buf_left ;
800
799
801
800
size_t match_ofs ;
801
+ int more ;
802
+ size_t iconv_ret ;
802
803
803
804
* pretval = (size_t )-1 ;
804
805
@@ -827,33 +828,34 @@ static php_iconv_err_t _php_iconv_strpos(size_t *pretval,
827
828
ndl_buf_p = ZSTR_VAL (ndl_buf );
828
829
ndl_buf_left = ZSTR_LEN (ndl_buf );
829
830
match_ofs = (size_t )-1 ;
831
+ more = haystk_nbytes > 0 ;
830
832
831
- for (in_p = haystk , in_left = haystk_nbytes , cnt = 0 ; in_left > 0 ; ++ cnt ) {
832
- size_t prev_in_left ;
833
+ for (in_p = haystk , in_left = haystk_nbytes , cnt = 0 ; more ; ++ cnt ) {
833
834
out_p = buf ;
834
835
out_left = sizeof (buf );
835
836
836
- prev_in_left = in_left ;
837
+ more = in_left > 0 ;
837
838
838
- if (iconv (cd , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
839
- if (prev_in_left == in_left ) {
840
- switch (errno ) {
841
- case EINVAL :
842
- err = PHP_ICONV_ERR_ILLEGAL_CHAR ;
843
- break ;
839
+ iconv_ret = iconv (cd , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
840
+ if (out_left == sizeof (buf )) {
841
+ break ;
842
+ }
843
+ if (iconv_ret == (size_t )-1 ) {
844
+ switch (errno ) {
845
+ case EINVAL :
846
+ err = PHP_ICONV_ERR_ILLEGAL_CHAR ;
847
+ break ;
844
848
845
- case EILSEQ :
846
- err = PHP_ICONV_ERR_ILLEGAL_SEQ ;
847
- break ;
849
+ case EILSEQ :
850
+ err = PHP_ICONV_ERR_ILLEGAL_SEQ ;
851
+ break ;
848
852
849
- case E2BIG :
850
- break ;
853
+ case E2BIG :
854
+ break ;
851
855
852
- default :
853
- err = PHP_ICONV_ERR_UNKNOWN ;
854
- break ;
855
- }
856
- break ;
856
+ default :
857
+ err = PHP_ICONV_ERR_UNKNOWN ;
858
+ break ;
857
859
}
858
860
}
859
861
if (offset >= 0 ) {
@@ -1777,6 +1779,13 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st
1777
1779
* next_pos = p1 ;
1778
1780
}
1779
1781
1782
+ if (cd != (iconv_t )(-1 )) {
1783
+ _php_iconv_appendl (pretval , NULL , 0 , cd );
1784
+ }
1785
+ if (cd_pl != (iconv_t )(-1 )) {
1786
+ _php_iconv_appendl (pretval , NULL , 0 , cd_pl );
1787
+ }
1788
+
1780
1789
smart_str_0 (pretval );
1781
1790
out :
1782
1791
if (cd != (iconv_t )(-1 )) {
0 commit comments