@@ -724,6 +724,7 @@ static php_iconv_err_t _php_iconv_strlen(size_t *pretval, const char *str, size_
724
724
size_t out_left ;
725
725
726
726
size_t cnt ;
727
+ int more ;
727
728
728
729
* pretval = (size_t )-1 ;
729
730
@@ -743,25 +744,23 @@ static php_iconv_err_t _php_iconv_strlen(size_t *pretval, const char *str, size_
743
744
744
745
errno = 0 ;
745
746
out_left = 0 ;
747
+ more = nbytes > 0 ;
746
748
747
- for (in_p = str , in_left = nbytes , cnt = 0 ; in_left > 0 ; cnt += 2 ) {
748
- size_t prev_in_left ;
749
+ for (in_p = str , in_left = nbytes , cnt = 0 ; more ;) {
749
750
out_p = buf ;
750
751
out_left = sizeof (buf );
751
752
752
- prev_in_left = in_left ;
753
+ more = in_left > 0 ;
753
754
754
- if (iconv (cd , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
755
- if (prev_in_left == in_left ) {
756
- break ;
757
- }
755
+ iconv (cd , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
756
+ if (out_left == sizeof (buf )) {
757
+ break ;
758
+ } else {
759
+ ZEND_ASSERT ((sizeof (buf ) - out_left ) % GENERIC_SUPERSET_NBYTES == 0 );
760
+ cnt += (sizeof (buf ) - out_left ) / GENERIC_SUPERSET_NBYTES ;
758
761
}
759
762
}
760
763
761
- if (out_left > 0 ) {
762
- cnt -= out_left / GENERIC_SUPERSET_NBYTES ;
763
- }
764
-
765
764
#if ICONV_SUPPORTS_ERRNO
766
765
switch (errno ) {
767
766
case EINVAL :
@@ -810,6 +809,7 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval,
810
809
811
810
size_t cnt ;
812
811
size_t total_len ;
812
+ int more ;
813
813
814
814
err = _php_iconv_strlen (& total_len , str , nbytes , enc );
815
815
if (err != PHP_ICONV_ERR_SUCCESS ) {
@@ -864,18 +864,17 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval,
864
864
865
865
cd2 = (iconv_t )NULL ;
866
866
errno = 0 ;
867
+ more = nbytes > 0 && len > 0 ;
867
868
868
- for (in_p = str , in_left = nbytes , cnt = 0 ; in_left > 0 && len > 0 ; ++ cnt ) {
869
- size_t prev_in_left ;
869
+ for (in_p = str , in_left = nbytes , cnt = 0 ; more ; ++ cnt ) {
870
870
out_p = buf ;
871
871
out_left = sizeof (buf );
872
872
873
- prev_in_left = in_left ;
873
+ more = in_left > 0 && len > 0 ;
874
874
875
- if (iconv (cd1 , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
876
- if (prev_in_left == in_left ) {
877
- break ;
878
- }
875
+ iconv (cd1 , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
876
+ if (out_left == sizeof (buf )) {
877
+ break ;
879
878
}
880
879
881
880
if ((zend_long )cnt >= offset ) {
@@ -963,6 +962,8 @@ static php_iconv_err_t _php_iconv_strpos(size_t *pretval,
963
962
size_t ndl_buf_left ;
964
963
965
964
size_t match_ofs ;
965
+ int more ;
966
+ size_t iconv_ret ;
966
967
967
968
* pretval = (size_t )-1 ;
968
969
@@ -995,37 +996,38 @@ static php_iconv_err_t _php_iconv_strpos(size_t *pretval,
995
996
ndl_buf_p = ZSTR_VAL (ndl_buf );
996
997
ndl_buf_left = ZSTR_LEN (ndl_buf );
997
998
match_ofs = (size_t )-1 ;
999
+ more = haystk_nbytes > 0 ;
998
1000
999
- for (in_p = haystk , in_left = haystk_nbytes , cnt = 0 ; in_left > 0 ; ++ cnt ) {
1000
- size_t prev_in_left ;
1001
+ for (in_p = haystk , in_left = haystk_nbytes , cnt = 0 ; more ; ++ cnt ) {
1001
1002
out_p = buf ;
1002
1003
out_left = sizeof (buf );
1003
1004
1004
- prev_in_left = in_left ;
1005
+ more = in_left > 0 ;
1005
1006
1006
- if (iconv (cd , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
1007
- if (prev_in_left == in_left ) {
1007
+ iconv_ret = iconv (cd , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
1008
+ if (out_left == sizeof (buf )) {
1009
+ break ;
1010
+ }
1008
1011
#if ICONV_SUPPORTS_ERRNO
1009
- switch (errno ) {
1010
- case EINVAL :
1011
- err = PHP_ICONV_ERR_ILLEGAL_CHAR ;
1012
- break ;
1012
+ if (iconv_ret == (size_t )-1 ) {
1013
+ switch (errno ) {
1014
+ case EINVAL :
1015
+ err = PHP_ICONV_ERR_ILLEGAL_CHAR ;
1016
+ break ;
1013
1017
1014
- case EILSEQ :
1015
- err = PHP_ICONV_ERR_ILLEGAL_SEQ ;
1016
- break ;
1018
+ case EILSEQ :
1019
+ err = PHP_ICONV_ERR_ILLEGAL_SEQ ;
1020
+ break ;
1017
1021
1018
- case E2BIG :
1019
- break ;
1022
+ case E2BIG :
1023
+ break ;
1020
1024
1021
- default :
1022
- err = PHP_ICONV_ERR_UNKNOWN ;
1023
- break ;
1024
- }
1025
- #endif
1026
- break ;
1025
+ default :
1026
+ err = PHP_ICONV_ERR_UNKNOWN ;
1027
+ break ;
1027
1028
}
1028
1029
}
1030
+ #endif
1029
1031
if (offset >= 0 ) {
1030
1032
if (cnt >= (size_t )offset ) {
1031
1033
if (_php_iconv_memequal (buf , ndl_buf_p , sizeof (buf ))) {
@@ -1997,6 +1999,13 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st
1997
1999
* next_pos = p1 ;
1998
2000
}
1999
2001
2002
+ if (cd != (iconv_t )(-1 )) {
2003
+ _php_iconv_appendl (pretval , NULL , 0 , cd );
2004
+ }
2005
+ if (cd_pl != (iconv_t )(-1 )) {
2006
+ _php_iconv_appendl (pretval , NULL , 0 , cd_pl );
2007
+ }
2008
+
2000
2009
smart_str_0 (pretval );
2001
2010
out :
2002
2011
if (cd != (iconv_t )(-1 )) {
0 commit comments