Line data Source code
1 : /* ------------------------------------------------------------------------
2 :
3 : Python Codec Registry and support functions
4 :
5 : Written by Marc-Andre Lemburg (mal@lemburg.com).
6 :
7 : Copyright (c) Corporation for National Research Initiatives.
8 :
9 : ------------------------------------------------------------------------ */
10 :
11 : #include "Python.h"
12 : #include <ctype.h>
13 :
14 : const char *Py_hexdigits = "0123456789abcdef";
15 :
16 : /* --- Codec Registry ----------------------------------------------------- */
17 :
18 : /* Import the standard encodings package which will register the first
19 : codec search function.
20 :
21 : This is done in a lazy way so that the Unicode implementation does
22 : not downgrade startup time of scripts not needing it.
23 :
24 : ImportErrors are silently ignored by this function. Only one try is
25 : made.
26 :
27 : */
28 :
29 : static int _PyCodecRegistry_Init(void); /* Forward */
30 :
31 1 : int PyCodec_Register(PyObject *search_function)
32 : {
33 1 : PyInterpreterState *interp = PyThreadState_GET()->interp;
34 1 : if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
35 0 : goto onError;
36 1 : if (search_function == NULL) {
37 0 : PyErr_BadArgument();
38 0 : goto onError;
39 : }
40 1 : if (!PyCallable_Check(search_function)) {
41 0 : PyErr_SetString(PyExc_TypeError, "argument must be callable");
42 0 : goto onError;
43 : }
44 1 : return PyList_Append(interp->codec_search_path, search_function);
45 :
46 : onError:
47 0 : return -1;
48 : }
49 :
50 : /* Convert a string to a normalized Python string: all characters are
51 : converted to lower case, spaces are replaced with underscores. */
52 :
53 : static
54 8 : PyObject *normalizestring(const char *string)
55 : {
56 : register size_t i;
57 8 : size_t len = strlen(string);
58 : char *p;
59 : PyObject *v;
60 :
61 8 : if (len > PY_SSIZE_T_MAX) {
62 0 : PyErr_SetString(PyExc_OverflowError, "string is too large");
63 0 : return NULL;
64 : }
65 :
66 8 : p = PyMem_Malloc(len + 1);
67 8 : if (p == NULL)
68 0 : return NULL;
69 48 : for (i = 0; i < len; i++) {
70 40 : register char ch = string[i];
71 40 : if (ch == ' ')
72 0 : ch = '-';
73 : else
74 40 : ch = Py_TOLOWER(Py_CHARMASK(ch));
75 40 : p[i] = ch;
76 : }
77 8 : p[i] = '\0';
78 8 : v = PyUnicode_FromString(p);
79 8 : if (v == NULL)
80 0 : return NULL;
81 8 : PyMem_Free(p);
82 8 : return v;
83 : }
84 :
85 : /* Lookup the given encoding and return a tuple providing the codec
86 : facilities.
87 :
88 : The encoding string is looked up converted to all lower-case
89 : characters. This makes encodings looked up through this mechanism
90 : effectively case-insensitive.
91 :
92 : If no codec is found, a LookupError is set and NULL returned.
93 :
94 : As side effect, this tries to load the encodings package, if not
95 : yet done. This is part of the lazy load strategy for the encodings
96 : package.
97 :
98 : */
99 :
100 8 : PyObject *_PyCodec_Lookup(const char *encoding)
101 : {
102 : PyInterpreterState *interp;
103 8 : PyObject *result, *args = NULL, *v;
104 : Py_ssize_t i, len;
105 :
106 8 : if (encoding == NULL) {
107 0 : PyErr_BadArgument();
108 0 : goto onError;
109 : }
110 :
111 8 : interp = PyThreadState_GET()->interp;
112 8 : if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
113 0 : goto onError;
114 :
115 : /* Convert the encoding to a normalized Python string: all
116 : characters are converted to lower case, spaces and hyphens are
117 : replaced with underscores. */
118 8 : v = normalizestring(encoding);
119 8 : if (v == NULL)
120 0 : goto onError;
121 8 : PyUnicode_InternInPlace(&v);
122 :
123 : /* First, try to lookup the name in the registry dictionary */
124 8 : result = PyDict_GetItem(interp->codec_search_cache, v);
125 8 : if (result != NULL) {
126 7 : Py_INCREF(result);
127 7 : Py_DECREF(v);
128 7 : return result;
129 : }
130 :
131 : /* Next, scan the search functions in order of registration */
132 1 : args = PyTuple_New(1);
133 1 : if (args == NULL)
134 0 : goto onError;
135 1 : PyTuple_SET_ITEM(args,0,v);
136 :
137 1 : len = PyList_Size(interp->codec_search_path);
138 1 : if (len < 0)
139 0 : goto onError;
140 1 : if (len == 0) {
141 0 : PyErr_SetString(PyExc_LookupError,
142 : "no codec search functions registered: "
143 : "can't find encoding");
144 0 : goto onError;
145 : }
146 :
147 2 : for (i = 0; i < len; i++) {
148 : PyObject *func;
149 :
150 1 : func = PyList_GetItem(interp->codec_search_path, i);
151 1 : if (func == NULL)
152 0 : goto onError;
153 1 : result = PyEval_CallObject(func, args);
154 1 : if (result == NULL)
155 0 : goto onError;
156 1 : if (result == Py_None) {
157 0 : Py_DECREF(result);
158 0 : continue;
159 : }
160 1 : if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) {
161 0 : PyErr_SetString(PyExc_TypeError,
162 : "codec search functions must return 4-tuples");
163 0 : Py_DECREF(result);
164 0 : goto onError;
165 : }
166 1 : break;
167 : }
168 1 : if (i == len) {
169 : /* XXX Perhaps we should cache misses too ? */
170 0 : PyErr_Format(PyExc_LookupError,
171 : "unknown encoding: %s", encoding);
172 0 : goto onError;
173 : }
174 :
175 : /* Cache and return the result */
176 1 : if (PyDict_SetItem(interp->codec_search_cache, v, result) < 0) {
177 0 : Py_DECREF(result);
178 0 : goto onError;
179 : }
180 1 : Py_DECREF(args);
181 1 : return result;
182 :
183 : onError:
184 0 : Py_XDECREF(args);
185 0 : return NULL;
186 : }
187 :
188 : /* Codec registry encoding check API. */
189 :
190 0 : int PyCodec_KnownEncoding(const char *encoding)
191 : {
192 : PyObject *codecs;
193 :
194 0 : codecs = _PyCodec_Lookup(encoding);
195 0 : if (!codecs) {
196 0 : PyErr_Clear();
197 0 : return 0;
198 : }
199 : else {
200 0 : Py_DECREF(codecs);
201 0 : return 1;
202 : }
203 : }
204 :
205 : static
206 0 : PyObject *args_tuple(PyObject *object,
207 : const char *errors)
208 : {
209 : PyObject *args;
210 :
211 0 : args = PyTuple_New(1 + (errors != NULL));
212 0 : if (args == NULL)
213 0 : return NULL;
214 0 : Py_INCREF(object);
215 0 : PyTuple_SET_ITEM(args,0,object);
216 0 : if (errors) {
217 : PyObject *v;
218 :
219 0 : v = PyUnicode_FromString(errors);
220 0 : if (v == NULL) {
221 0 : Py_DECREF(args);
222 0 : return NULL;
223 : }
224 0 : PyTuple_SET_ITEM(args, 1, v);
225 : }
226 0 : return args;
227 : }
228 :
229 : /* Helper function to get a codec item */
230 :
231 : static
232 0 : PyObject *codec_getitem(const char *encoding, int index)
233 : {
234 : PyObject *codecs;
235 : PyObject *v;
236 :
237 0 : codecs = _PyCodec_Lookup(encoding);
238 0 : if (codecs == NULL)
239 0 : return NULL;
240 0 : v = PyTuple_GET_ITEM(codecs, index);
241 0 : Py_DECREF(codecs);
242 0 : Py_INCREF(v);
243 0 : return v;
244 : }
245 :
246 : /* Helper function to create an incremental codec. */
247 :
248 : static
249 4 : PyObject *codec_getincrementalcodec(const char *encoding,
250 : const char *errors,
251 : const char *attrname)
252 : {
253 : PyObject *codecs, *ret, *inccodec;
254 :
255 4 : codecs = _PyCodec_Lookup(encoding);
256 4 : if (codecs == NULL)
257 0 : return NULL;
258 4 : inccodec = PyObject_GetAttrString(codecs, attrname);
259 4 : Py_DECREF(codecs);
260 4 : if (inccodec == NULL)
261 0 : return NULL;
262 4 : if (errors)
263 4 : ret = PyObject_CallFunction(inccodec, "s", errors);
264 : else
265 0 : ret = PyObject_CallFunction(inccodec, NULL);
266 4 : Py_DECREF(inccodec);
267 4 : return ret;
268 : }
269 :
270 : /* Helper function to create a stream codec. */
271 :
272 : static
273 0 : PyObject *codec_getstreamcodec(const char *encoding,
274 : PyObject *stream,
275 : const char *errors,
276 : const int index)
277 : {
278 : PyObject *codecs, *streamcodec, *codeccls;
279 :
280 0 : codecs = _PyCodec_Lookup(encoding);
281 0 : if (codecs == NULL)
282 0 : return NULL;
283 :
284 0 : codeccls = PyTuple_GET_ITEM(codecs, index);
285 0 : if (errors != NULL)
286 0 : streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors);
287 : else
288 0 : streamcodec = PyObject_CallFunction(codeccls, "O", stream);
289 0 : Py_DECREF(codecs);
290 0 : return streamcodec;
291 : }
292 :
293 : /* Convenience APIs to query the Codec registry.
294 :
295 : All APIs return a codec object with incremented refcount.
296 :
297 : */
298 :
299 0 : PyObject *PyCodec_Encoder(const char *encoding)
300 : {
301 0 : return codec_getitem(encoding, 0);
302 : }
303 :
304 0 : PyObject *PyCodec_Decoder(const char *encoding)
305 : {
306 0 : return codec_getitem(encoding, 1);
307 : }
308 :
309 2 : PyObject *PyCodec_IncrementalEncoder(const char *encoding,
310 : const char *errors)
311 : {
312 2 : return codec_getincrementalcodec(encoding, errors, "incrementalencoder");
313 : }
314 :
315 2 : PyObject *PyCodec_IncrementalDecoder(const char *encoding,
316 : const char *errors)
317 : {
318 2 : return codec_getincrementalcodec(encoding, errors, "incrementaldecoder");
319 : }
320 :
321 0 : PyObject *PyCodec_StreamReader(const char *encoding,
322 : PyObject *stream,
323 : const char *errors)
324 : {
325 0 : return codec_getstreamcodec(encoding, stream, errors, 2);
326 : }
327 :
328 0 : PyObject *PyCodec_StreamWriter(const char *encoding,
329 : PyObject *stream,
330 : const char *errors)
331 : {
332 0 : return codec_getstreamcodec(encoding, stream, errors, 3);
333 : }
334 :
335 : /* Encode an object (e.g. an Unicode object) using the given encoding
336 : and return the resulting encoded object (usually a Python string).
337 :
338 : errors is passed to the encoder factory as argument if non-NULL. */
339 :
340 0 : PyObject *PyCodec_Encode(PyObject *object,
341 : const char *encoding,
342 : const char *errors)
343 : {
344 0 : PyObject *encoder = NULL;
345 0 : PyObject *args = NULL, *result = NULL;
346 0 : PyObject *v = NULL;
347 :
348 0 : encoder = PyCodec_Encoder(encoding);
349 0 : if (encoder == NULL)
350 0 : goto onError;
351 :
352 0 : args = args_tuple(object, errors);
353 0 : if (args == NULL)
354 0 : goto onError;
355 :
356 0 : result = PyEval_CallObject(encoder, args);
357 0 : if (result == NULL)
358 0 : goto onError;
359 :
360 0 : if (!PyTuple_Check(result) ||
361 0 : PyTuple_GET_SIZE(result) != 2) {
362 0 : PyErr_SetString(PyExc_TypeError,
363 : "encoder must return a tuple (object, integer)");
364 0 : goto onError;
365 : }
366 0 : v = PyTuple_GET_ITEM(result,0);
367 0 : Py_INCREF(v);
368 : /* We don't check or use the second (integer) entry. */
369 :
370 0 : Py_DECREF(args);
371 0 : Py_DECREF(encoder);
372 0 : Py_DECREF(result);
373 0 : return v;
374 :
375 : onError:
376 0 : Py_XDECREF(result);
377 0 : Py_XDECREF(args);
378 0 : Py_XDECREF(encoder);
379 0 : return NULL;
380 : }
381 :
382 : /* Decode an object (usually a Python string) using the given encoding
383 : and return an equivalent object (e.g. an Unicode object).
384 :
385 : errors is passed to the decoder factory as argument if non-NULL. */
386 :
387 0 : PyObject *PyCodec_Decode(PyObject *object,
388 : const char *encoding,
389 : const char *errors)
390 : {
391 0 : PyObject *decoder = NULL;
392 0 : PyObject *args = NULL, *result = NULL;
393 : PyObject *v;
394 :
395 0 : decoder = PyCodec_Decoder(encoding);
396 0 : if (decoder == NULL)
397 0 : goto onError;
398 :
399 0 : args = args_tuple(object, errors);
400 0 : if (args == NULL)
401 0 : goto onError;
402 :
403 0 : result = PyEval_CallObject(decoder,args);
404 0 : if (result == NULL)
405 0 : goto onError;
406 0 : if (!PyTuple_Check(result) ||
407 0 : PyTuple_GET_SIZE(result) != 2) {
408 0 : PyErr_SetString(PyExc_TypeError,
409 : "decoder must return a tuple (object,integer)");
410 0 : goto onError;
411 : }
412 0 : v = PyTuple_GET_ITEM(result,0);
413 0 : Py_INCREF(v);
414 : /* We don't check or use the second (integer) entry. */
415 :
416 0 : Py_DECREF(args);
417 0 : Py_DECREF(decoder);
418 0 : Py_DECREF(result);
419 0 : return v;
420 :
421 : onError:
422 0 : Py_XDECREF(args);
423 0 : Py_XDECREF(decoder);
424 0 : Py_XDECREF(result);
425 0 : return NULL;
426 : }
427 :
428 : /* Register the error handling callback function error under the name
429 : name. This function will be called by the codec when it encounters
430 : an unencodable characters/undecodable bytes and doesn't know the
431 : callback name, when name is specified as the error parameter
432 : in the call to the encode/decode function.
433 : Return 0 on success, -1 on error */
434 7 : int PyCodec_RegisterError(const char *name, PyObject *error)
435 : {
436 7 : PyInterpreterState *interp = PyThreadState_GET()->interp;
437 7 : if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
438 0 : return -1;
439 7 : if (!PyCallable_Check(error)) {
440 0 : PyErr_SetString(PyExc_TypeError, "handler must be callable");
441 0 : return -1;
442 : }
443 7 : return PyDict_SetItemString(interp->codec_error_registry,
444 : (char *)name, error);
445 : }
446 :
447 : /* Lookup the error handling callback function registered under the
448 : name error. As a special case NULL can be passed, in which case
449 : the error handling callback for strict encoding will be returned. */
450 5 : PyObject *PyCodec_LookupError(const char *name)
451 : {
452 5 : PyObject *handler = NULL;
453 :
454 5 : PyInterpreterState *interp = PyThreadState_GET()->interp;
455 5 : if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
456 0 : return NULL;
457 :
458 5 : if (name==NULL)
459 0 : name = "strict";
460 5 : handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name);
461 5 : if (!handler)
462 0 : PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name);
463 : else
464 5 : Py_INCREF(handler);
465 5 : return handler;
466 : }
467 :
468 0 : static void wrong_exception_type(PyObject *exc)
469 : {
470 : _Py_IDENTIFIER(__class__);
471 : _Py_IDENTIFIER(__name__);
472 0 : PyObject *type = _PyObject_GetAttrId(exc, &PyId___class__);
473 0 : if (type != NULL) {
474 0 : PyObject *name = _PyObject_GetAttrId(type, &PyId___name__);
475 0 : Py_DECREF(type);
476 0 : if (name != NULL) {
477 0 : PyErr_Format(PyExc_TypeError,
478 : "don't know how to handle %S in error callback", name);
479 0 : Py_DECREF(name);
480 : }
481 : }
482 0 : }
483 :
484 0 : PyObject *PyCodec_StrictErrors(PyObject *exc)
485 : {
486 0 : if (PyExceptionInstance_Check(exc))
487 0 : PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
488 : else
489 0 : PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
490 0 : return NULL;
491 : }
492 :
493 :
494 0 : PyObject *PyCodec_IgnoreErrors(PyObject *exc)
495 : {
496 : Py_ssize_t end;
497 0 : if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
498 0 : if (PyUnicodeEncodeError_GetEnd(exc, &end))
499 0 : return NULL;
500 : }
501 0 : else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
502 0 : if (PyUnicodeDecodeError_GetEnd(exc, &end))
503 0 : return NULL;
504 : }
505 0 : else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) {
506 0 : if (PyUnicodeTranslateError_GetEnd(exc, &end))
507 0 : return NULL;
508 : }
509 : else {
510 0 : wrong_exception_type(exc);
511 0 : return NULL;
512 : }
513 0 : return Py_BuildValue("(Nn)", PyUnicode_New(0, 0), end);
514 : }
515 :
516 :
517 0 : PyObject *PyCodec_ReplaceErrors(PyObject *exc)
518 : {
519 : Py_ssize_t start, end, i, len;
520 :
521 0 : if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
522 : PyObject *res;
523 : int kind;
524 : void *data;
525 0 : if (PyUnicodeEncodeError_GetStart(exc, &start))
526 0 : return NULL;
527 0 : if (PyUnicodeEncodeError_GetEnd(exc, &end))
528 0 : return NULL;
529 0 : len = end - start;
530 0 : res = PyUnicode_New(len, '?');
531 0 : if (res == NULL)
532 0 : return NULL;
533 0 : kind = PyUnicode_KIND(res);
534 0 : data = PyUnicode_DATA(res);
535 0 : for (i = 0; i < len; ++i)
536 0 : PyUnicode_WRITE(kind, data, i, '?');
537 : assert(_PyUnicode_CheckConsistency(res, 1));
538 0 : return Py_BuildValue("(Nn)", res, end);
539 : }
540 0 : else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
541 0 : if (PyUnicodeDecodeError_GetEnd(exc, &end))
542 0 : return NULL;
543 0 : return Py_BuildValue("(Cn)",
544 : (int)Py_UNICODE_REPLACEMENT_CHARACTER,
545 : end);
546 : }
547 0 : else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) {
548 : PyObject *res;
549 : int kind;
550 : void *data;
551 0 : if (PyUnicodeTranslateError_GetStart(exc, &start))
552 0 : return NULL;
553 0 : if (PyUnicodeTranslateError_GetEnd(exc, &end))
554 0 : return NULL;
555 0 : len = end - start;
556 0 : res = PyUnicode_New(len, Py_UNICODE_REPLACEMENT_CHARACTER);
557 0 : if (res == NULL)
558 0 : return NULL;
559 0 : kind = PyUnicode_KIND(res);
560 0 : data = PyUnicode_DATA(res);
561 0 : for (i=0; i < len; i++)
562 0 : PyUnicode_WRITE(kind, data, i, Py_UNICODE_REPLACEMENT_CHARACTER);
563 : assert(_PyUnicode_CheckConsistency(res, 1));
564 0 : return Py_BuildValue("(Nn)", res, end);
565 : }
566 : else {
567 0 : wrong_exception_type(exc);
568 0 : return NULL;
569 : }
570 : }
571 :
572 0 : PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
573 : {
574 0 : if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
575 : PyObject *restuple;
576 : PyObject *object;
577 : Py_ssize_t i;
578 : Py_ssize_t start;
579 : Py_ssize_t end;
580 : PyObject *res;
581 : unsigned char *outp;
582 : int ressize;
583 : Py_UCS4 ch;
584 0 : if (PyUnicodeEncodeError_GetStart(exc, &start))
585 0 : return NULL;
586 0 : if (PyUnicodeEncodeError_GetEnd(exc, &end))
587 0 : return NULL;
588 0 : if (!(object = PyUnicodeEncodeError_GetObject(exc)))
589 0 : return NULL;
590 0 : for (i = start, ressize = 0; i < end; ++i) {
591 : /* object is guaranteed to be "ready" */
592 0 : ch = PyUnicode_READ_CHAR(object, i);
593 0 : if (ch<10)
594 0 : ressize += 2+1+1;
595 0 : else if (ch<100)
596 0 : ressize += 2+2+1;
597 0 : else if (ch<1000)
598 0 : ressize += 2+3+1;
599 0 : else if (ch<10000)
600 0 : ressize += 2+4+1;
601 0 : else if (ch<100000)
602 0 : ressize += 2+5+1;
603 0 : else if (ch<1000000)
604 0 : ressize += 2+6+1;
605 : else
606 0 : ressize += 2+7+1;
607 : }
608 : /* allocate replacement */
609 0 : res = PyUnicode_New(ressize, 127);
610 0 : if (res == NULL) {
611 0 : Py_DECREF(object);
612 0 : return NULL;
613 : }
614 0 : outp = PyUnicode_1BYTE_DATA(res);
615 : /* generate replacement */
616 0 : for (i = start; i < end; ++i) {
617 : int digits;
618 : int base;
619 0 : ch = PyUnicode_READ_CHAR(object, i);
620 0 : *outp++ = '&';
621 0 : *outp++ = '#';
622 0 : if (ch<10) {
623 0 : digits = 1;
624 0 : base = 1;
625 : }
626 0 : else if (ch<100) {
627 0 : digits = 2;
628 0 : base = 10;
629 : }
630 0 : else if (ch<1000) {
631 0 : digits = 3;
632 0 : base = 100;
633 : }
634 0 : else if (ch<10000) {
635 0 : digits = 4;
636 0 : base = 1000;
637 : }
638 0 : else if (ch<100000) {
639 0 : digits = 5;
640 0 : base = 10000;
641 : }
642 0 : else if (ch<1000000) {
643 0 : digits = 6;
644 0 : base = 100000;
645 : }
646 : else {
647 0 : digits = 7;
648 0 : base = 1000000;
649 : }
650 0 : while (digits-->0) {
651 0 : *outp++ = '0' + ch/base;
652 0 : ch %= base;
653 0 : base /= 10;
654 : }
655 0 : *outp++ = ';';
656 : }
657 : assert(_PyUnicode_CheckConsistency(res, 1));
658 0 : restuple = Py_BuildValue("(Nn)", res, end);
659 0 : Py_DECREF(object);
660 0 : return restuple;
661 : }
662 : else {
663 0 : wrong_exception_type(exc);
664 0 : return NULL;
665 : }
666 : }
667 :
668 0 : PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
669 : {
670 0 : if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
671 : PyObject *restuple;
672 : PyObject *object;
673 : Py_ssize_t i;
674 : Py_ssize_t start;
675 : Py_ssize_t end;
676 : PyObject *res;
677 : unsigned char *outp;
678 : int ressize;
679 : Py_UCS4 c;
680 0 : if (PyUnicodeEncodeError_GetStart(exc, &start))
681 0 : return NULL;
682 0 : if (PyUnicodeEncodeError_GetEnd(exc, &end))
683 0 : return NULL;
684 0 : if (!(object = PyUnicodeEncodeError_GetObject(exc)))
685 0 : return NULL;
686 0 : for (i = start, ressize = 0; i < end; ++i) {
687 : /* object is guaranteed to be "ready" */
688 0 : c = PyUnicode_READ_CHAR(object, i);
689 0 : if (c >= 0x10000) {
690 0 : ressize += 1+1+8;
691 : }
692 0 : else if (c >= 0x100) {
693 0 : ressize += 1+1+4;
694 : }
695 : else
696 0 : ressize += 1+1+2;
697 : }
698 0 : res = PyUnicode_New(ressize, 127);
699 0 : if (res==NULL)
700 0 : return NULL;
701 0 : for (i = start, outp = PyUnicode_1BYTE_DATA(res);
702 0 : i < end; ++i) {
703 0 : c = PyUnicode_READ_CHAR(object, i);
704 0 : *outp++ = '\\';
705 0 : if (c >= 0x00010000) {
706 0 : *outp++ = 'U';
707 0 : *outp++ = Py_hexdigits[(c>>28)&0xf];
708 0 : *outp++ = Py_hexdigits[(c>>24)&0xf];
709 0 : *outp++ = Py_hexdigits[(c>>20)&0xf];
710 0 : *outp++ = Py_hexdigits[(c>>16)&0xf];
711 0 : *outp++ = Py_hexdigits[(c>>12)&0xf];
712 0 : *outp++ = Py_hexdigits[(c>>8)&0xf];
713 : }
714 0 : else if (c >= 0x100) {
715 0 : *outp++ = 'u';
716 0 : *outp++ = Py_hexdigits[(c>>12)&0xf];
717 0 : *outp++ = Py_hexdigits[(c>>8)&0xf];
718 : }
719 : else
720 0 : *outp++ = 'x';
721 0 : *outp++ = Py_hexdigits[(c>>4)&0xf];
722 0 : *outp++ = Py_hexdigits[c&0xf];
723 : }
724 :
725 : assert(_PyUnicode_CheckConsistency(res, 1));
726 0 : restuple = Py_BuildValue("(Nn)", res, end);
727 0 : Py_DECREF(object);
728 0 : return restuple;
729 : }
730 : else {
731 0 : wrong_exception_type(exc);
732 0 : return NULL;
733 : }
734 : }
735 :
736 : /* This handler is declared static until someone demonstrates
737 : a need to call it directly. */
738 : static PyObject *
739 0 : PyCodec_SurrogatePassErrors(PyObject *exc)
740 : {
741 : PyObject *restuple;
742 : PyObject *object;
743 : Py_ssize_t i;
744 : Py_ssize_t start;
745 : Py_ssize_t end;
746 : PyObject *res;
747 0 : if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
748 : char *outp;
749 0 : if (PyUnicodeEncodeError_GetStart(exc, &start))
750 0 : return NULL;
751 0 : if (PyUnicodeEncodeError_GetEnd(exc, &end))
752 0 : return NULL;
753 0 : if (!(object = PyUnicodeEncodeError_GetObject(exc)))
754 0 : return NULL;
755 0 : res = PyBytes_FromStringAndSize(NULL, 3*(end-start));
756 0 : if (!res) {
757 0 : Py_DECREF(object);
758 0 : return NULL;
759 : }
760 0 : outp = PyBytes_AsString(res);
761 0 : for (i = start; i < end; i++) {
762 : /* object is guaranteed to be "ready" */
763 0 : Py_UCS4 ch = PyUnicode_READ_CHAR(object, i);
764 0 : if (ch < 0xd800 || ch > 0xdfff) {
765 : /* Not a surrogate, fail with original exception */
766 0 : PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
767 0 : Py_DECREF(res);
768 0 : Py_DECREF(object);
769 0 : return NULL;
770 : }
771 0 : *outp++ = (char)(0xe0 | (ch >> 12));
772 0 : *outp++ = (char)(0x80 | ((ch >> 6) & 0x3f));
773 0 : *outp++ = (char)(0x80 | (ch & 0x3f));
774 : }
775 0 : restuple = Py_BuildValue("(On)", res, end);
776 0 : Py_DECREF(res);
777 0 : Py_DECREF(object);
778 0 : return restuple;
779 : }
780 0 : else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
781 : unsigned char *p;
782 0 : Py_UCS4 ch = 0;
783 0 : if (PyUnicodeDecodeError_GetStart(exc, &start))
784 0 : return NULL;
785 0 : if (!(object = PyUnicodeDecodeError_GetObject(exc)))
786 0 : return NULL;
787 0 : if (!(p = (unsigned char*)PyBytes_AsString(object))) {
788 0 : Py_DECREF(object);
789 0 : return NULL;
790 : }
791 : /* Try decoding a single surrogate character. If
792 : there are more, let the codec call us again. */
793 0 : p += start;
794 0 : if ((p[0] & 0xf0) == 0xe0 ||
795 0 : (p[1] & 0xc0) == 0x80 ||
796 0 : (p[2] & 0xc0) == 0x80) {
797 : /* it's a three-byte code */
798 0 : ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f);
799 0 : if (ch < 0xd800 || ch > 0xdfff)
800 : /* it's not a surrogate - fail */
801 0 : ch = 0;
802 : }
803 0 : Py_DECREF(object);
804 0 : if (ch == 0) {
805 0 : PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
806 0 : return NULL;
807 : }
808 0 : res = PyUnicode_FromOrdinal(ch);
809 0 : if (res == NULL)
810 0 : return NULL;
811 0 : return Py_BuildValue("(Nn)", res, start+3);
812 : }
813 : else {
814 0 : wrong_exception_type(exc);
815 0 : return NULL;
816 : }
817 : }
818 :
819 : static PyObject *
820 0 : PyCodec_SurrogateEscapeErrors(PyObject *exc)
821 : {
822 : PyObject *restuple;
823 : PyObject *object;
824 : Py_ssize_t i;
825 : Py_ssize_t start;
826 : Py_ssize_t end;
827 : PyObject *res;
828 0 : if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
829 : char *outp;
830 0 : if (PyUnicodeEncodeError_GetStart(exc, &start))
831 0 : return NULL;
832 0 : if (PyUnicodeEncodeError_GetEnd(exc, &end))
833 0 : return NULL;
834 0 : if (!(object = PyUnicodeEncodeError_GetObject(exc)))
835 0 : return NULL;
836 0 : res = PyBytes_FromStringAndSize(NULL, end-start);
837 0 : if (!res) {
838 0 : Py_DECREF(object);
839 0 : return NULL;
840 : }
841 0 : outp = PyBytes_AsString(res);
842 0 : for (i = start; i < end; i++) {
843 : /* object is guaranteed to be "ready" */
844 0 : Py_UCS4 ch = PyUnicode_READ_CHAR(object, i);
845 0 : if (ch < 0xdc80 || ch > 0xdcff) {
846 : /* Not a UTF-8b surrogate, fail with original exception */
847 0 : PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
848 0 : Py_DECREF(res);
849 0 : Py_DECREF(object);
850 0 : return NULL;
851 : }
852 0 : *outp++ = ch - 0xdc00;
853 : }
854 0 : restuple = Py_BuildValue("(On)", res, end);
855 0 : Py_DECREF(res);
856 0 : Py_DECREF(object);
857 0 : return restuple;
858 : }
859 0 : else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
860 : PyObject *str;
861 : unsigned char *p;
862 : Py_UCS2 ch[4]; /* decode up to 4 bad bytes. */
863 0 : int consumed = 0;
864 0 : if (PyUnicodeDecodeError_GetStart(exc, &start))
865 0 : return NULL;
866 0 : if (PyUnicodeDecodeError_GetEnd(exc, &end))
867 0 : return NULL;
868 0 : if (!(object = PyUnicodeDecodeError_GetObject(exc)))
869 0 : return NULL;
870 0 : if (!(p = (unsigned char*)PyBytes_AsString(object))) {
871 0 : Py_DECREF(object);
872 0 : return NULL;
873 : }
874 0 : while (consumed < 4 && consumed < end-start) {
875 : /* Refuse to escape ASCII bytes. */
876 0 : if (p[start+consumed] < 128)
877 0 : break;
878 0 : ch[consumed] = 0xdc00 + p[start+consumed];
879 0 : consumed++;
880 : }
881 0 : Py_DECREF(object);
882 0 : if (!consumed) {
883 : /* codec complained about ASCII byte. */
884 0 : PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
885 0 : return NULL;
886 : }
887 0 : str = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, ch, consumed);
888 0 : if (str == NULL)
889 0 : return NULL;
890 0 : return Py_BuildValue("(Nn)", str, start+consumed);
891 : }
892 : else {
893 0 : wrong_exception_type(exc);
894 0 : return NULL;
895 : }
896 : }
897 :
898 :
899 0 : static PyObject *strict_errors(PyObject *self, PyObject *exc)
900 : {
901 0 : return PyCodec_StrictErrors(exc);
902 : }
903 :
904 :
905 0 : static PyObject *ignore_errors(PyObject *self, PyObject *exc)
906 : {
907 0 : return PyCodec_IgnoreErrors(exc);
908 : }
909 :
910 :
911 0 : static PyObject *replace_errors(PyObject *self, PyObject *exc)
912 : {
913 0 : return PyCodec_ReplaceErrors(exc);
914 : }
915 :
916 :
917 0 : static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc)
918 : {
919 0 : return PyCodec_XMLCharRefReplaceErrors(exc);
920 : }
921 :
922 :
923 0 : static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc)
924 : {
925 0 : return PyCodec_BackslashReplaceErrors(exc);
926 : }
927 :
928 0 : static PyObject *surrogatepass_errors(PyObject *self, PyObject *exc)
929 : {
930 0 : return PyCodec_SurrogatePassErrors(exc);
931 : }
932 :
933 0 : static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc)
934 : {
935 0 : return PyCodec_SurrogateEscapeErrors(exc);
936 : }
937 :
938 1 : static int _PyCodecRegistry_Init(void)
939 : {
940 : static struct {
941 : char *name;
942 : PyMethodDef def;
943 : } methods[] =
944 : {
945 : {
946 : "strict",
947 : {
948 : "strict_errors",
949 : strict_errors,
950 : METH_O,
951 : PyDoc_STR("Implements the 'strict' error handling, which "
952 : "raises a UnicodeError on coding errors.")
953 : }
954 : },
955 : {
956 : "ignore",
957 : {
958 : "ignore_errors",
959 : ignore_errors,
960 : METH_O,
961 : PyDoc_STR("Implements the 'ignore' error handling, which "
962 : "ignores malformed data and continues.")
963 : }
964 : },
965 : {
966 : "replace",
967 : {
968 : "replace_errors",
969 : replace_errors,
970 : METH_O,
971 : PyDoc_STR("Implements the 'replace' error handling, which "
972 : "replaces malformed data with a replacement marker.")
973 : }
974 : },
975 : {
976 : "xmlcharrefreplace",
977 : {
978 : "xmlcharrefreplace_errors",
979 : xmlcharrefreplace_errors,
980 : METH_O,
981 : PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, "
982 : "which replaces an unencodable character with the "
983 : "appropriate XML character reference.")
984 : }
985 : },
986 : {
987 : "backslashreplace",
988 : {
989 : "backslashreplace_errors",
990 : backslashreplace_errors,
991 : METH_O,
992 : PyDoc_STR("Implements the 'backslashreplace' error handling, "
993 : "which replaces an unencodable character with a "
994 : "backslashed escape sequence.")
995 : }
996 : },
997 : {
998 : "surrogatepass",
999 : {
1000 : "surrogatepass",
1001 : surrogatepass_errors,
1002 : METH_O
1003 : }
1004 : },
1005 : {
1006 : "surrogateescape",
1007 : {
1008 : "surrogateescape",
1009 : surrogateescape_errors,
1010 : METH_O
1011 : }
1012 : }
1013 : };
1014 :
1015 1 : PyInterpreterState *interp = PyThreadState_GET()->interp;
1016 : PyObject *mod;
1017 : unsigned i;
1018 :
1019 1 : if (interp->codec_search_path != NULL)
1020 0 : return 0;
1021 :
1022 1 : interp->codec_search_path = PyList_New(0);
1023 1 : interp->codec_search_cache = PyDict_New();
1024 1 : interp->codec_error_registry = PyDict_New();
1025 :
1026 1 : if (interp->codec_error_registry) {
1027 8 : for (i = 0; i < Py_ARRAY_LENGTH(methods); ++i) {
1028 7 : PyObject *func = PyCFunction_New(&methods[i].def, NULL);
1029 : int res;
1030 7 : if (!func)
1031 0 : Py_FatalError("can't initialize codec error registry");
1032 7 : res = PyCodec_RegisterError(methods[i].name, func);
1033 7 : Py_DECREF(func);
1034 7 : if (res)
1035 0 : Py_FatalError("can't initialize codec error registry");
1036 : }
1037 : }
1038 :
1039 2 : if (interp->codec_search_path == NULL ||
1040 2 : interp->codec_search_cache == NULL ||
1041 1 : interp->codec_error_registry == NULL)
1042 0 : Py_FatalError("can't initialize codec registry");
1043 :
1044 1 : mod = PyImport_ImportModuleNoBlock("encodings");
1045 1 : if (mod == NULL) {
1046 0 : return -1;
1047 : }
1048 1 : Py_DECREF(mod);
1049 1 : interp->codecs_initialized = 1;
1050 1 : return 0;
1051 : }
|