@@ -739,6 +739,7 @@ static php_iconv_err_t _php_iconv_strlen(size_t *pretval, const char *str, size_
739
739
size_t out_left ;
740
740
741
741
size_t cnt ;
742
+ int more ;
742
743
743
744
* pretval = (size_t )-1 ;
744
745
@@ -758,25 +759,23 @@ static php_iconv_err_t _php_iconv_strlen(size_t *pretval, const char *str, size_
758
759
759
760
errno = 0 ;
760
761
out_left = 0 ;
762
+ more = nbytes > 0 ;
761
763
762
- for (in_p = str , in_left = nbytes , cnt = 0 ; in_left > 0 ; cnt += 2 ) {
763
- size_t prev_in_left ;
764
+ for (in_p = str , in_left = nbytes , cnt = 0 ; more ;) {
764
765
out_p = buf ;
765
766
out_left = sizeof (buf );
766
767
767
- prev_in_left = in_left ;
768
+ more = in_left > 0 ;
768
769
769
- if (iconv (cd , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
770
- if (prev_in_left == in_left ) {
771
- break ;
772
- }
770
+ iconv (cd , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
771
+ if (out_left == sizeof (buf )) {
772
+ break ;
773
+ } else {
774
+ ZEND_ASSERT ((sizeof (buf ) - out_left ) % GENERIC_SUPERSET_NBYTES == 0 );
775
+ cnt += (sizeof (buf ) - out_left ) / GENERIC_SUPERSET_NBYTES ;
773
776
}
774
777
}
775
778
776
- if (out_left > 0 ) {
777
- cnt -= out_left / GENERIC_SUPERSET_NBYTES ;
778
- }
779
-
780
779
#if ICONV_SUPPORTS_ERRNO
781
780
switch (errno ) {
782
781
case EINVAL :
@@ -825,6 +824,7 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval,
825
824
826
825
size_t cnt ;
827
826
size_t total_len ;
827
+ int more ;
828
828
829
829
err = _php_iconv_strlen (& total_len , str , nbytes , enc );
830
830
if (err != PHP_ICONV_ERR_SUCCESS ) {
@@ -879,18 +879,17 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval,
879
879
880
880
cd2 = (iconv_t )NULL ;
881
881
errno = 0 ;
882
+ more = nbytes > 0 && len > 0 ;
882
883
883
- for (in_p = str , in_left = nbytes , cnt = 0 ; in_left > 0 && len > 0 ; ++ cnt ) {
884
- size_t prev_in_left ;
884
+ for (in_p = str , in_left = nbytes , cnt = 0 ; more ; ++ cnt ) {
885
885
out_p = buf ;
886
886
out_left = sizeof (buf );
887
887
888
- prev_in_left = in_left ;
888
+ more = in_left > 0 && len > 0 ;
889
889
890
- if (iconv (cd1 , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
891
- if (prev_in_left == in_left ) {
892
- break ;
893
- }
890
+ iconv (cd1 , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
891
+ if (out_left == sizeof (buf )) {
892
+ break ;
894
893
}
895
894
896
895
if ((zend_long )cnt >= offset ) {
@@ -978,6 +977,8 @@ static php_iconv_err_t _php_iconv_strpos(size_t *pretval,
978
977
size_t ndl_buf_left ;
979
978
980
979
size_t match_ofs ;
980
+ int more ;
981
+ size_t iconv_ret ;
981
982
982
983
* pretval = (size_t )-1 ;
983
984
@@ -1010,37 +1011,38 @@ static php_iconv_err_t _php_iconv_strpos(size_t *pretval,
1010
1011
ndl_buf_p = ZSTR_VAL (ndl_buf );
1011
1012
ndl_buf_left = ZSTR_LEN (ndl_buf );
1012
1013
match_ofs = (size_t )-1 ;
1014
+ more = haystk_nbytes > 0 ;
1013
1015
1014
- for (in_p = haystk , in_left = haystk_nbytes , cnt = 0 ; in_left > 0 ; ++ cnt ) {
1015
- size_t prev_in_left ;
1016
+ for (in_p = haystk , in_left = haystk_nbytes , cnt = 0 ; more ; ++ cnt ) {
1016
1017
out_p = buf ;
1017
1018
out_left = sizeof (buf );
1018
1019
1019
- prev_in_left = in_left ;
1020
+ more = in_left > 0 ;
1020
1021
1021
- if (iconv (cd , (char * * )& in_p , & in_left , (char * * ) & out_p , & out_left ) == (size_t )-1 ) {
1022
- if (prev_in_left == in_left ) {
1022
+ iconv_ret = iconv (cd , more ? (char * * )& in_p : NULL , more ? & in_left : NULL , (char * * ) & out_p , & out_left );
1023
+ if (out_left == sizeof (buf )) {
1024
+ break ;
1025
+ }
1023
1026
#if ICONV_SUPPORTS_ERRNO
1024
- switch (errno ) {
1025
- case EINVAL :
1026
- err = PHP_ICONV_ERR_ILLEGAL_CHAR ;
1027
- break ;
1027
+ if (iconv_ret == (size_t )-1 ) {
1028
+ switch (errno ) {
1029
+ case EINVAL :
1030
+ err = PHP_ICONV_ERR_ILLEGAL_CHAR ;
1031
+ break ;
1028
1032
1029
- case EILSEQ :
1030
- err = PHP_ICONV_ERR_ILLEGAL_SEQ ;
1031
- break ;
1033
+ case EILSEQ :
1034
+ err = PHP_ICONV_ERR_ILLEGAL_SEQ ;
1035
+ break ;
1032
1036
1033
- case E2BIG :
1034
- break ;
1037
+ case E2BIG :
1038
+ break ;
1035
1039
1036
- default :
1037
- err = PHP_ICONV_ERR_UNKNOWN ;
1038
- break ;
1039
- }
1040
- #endif
1041
- break ;
1040
+ default :
1041
+ err = PHP_ICONV_ERR_UNKNOWN ;
1042
+ break ;
1042
1043
}
1043
1044
}
1045
+ #endif
1044
1046
if (offset >= 0 ) {
1045
1047
if (cnt >= (size_t )offset ) {
1046
1048
if (_php_iconv_memequal (buf , ndl_buf_p , sizeof (buf ))) {
@@ -2012,6 +2014,13 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st
2012
2014
* next_pos = p1 ;
2013
2015
}
2014
2016
2017
+ if (cd != (iconv_t )(-1 )) {
2018
+ _php_iconv_appendl (pretval , NULL , 0 , cd );
2019
+ }
2020
+ if (cd_pl != (iconv_t )(-1 )) {
2021
+ _php_iconv_appendl (pretval , NULL , 0 , cd_pl );
2022
+ }
2023
+
2015
2024
smart_str_0 (pretval );
2016
2025
out :
2017
2026
if (cd != (iconv_t )(-1 )) {
0 commit comments