Serhiy Storchaka <storch...@gmail.com> added the comment:
Here is a patch, which took into account the Martin suggestions.
----------
title: Vulnerability in the utf-16 decoder after error handling -> Possible
vulnerability in the utf-16 decoder after error handling
Added file: http://bugs.python.org/file25352/utf16_error_handling-3.2_3.patch
_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue14579>
_______________________________________
diff -r b07488490001 Objects/unicodeobject.c
--- a/Objects/unicodeobject.c Fri Apr 20 14:36:47 2012 +0200
+++ b/Objects/unicodeobject.c Tue Apr 24 23:54:58 2012 +0300
@@ -3425,7 +3425,7 @@
/* Unpack UTF-16 encoded data */
p = unicode->str;
q = (unsigned char *)s;
- e = q + size - 1;
+ e = q + size;
if (byteorder)
bo = *byteorder;
@@ -3476,8 +3476,20 @@
#endif
aligned_end = (const unsigned char *) ((size_t) e & ~LONG_PTR_MASK);
- while (q < e) {
+ while (1) {
Py_UNICODE ch;
+ if (e - q < 2) {
+ /* remaining byte at the end? (size should be even) */
+ if (q == e || consumed)
+ break;
+ errmsg = "truncated data";
+ startinpos = ((const char *)q) - starts;
+ endinpos = ((const char *)e) - starts;
+ outpos = p - PyUnicode_AS_UNICODE(unicode);
+ goto utf16Error;
+ /* The remaining input chars are ignored if the callback
+ chooses to skip the input */
+ }
/* First check for possible aligned read of a C 'long'. Unaligned
reads are more expensive, better to defer to another iteration. */
if (!((size_t) q & LONG_PTR_MASK)) {
@@ -3546,7 +3558,7 @@
}
p = _p;
q = _q;
- if (q >= e)
+ if (e - q < 2)
break;
}
ch = (q[ihi] << 8) | q[ilo];
@@ -3559,10 +3571,10 @@
}
/* UTF-16 code pair: */
- if (q > e) {
+ if (e - q < 2) {
errmsg = "unexpected end of data";
startinpos = (((const char *)q) - 2) - starts;
- endinpos = ((const char *)e) + 1 - starts;
+ endinpos = ((const char *)e) - starts;
goto utf16Error;
}
if (0xD800 <= ch && ch <= 0xDBFF) {
@@ -3606,31 +3618,9 @@
&outpos,
&p))
goto onError;
- }
- /* remaining byte at the end? (size should be even) */
- if (e == q) {
- if (!consumed) {
- errmsg = "truncated data";
- startinpos = ((const char *)q) - starts;
- endinpos = ((const char *)e) + 1 - starts;
- outpos = p - PyUnicode_AS_UNICODE(unicode);
- if (unicode_decode_call_errorhandler(
- errors,
- &errorHandler,
- "utf16", errmsg,
- &starts,
- (const char **)&e,
- &startinpos,
- &endinpos,
- &exc,
- (const char **)&q,
- &unicode,
- &outpos,
- &p))
- goto onError;
- /* The remaining input chars are ignored if the callback
- chooses to skip the input */
- }
+ /* Update data because unicode_decode_call_errorhandler might have
+ changed the input object. */
+ aligned_end = (const unsigned char *) ((size_t) e & ~LONG_PTR_MASK);
}
if (byteorder)
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com