@@ -846,7 +846,7 @@ static int write_pair(bson_buffer* buffer, const char* name, Py_ssize_t name_len
846846 int type_byte ;
847847
848848 /* Don't write any _id elements unless we're explicitly told to -
849- * _id has to be written first so we write do so, but don't bother
849+ * _id has to be written first so we do so, but don't bother
850850 * deleting it from the dictionary being written. */
851851 if (!allow_id && strcmp (name , "_id" ) == 0 ) {
852852 return 1 ;
@@ -868,6 +868,37 @@ static int write_pair(bson_buffer* buffer, const char* name, Py_ssize_t name_len
868868 return 1 ;
869869}
870870
871+ static int decode_and_write_pair (bson_buffer * buffer , PyObject * key ,
872+ PyObject * value , unsigned char check_keys ) {
873+ PyObject * encoded ;
874+ if (PyUnicode_Check (key )) {
875+ encoded = PyUnicode_AsUTF8String (key );
876+ if (!encoded ) {
877+ return 0 ;
878+ }
879+ } else if (PyString_Check (key )) {
880+ encoded = key ;
881+ Py_INCREF (encoded );
882+ } else {
883+ PyObject * errmsg = PyString_FromString ("documents must have only string keys, key was " );
884+ PyObject * repr = PyObject_Repr (key );
885+ PyString_ConcatAndDel (& errmsg , repr );
886+ PyErr_SetString (InvalidDocument , PyString_AsString (errmsg ));
887+ Py_DECREF (errmsg );
888+ return 0 ;
889+ }
890+
891+ /* Don't allow writing _id here - it was already written. */
892+ if (!write_pair (buffer , PyString_AsString (encoded ),
893+ PyString_Size (encoded ), value , check_keys , 0 )) {
894+ Py_DECREF (encoded );
895+ return 0 ;
896+ }
897+
898+ Py_DECREF (encoded );
899+ return 1 ;
900+ }
901+
871902static int write_son (bson_buffer * buffer , PyObject * dict , int start_position ,
872903 int length_location , unsigned char check_keys ) {
873904 PyObject * keys = PyObject_CallMethod (dict , "keys" , NULL );
@@ -880,33 +911,16 @@ static int write_son(bson_buffer* buffer, PyObject* dict, int start_position,
880911 for (i = 0 ; i < items ; i ++ ) {
881912 PyObject * key ;
882913 PyObject * value ;
883- PyObject * encoded ;
884914
885915 key = PyList_GetItem (keys , i );
886916 if (!key ) {
887917 Py_DECREF (keys );
888918 return 0 ;
889919 }
890920 value = PyDict_GetItem (dict , key );
891- if (!value ) {
892- Py_DECREF (keys );
893- return 0 ;
894- }
895- if (PyUnicode_CheckExact (key )) {
896- encoded = PyUnicode_AsUTF8String (key );
897- if (!encoded ) {
898- Py_DECREF (keys );
899- return 0 ;
900- }
901- } else {
902- encoded = key ;
903- Py_INCREF (encoded );
904- }
905- /* Don't allow writing _id here - it was written above. */
906- if (!write_pair (buffer , PyString_AsString (encoded ),
907- PyString_Size (encoded ), value , check_keys , 0 )) {
921+ if (!value ||
922+ !decode_and_write_pair (buffer , key , value , check_keys )) {
908923 Py_DECREF (keys );
909- Py_DECREF (encoded );
910924 return 0 ;
911925 }
912926 }
@@ -950,20 +964,7 @@ static int write_dict(bson_buffer* buffer, PyObject* dict, unsigned char check_k
950964 Py_ssize_t pos = 0 ;
951965
952966 while (PyDict_Next (dict , & pos , & key , & value )) {
953- PyObject * encoded ;
954- if (PyUnicode_CheckExact (key )) {
955- encoded = PyUnicode_AsUTF8String (key );
956- if (!encoded ) {
957- return 0 ;
958- }
959- } else {
960- encoded = key ;
961- Py_INCREF (encoded );
962- }
963- /* Don't allow writing _id here - it was written above. */
964- if (!write_pair (buffer , PyString_AsString (encoded ),
965- PyString_Size (encoded ), value , check_keys , 0 )) {
966- Py_DECREF (encoded );
967+ if (!decode_and_write_pair (buffer , key , value , check_keys )) {
967968 return 0 ;
968969 }
969970 }
0 commit comments