]> granicus.if.org Git - python/commitdiff
Allow long objects as a position value of error callbacks returned.
authorHye-Shik Chang <hyeshik@gmail.com>
Sun, 26 Mar 2006 06:21:34 +0000 (06:21 +0000)
committerHye-Shik Chang <hyeshik@gmail.com>
Sun, 26 Mar 2006 06:21:34 +0000 (06:21 +0000)
Lib/test/test_multibytecodec.py
Lib/test/test_multibytecodec_support.py
Modules/cjkcodecs/multibytecodec.c

index 8f9f6e970b4725426ea59812aac0018ac6f41c0a..4d02dee6973bfa4df68664aa323749451be8e49e 100644 (file)
@@ -7,7 +7,7 @@
 
 from test import test_support
 from test import test_multibytecodec_support
-import unittest, StringIO, codecs
+import unittest, StringIO, codecs, sys
 
 class Test_MultibyteCodec(unittest.TestCase):
 
@@ -19,6 +19,12 @@ class Test_MultibyteCodec(unittest.TestCase):
     def test_str_decode(self):
         self.assertEqual('abcd'.encode('gb18030'), 'abcd')
 
+    def test_errorcallback_longindex(self):
+        dec = codecs.getdecoder('euc-kr')
+        myreplace  = lambda exc: (u'', sys.maxint+1)
+        codecs.register_error('test.cjktest', myreplace)
+        self.assertRaises(IndexError, dec,
+                          'apple\x92ham\x93spam', 'test.cjktest')
 
 class Test_IncrementalEncoder(unittest.TestCase):
 
index 563a3ea7f7cfcef2bb611dd4958687122f72b892..bec32de1d5673e854601ba1ad30e24272265a6d0 100644 (file)
@@ -60,7 +60,7 @@ class TestBase:
             "&#2835;&#2851;&#2912; nd eggs"
         )
 
-    def test_customreplace(self):
+    def test_customreplace_encode(self):
         if self.has_iso10646:
             return
 
@@ -96,6 +96,19 @@ class TestBase:
             self.assertRaises(TypeError, self.encode, self.unmappedunicode,
                               'test.cjktest')
 
+    def test_callback_long_index(self):
+        def myreplace(exc):
+            return (u'x', long(exc.end))
+        codecs.register_error("test.cjktest", myreplace)
+        self.assertEqual(self.encode(u'abcd' + self.unmappedunicode + u'efgh',
+                                     'test.cjktest'), ('abcdxefgh', 9))
+
+        def myreplace(exc):
+            return (u'x', sys.maxint + 1)
+        codecs.register_error("test.cjktest", myreplace)
+        self.assertRaises(IndexError, self.encode, self.unmappedunicode,
+                          'test.cjktest')
+
     def test_callback_None_index(self):
         def myreplace(exc):
             return (u'x', None)
index 26d5c944c9d28e10b2cb836888a0e2e1b2c85018..c19da9c12754f245049bbb37ccd16df98b6f0441 100644 (file)
@@ -304,7 +304,8 @@ multibytecodec_encerror(MultibyteCodec *codec,
 
        if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
            !PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) ||
-           !PyInt_Check(PyTuple_GET_ITEM(retobj, 1))) {
+           !(PyInt_Check(PyTuple_GET_ITEM(retobj, 1)) ||
+             PyLong_Check(PyTuple_GET_ITEM(retobj, 1)))) {
                PyErr_SetString(PyExc_TypeError,
                                "encoding error handler must return "
                                "(unicode, int) tuple");
@@ -328,12 +329,13 @@ multibytecodec_encerror(MultibyteCodec *codec,
        buf->outbuf += retstrsize;
 
        newpos = PyInt_AsSsize_t(PyTuple_GET_ITEM(retobj, 1));
-       if (newpos < 0)
+       if (newpos < 0 && !PyErr_Occurred())
                newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top);
        if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) {
+               PyErr_Clear();
                PyErr_Format(PyExc_IndexError,
-                            "position %d from error handler out of bounds",
-                            (int)newpos);
+                            "position %ld from error handler out of bounds",
+                            (long)newpos);
                goto errorexit;
        }
        buf->inbuf = buf->inbuf_top + newpos;
@@ -421,7 +423,8 @@ multibytecodec_decerror(MultibyteCodec *codec,
 
        if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
            !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) ||
-           !PyInt_Check(PyTuple_GET_ITEM(retobj, 1))) {
+           !(PyInt_Check(PyTuple_GET_ITEM(retobj, 1)) ||
+             PyLong_Check(PyTuple_GET_ITEM(retobj, 1)))) {
                PyErr_SetString(PyExc_TypeError,
                                "decoding error handler must return "
                                "(unicode, int) tuple");
@@ -437,12 +440,13 @@ multibytecodec_decerror(MultibyteCodec *codec,
        }
 
        newpos = PyInt_AsSsize_t(PyTuple_GET_ITEM(retobj, 1));
-       if (newpos < 0)
+       if (newpos < 0 && !PyErr_Occurred())
                newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top);
        if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) {
+               PyErr_Clear();
                PyErr_Format(PyExc_IndexError,
-                               "position %d from error handler out of bounds",
-                               (int)newpos);
+                               "position %ld from error handler out of bounds",
+                               (long)newpos);
                goto errorexit;
        }
        buf->inbuf = buf->inbuf_top + newpos;