git-svn: trunk@3525
Török Edvin authored on 2008/01/23 02:12:12... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Tue Jan 22 18:47:54 EET 2008 (edwin) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav/entconv.c: handle E2BIG correctly, avoid infinite loops on iconv |
|
4 |
+ errors. (bb #785) |
|
5 |
+ |
|
1 | 6 |
Tue Jan 22 15:29:15 CET 2008 (tk) |
2 | 7 |
--------------------------------- |
3 | 8 |
* configure: if available use dscl on Mac OS X (bb#753) |
... | ... |
@@ -850,6 +850,7 @@ static int in_iconv_u16(m_area_t* in_m_area, iconv_t* iconv_struct, m_area_t* ou |
850 | 850 |
if(!inleft) { |
851 | 851 |
/* EOF */ |
852 | 852 |
out_m_area->offset = out_m_area->length = 0; |
853 |
+ return 0; |
|
853 | 854 |
} |
854 | 855 |
/* convert encoding conv->tmp_area. conv->out_area */ |
855 | 856 |
alignfix = inleft%4;/* iconv gives an error if we give him 3 bytes to convert, |
... | ... |
@@ -864,21 +865,31 @@ static int in_iconv_u16(m_area_t* in_m_area, iconv_t* iconv_struct, m_area_t* ou |
864 | 864 |
inleft = 4; |
865 | 865 |
} |
866 | 866 |
|
867 |
- rc = (size_t)-1; |
|
868 |
- while (inleft && (outleft >= 2) && rc == (size_t)-1) { /* iconv doesn't like inleft to be 0 */ |
|
867 |
+ while (inleft && (outleft >= 2)) { /* iconv doesn't like inleft to be 0 */ |
|
868 |
+ const size_t outleft_last = outleft; |
|
869 | 869 |
assert(*iconv_struct != (iconv_t)-1); |
870 | 870 |
rc = iconv(*iconv_struct, (char**) &input, &inleft, (char**) &out, &outleft); |
871 |
- if(rc == (size_t)-1 && errno != E2BIG) { |
|
872 |
- cli_dbgmsg("iconv error:%s, silently resuming (%lu, %lu, %ld, %ld)\n", |
|
873 |
- strerror(errno), inleft, outleft, input - (char*)in_m_area->buffer, |
|
874 |
- out - (char*)out_m_area->buffer); |
|
875 |
- /* output raw byte, and resume at next byte */ |
|
876 |
- if(outleft < 2) break; |
|
877 |
- outleft -= 2; |
|
878 |
- *out++ = 0; |
|
879 |
- *out++ = *input++; |
|
880 |
- inleft--; |
|
871 |
+ if(rc == (size_t)-1) { |
|
872 |
+ if(errno == E2BIG) { |
|
873 |
+ /* not enough space in output buffer */ |
|
874 |
+ break; |
|
875 |
+ } |
|
876 |
+ cli_dbgmsg(MODULE_NAME "iconv error:%s\n", strerror(errno)); |
|
877 |
+ } else if(outleft == outleft_last) { |
|
878 |
+ cli_dbgmsg(MODULE_NAME "iconv stall (no output)\n"); |
|
879 |
+ } else { |
|
880 |
+ /* everything ok */ |
|
881 |
+ continue; |
|
881 | 882 |
} |
883 |
+ cli_dbgmsg(MODULE_NAME "resuming (inleft:%lu, outleft:%lu, inpos:%ld, %ld)\n", |
|
884 |
+ inleft, outleft, input - (char*)in_m_area->buffer, |
|
885 |
+ out - (char*)out_m_area->buffer); |
|
886 |
+ /* output raw byte, and resume at next byte */ |
|
887 |
+ if(outleft < 2) break; |
|
888 |
+ outleft -= 2; |
|
889 |
+ *out++ = 0; |
|
890 |
+ *out++ = *input++; |
|
891 |
+ inleft--; |
|
882 | 892 |
} |
883 | 893 |
in_m_area->offset = in_m_area->length - inleft; |
884 | 894 |
if(out_m_area->length >= 0 && out_m_area->length >= (off_t)outleft) { |