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;