@@ -8208,8 +8208,12 @@ charmap_decode_mapping(const char *s,
8208
8208
if (key == NULL )
8209
8209
goto onError ;
8210
8210
8211
- item = PyObject_GetItem (mapping , key );
8211
+ int rc = PyMapping_GetOptionalItem (mapping , key , & item );
8212
8212
Py_DECREF (key );
8213
+ if (rc == 0 ) {
8214
+ /* No mapping found means: mapping is undefined. */
8215
+ goto Undefined ;
8216
+ }
8213
8217
if (item == NULL ) {
8214
8218
if (PyErr_ExceptionMatches (PyExc_LookupError )) {
8215
8219
/* No mapping found means: mapping is undefined. */
@@ -8223,7 +8227,7 @@ charmap_decode_mapping(const char *s,
8223
8227
if (item == Py_None )
8224
8228
goto Undefined ;
8225
8229
if (PyLong_Check (item )) {
8226
- long value = PyLong_AS_LONG (item );
8230
+ long value = PyLong_AsLong (item );
8227
8231
if (value == 0xFFFE )
8228
8232
goto Undefined ;
8229
8233
if (value < 0 || value > MAX_UNICODE ) {
@@ -8507,19 +8511,25 @@ encoding_map_lookup(Py_UCS4 c, PyObject *mapping)
8507
8511
return i ;
8508
8512
}
8509
8513
8510
- /* Lookup the character ch in the mapping. If the character
8511
- can't be found, Py_None is returned (or NULL, if another
8512
- error occurred). */
8514
+ /* Lookup the character in the mapping.
8515
+ On success, return PyLong, PyBytes or None (if the character can't be found).
8516
+ If the result is PyLong, put its value in replace.
8517
+ On error, return NULL.
8518
+ */
8513
8519
static PyObject *
8514
- charmapencode_lookup (Py_UCS4 c , PyObject * mapping )
8520
+ charmapencode_lookup (Py_UCS4 c , PyObject * mapping , unsigned char * replace )
8515
8521
{
8516
8522
PyObject * w = PyLong_FromLong ((long )c );
8517
8523
PyObject * x ;
8518
8524
8519
8525
if (w == NULL )
8520
8526
return NULL ;
8521
- x = PyObject_GetItem (mapping , w );
8527
+ int rc = PyMapping_GetOptionalItem (mapping , w , & x );
8522
8528
Py_DECREF (w );
8529
+ if (rc == 0 ) {
8530
+ /* No mapping found means: mapping is undefined. */
8531
+ Py_RETURN_NONE ;
8532
+ }
8523
8533
if (x == NULL ) {
8524
8534
if (PyErr_ExceptionMatches (PyExc_LookupError )) {
8525
8535
/* No mapping found means: mapping is undefined. */
@@ -8531,13 +8541,14 @@ charmapencode_lookup(Py_UCS4 c, PyObject *mapping)
8531
8541
else if (x == Py_None )
8532
8542
return x ;
8533
8543
else if (PyLong_Check (x )) {
8534
- long value = PyLong_AS_LONG (x );
8544
+ long value = PyLong_AsLong (x );
8535
8545
if (value < 0 || value > 255 ) {
8536
8546
PyErr_SetString (PyExc_TypeError ,
8537
8547
"character mapping must be in range(256)" );
8538
8548
Py_DECREF (x );
8539
8549
return NULL ;
8540
8550
}
8551
+ * replace = (unsigned char )value ;
8541
8552
return x ;
8542
8553
}
8543
8554
else if (PyBytes_Check (x ))
@@ -8578,6 +8589,7 @@ charmapencode_output(Py_UCS4 c, PyObject *mapping,
8578
8589
PyObject * * outobj , Py_ssize_t * outpos )
8579
8590
{
8580
8591
PyObject * rep ;
8592
+ unsigned char replace ;
8581
8593
char * outstart ;
8582
8594
Py_ssize_t outsize = PyBytes_GET_SIZE (* outobj );
8583
8595
@@ -8594,7 +8606,7 @@ charmapencode_output(Py_UCS4 c, PyObject *mapping,
8594
8606
return enc_SUCCESS ;
8595
8607
}
8596
8608
8597
- rep = charmapencode_lookup (c , mapping );
8609
+ rep = charmapencode_lookup (c , mapping , & replace );
8598
8610
if (rep == NULL )
8599
8611
return enc_EXCEPTION ;
8600
8612
else if (rep == Py_None ) {
@@ -8609,7 +8621,7 @@ charmapencode_output(Py_UCS4 c, PyObject *mapping,
8609
8621
return enc_EXCEPTION ;
8610
8622
}
8611
8623
outstart = PyBytes_AS_STRING (* outobj );
8612
- outstart [(* outpos )++ ] = (char )PyLong_AS_LONG ( rep ) ;
8624
+ outstart [(* outpos )++ ] = (char )replace ;
8613
8625
}
8614
8626
else {
8615
8627
const char * repchars = PyBytes_AS_STRING (rep );
@@ -8658,6 +8670,7 @@ charmap_encoding_error(
8658
8670
/* find all unencodable characters */
8659
8671
while (collendpos < size ) {
8660
8672
PyObject * rep ;
8673
+ unsigned char replace ;
8661
8674
if (Py_IS_TYPE (mapping , & EncodingMapType )) {
8662
8675
ch = PyUnicode_READ_CHAR (unicode , collendpos );
8663
8676
val = encoding_map_lookup (ch , mapping );
@@ -8668,7 +8681,7 @@ charmap_encoding_error(
8668
8681
}
8669
8682
8670
8683
ch = PyUnicode_READ_CHAR (unicode , collendpos );
8671
- rep = charmapencode_lookup (ch , mapping );
8684
+ rep = charmapencode_lookup (ch , mapping , & replace );
8672
8685
if (rep == NULL )
8673
8686
return -1 ;
8674
8687
else if (rep != Py_None ) {
@@ -8933,17 +8946,24 @@ unicode_translate_call_errorhandler(const char *errors,
8933
8946
8934
8947
/* Lookup the character ch in the mapping and put the result in result,
8935
8948
which must be decrefed by the caller.
8949
+ The result can be PyLong, PyUnicode, None or NULL.
8950
+ If the result is PyLong, put its value in replace.
8936
8951
Return 0 on success, -1 on error */
8937
8952
static int
8938
- charmaptranslate_lookup (Py_UCS4 c , PyObject * mapping , PyObject * * result )
8953
+ charmaptranslate_lookup (Py_UCS4 c , PyObject * mapping , PyObject * * result , Py_UCS4 * replace )
8939
8954
{
8940
8955
PyObject * w = PyLong_FromLong ((long )c );
8941
8956
PyObject * x ;
8942
8957
8943
8958
if (w == NULL )
8944
8959
return -1 ;
8945
- x = PyObject_GetItem (mapping , w );
8960
+ int rc = PyMapping_GetOptionalItem (mapping , w , & x );
8946
8961
Py_DECREF (w );
8962
+ if (rc == 0 ) {
8963
+ /* No mapping found means: use 1:1 mapping. */
8964
+ * result = NULL ;
8965
+ return 0 ;
8966
+ }
8947
8967
if (x == NULL ) {
8948
8968
if (PyErr_ExceptionMatches (PyExc_LookupError )) {
8949
8969
/* No mapping found means: use 1:1 mapping. */
@@ -8958,7 +8978,7 @@ charmaptranslate_lookup(Py_UCS4 c, PyObject *mapping, PyObject **result)
8958
8978
return 0 ;
8959
8979
}
8960
8980
else if (PyLong_Check (x )) {
8961
- long value = PyLong_AS_LONG (x );
8981
+ long value = PyLong_AsLong (x );
8962
8982
if (value < 0 || value > MAX_UNICODE ) {
8963
8983
PyErr_Format (PyExc_ValueError ,
8964
8984
"character mapping must be in range(0x%x)" ,
@@ -8967,6 +8987,7 @@ charmaptranslate_lookup(Py_UCS4 c, PyObject *mapping, PyObject **result)
8967
8987
return -1 ;
8968
8988
}
8969
8989
* result = x ;
8990
+ * replace = (Py_UCS4 )value ;
8970
8991
return 0 ;
8971
8992
}
8972
8993
else if (PyUnicode_Check (x )) {
@@ -8990,8 +9011,9 @@ charmaptranslate_output(Py_UCS4 ch, PyObject *mapping,
8990
9011
_PyUnicodeWriter * writer )
8991
9012
{
8992
9013
PyObject * item ;
9014
+ Py_UCS4 replace ;
8993
9015
8994
- if (charmaptranslate_lookup (ch , mapping , & item ))
9016
+ if (charmaptranslate_lookup (ch , mapping , & item , & replace ))
8995
9017
return -1 ;
8996
9018
8997
9019
if (item == NULL ) {
@@ -9008,10 +9030,7 @@ charmaptranslate_output(Py_UCS4 ch, PyObject *mapping,
9008
9030
}
9009
9031
9010
9032
if (PyLong_Check (item )) {
9011
- long ch = (Py_UCS4 )PyLong_AS_LONG (item );
9012
- /* PyLong_AS_LONG() cannot fail, charmaptranslate_lookup() already
9013
- used it */
9014
- if (_PyUnicodeWriter_WriteCharInline (writer , ch ) < 0 ) {
9033
+ if (_PyUnicodeWriter_WriteCharInline (writer , replace ) < 0 ) {
9015
9034
Py_DECREF (item );
9016
9035
return -1 ;
9017
9036
}
@@ -9038,9 +9057,10 @@ unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch,
9038
9057
Py_UCS1 * translate )
9039
9058
{
9040
9059
PyObject * item = NULL ;
9060
+ Py_UCS4 replace ;
9041
9061
int ret = 0 ;
9042
9062
9043
- if (charmaptranslate_lookup (ch , mapping , & item )) {
9063
+ if (charmaptranslate_lookup (ch , mapping , & item , & replace )) {
9044
9064
return -1 ;
9045
9065
}
9046
9066
@@ -9054,19 +9074,14 @@ unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch,
9054
9074
return 1 ;
9055
9075
}
9056
9076
else if (PyLong_Check (item )) {
9057
- long replace = PyLong_AS_LONG (item );
9058
- /* PyLong_AS_LONG() cannot fail, charmaptranslate_lookup() already
9059
- used it */
9060
- if (127 < replace ) {
9077
+ if (replace > 127 ) {
9061
9078
/* invalid character or character outside ASCII:
9062
9079
skip the fast translate */
9063
9080
goto exit ;
9064
9081
}
9065
9082
translate [ch ] = (Py_UCS1 )replace ;
9066
9083
}
9067
9084
else if (PyUnicode_Check (item )) {
9068
- Py_UCS4 replace ;
9069
-
9070
9085
if (PyUnicode_GET_LENGTH (item ) != 1 )
9071
9086
goto exit ;
9072
9087
@@ -9219,8 +9234,9 @@ _PyUnicode_TranslateCharmap(PyObject *input,
9219
9234
/* find all untranslatable characters */
9220
9235
while (collend < size ) {
9221
9236
PyObject * x ;
9237
+ Py_UCS4 replace ;
9222
9238
ch = PyUnicode_READ (kind , data , collend );
9223
- if (charmaptranslate_lookup (ch , mapping , & x ))
9239
+ if (charmaptranslate_lookup (ch , mapping , & x , & replace ))
9224
9240
goto onError ;
9225
9241
Py_XDECREF (x );
9226
9242
if (x != Py_None )
0 commit comments