Mercurial > cpython-lru_cache-weakref
comparison Python/codecs.c @ 53681:52a77ef069cd
Issue #3672: Reject surrogates in utf-8 codec; add surrogates error
handler.
| author | Martin v. Löwis <martin@v.loewis.de> |
|---|---|
| date | Sat, 02 May 2009 18:52:14 +0000 |
| parents | efef5fc45a9a |
| children | 52a89d723b6b |
comparison
equal
deleted
inserted
replaced
| 53680:ec3fc64631d9 | 53681:52a77ef069cd |
|---|---|
| 746 wrong_exception_type(exc); | 746 wrong_exception_type(exc); |
| 747 return NULL; | 747 return NULL; |
| 748 } | 748 } |
| 749 } | 749 } |
| 750 | 750 |
| 751 PyObject *PyCodec_SurrogateErrors(PyObject *exc) | |
| 752 { | |
| 753 PyObject *restuple; | |
| 754 PyObject *object; | |
| 755 Py_ssize_t start; | |
| 756 Py_ssize_t end; | |
| 757 PyObject *res; | |
| 758 if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { | |
| 759 Py_UNICODE *p; | |
| 760 Py_UNICODE *startp; | |
| 761 char *outp; | |
| 762 if (PyUnicodeEncodeError_GetStart(exc, &start)) | |
| 763 return NULL; | |
| 764 if (PyUnicodeEncodeError_GetEnd(exc, &end)) | |
| 765 return NULL; | |
| 766 if (!(object = PyUnicodeEncodeError_GetObject(exc))) | |
| 767 return NULL; | |
| 768 startp = PyUnicode_AS_UNICODE(object); | |
| 769 res = PyBytes_FromStringAndSize(NULL, 3*(end-start)); | |
| 770 if (!res) { | |
| 771 Py_DECREF(object); | |
| 772 return NULL; | |
| 773 } | |
| 774 outp = PyBytes_AsString(res); | |
| 775 for (p = startp+start; p < startp+end; p++) { | |
| 776 Py_UNICODE ch = *p; | |
| 777 if (ch < 0xd800 || ch > 0xdfff) { | |
| 778 /* Not a surrogate, fail with original exception */ | |
| 779 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); | |
| 780 Py_DECREF(res); | |
| 781 Py_DECREF(object); | |
| 782 return NULL; | |
| 783 } | |
| 784 *outp++ = (char)(0xe0 | (ch >> 12)); | |
| 785 *outp++ = (char)(0x80 | ((ch >> 6) & 0x3f)); | |
| 786 *outp++ = (char)(0x80 | (ch & 0x3f)); | |
| 787 } | |
| 788 restuple = Py_BuildValue("(On)", res, end); | |
| 789 Py_DECREF(res); | |
| 790 Py_DECREF(object); | |
| 791 return restuple; | |
| 792 } | |
| 793 else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { | |
| 794 unsigned char *p; | |
| 795 Py_UNICODE ch = 0; | |
| 796 if (PyUnicodeDecodeError_GetStart(exc, &start)) | |
| 797 return NULL; | |
| 798 if (!(object = PyUnicodeDecodeError_GetObject(exc))) | |
| 799 return NULL; | |
| 800 if (!(p = (unsigned char*)PyBytes_AsString(object))) { | |
| 801 Py_DECREF(object); | |
| 802 return NULL; | |
| 803 } | |
| 804 /* Try decoding a single surrogate character. If | |
| 805 there are more, let the codec call us again. */ | |
| 806 p += start; | |
| 807 if ((p[0] & 0xf0) == 0xe0 || | |
| 808 (p[1] & 0xc0) == 0x80 || | |
| 809 (p[2] & 0xc0) == 0x80) { | |
| 810 /* it's a three-byte code */ | |
| 811 ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f); | |
| 812 if (ch < 0xd800 || ch > 0xdfff) | |
| 813 /* it's not a surrogate - fail */ | |
| 814 ch = 0; | |
| 815 } | |
| 816 Py_DECREF(object); | |
| 817 if (ch == 0) { | |
| 818 PyErr_SetObject(PyExceptionInstance_Class(exc), exc); | |
| 819 return NULL; | |
| 820 } | |
| 821 return Py_BuildValue("(u#n)", &ch, 1, start+3); | |
| 822 } | |
| 823 else { | |
| 824 wrong_exception_type(exc); | |
| 825 return NULL; | |
| 826 } | |
| 827 } | |
| 828 | |
| 829 | |
| 751 static PyObject *strict_errors(PyObject *self, PyObject *exc) | 830 static PyObject *strict_errors(PyObject *self, PyObject *exc) |
| 752 { | 831 { |
| 753 return PyCodec_StrictErrors(exc); | 832 return PyCodec_StrictErrors(exc); |
| 754 } | 833 } |
| 755 | 834 |
| 773 | 852 |
| 774 | 853 |
| 775 static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc) | 854 static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc) |
| 776 { | 855 { |
| 777 return PyCodec_BackslashReplaceErrors(exc); | 856 return PyCodec_BackslashReplaceErrors(exc); |
| 857 } | |
| 858 | |
| 859 static PyObject *surrogates_errors(PyObject *self, PyObject *exc) | |
| 860 { | |
| 861 return PyCodec_SurrogateErrors(exc); | |
| 778 } | 862 } |
| 779 | 863 |
| 780 static int _PyCodecRegistry_Init(void) | 864 static int _PyCodecRegistry_Init(void) |
| 781 { | 865 { |
| 782 static struct { | 866 static struct { |
| 821 { | 905 { |
| 822 "backslashreplace_errors", | 906 "backslashreplace_errors", |
| 823 backslashreplace_errors, | 907 backslashreplace_errors, |
| 824 METH_O | 908 METH_O |
| 825 } | 909 } |
| 910 }, | |
| 911 { | |
| 912 "surrogates", | |
| 913 { | |
| 914 "surrogates", | |
| 915 surrogates_errors, | |
| 916 METH_O | |
| 917 } | |
| 826 } | 918 } |
| 827 }; | 919 }; |
| 828 | 920 |
| 829 PyInterpreterState *interp = PyThreadState_GET()->interp; | 921 PyInterpreterState *interp = PyThreadState_GET()->interp; |
| 830 PyObject *mod; | 922 PyObject *mod; |
