From 077648cc749468dc69628bac0a254b85ed609145 Mon Sep 17 00:00:00 2001 From: sarvesh patil <103917093+HyperPS@users.noreply.github.com> Date: Tue, 24 Feb 2026 19:21:25 +0530 Subject: [PATCH] Revert all changes except fix: check downsize instead of size in buffer_write_bytes_ssize_t --- pymongo/_cmessagemodule.c | 116 ++++++++------------------------------ 1 file changed, 23 insertions(+), 93 deletions(-) diff --git a/pymongo/_cmessagemodule.c b/pymongo/_cmessagemodule.c index e115e81de..a6789cbcc 100644 --- a/pymongo/_cmessagemodule.c +++ b/pymongo/_cmessagemodule.c @@ -25,17 +25,6 @@ #include "_cbsonmodule.h" #include "buffer.h" -#include - -static int _check_int32_size(size_t size, const char *what) { - if (size > (size_t)INT32_MAX) { - PyErr_Format(PyExc_OverflowError, - "MongoDB %s length exceeds maximum int32 size (%d bytes)", - what, INT32_MAX); - return 0; - } - return 1; -} struct module_state { PyObject* _cbson; @@ -55,7 +44,7 @@ struct module_state { /* Get an error class from the pymongo.errors module. * * Returns a new ref */ -static PyObject* _error(const char *name) { +static PyObject* _error(char* name) { PyObject* error = NULL; PyObject* errors = PyImport_ImportModule("pymongo.errors"); if (!errors) { @@ -69,17 +58,14 @@ static PyObject* _error(const char *name) { /* The same as buffer_write_bytes except that it also validates * "size" will fit in an int. * Returns 0 on failure */ -static int buffer_write_bytes_ssize_t(buffer_t buffer, const char *data, Py_ssize_t size) -{ +static int buffer_write_bytes_ssize_t(buffer_t buffer, const char* data, Py_ssize_t size) { int downsize = _downcast_and_check(size, 0); if (downsize == -1) { - /* _downcast_and_check already set an exception */ return 0; } return buffer_write_bytes(buffer, data, downsize); } - static PyObject* _cbson_query_message(PyObject* self, PyObject* args) { /* NOTE just using a random number as the request_id */ int request_id = rand(); @@ -94,8 +80,7 @@ static PyObject* _cbson_query_message(PyObject* self, PyObject* args) { PyObject* options_obj = NULL; codec_options_t options; buffer_t buffer = NULL; - int length_location; - size_t message_length; + int length_location, message_length; PyObject* result = NULL; struct module_state *state = GETSTATE(self); if (!state) { @@ -151,13 +136,7 @@ static PyObject* _cbson_query_message(PyObject* self, PyObject* args) { max_size = (cur_size > max_size) ? cur_size : max_size; } - message_length = (size_t)pymongo_buffer_get_position(buffer) - - (size_t)length_location; - - if (!_check_int32_size(message_length, "message length")) { - goto fail; - } - + message_length = pymongo_buffer_get_position(buffer) - length_location; buffer_write_int32_at_position( buffer, length_location, (int32_t)message_length); @@ -183,8 +162,7 @@ static PyObject* _cbson_get_more_message(PyObject* self, PyObject* args) { int num_to_return; long long cursor_id; buffer_t buffer = NULL; - int length_location; - size_t message_length; + int length_location, message_length; PyObject* result = NULL; if (!PyArg_ParseTuple(args, "et#iL", @@ -218,13 +196,7 @@ static PyObject* _cbson_get_more_message(PyObject* self, PyObject* args) { goto fail; } - message_length = (size_t)pymongo_buffer_get_position(buffer) - - (size_t)length_location; - - if (!_check_int32_size(message_length, "getMore message length")) { - goto fail; - } - + message_length = pymongo_buffer_get_position(buffer) - length_location; buffer_write_int32_at_position( buffer, length_location, (int32_t)message_length); @@ -232,7 +204,7 @@ static PyObject* _cbson_get_more_message(PyObject* self, PyObject* args) { result = Py_BuildValue("iy#", request_id, pymongo_buffer_get_buffer(buffer), (Py_ssize_t)pymongo_buffer_get_position(buffer)); -fail: +failure: PyMem_Free(collection_name); if (buffer) { pymongo_buffer_free(buffer); @@ -257,8 +229,7 @@ static PyObject* _cbson_op_msg(PyObject* self, PyObject* args) { PyObject* options_obj = NULL; codec_options_t options; buffer_t buffer = NULL; - int length_location; - size_t message_length; + int length_location, message_length; int total_size = 0; int max_doc_size = 0; PyObject* result = NULL; @@ -308,8 +279,7 @@ static PyObject* _cbson_op_msg(PyObject* self, PyObject* args) { } if (identifier_length) { - int payload_one_length_location; - size_t payload_length; + int payload_one_length_location, payload_length; /* Payload type 1 */ if (!buffer_write_bytes(buffer, "\x01", 1)) { goto fail; @@ -337,30 +307,16 @@ static PyObject* _cbson_op_msg(PyObject* self, PyObject* args) { Py_CLEAR(doc); } - payload_length = (size_t)pymongo_buffer_get_position(buffer) - - (size_t)payload_one_length_location; - - if (!_check_int32_size(payload_length, "OP_MSG payload length")) { - goto fail; - } - + payload_length = pymongo_buffer_get_position(buffer) - payload_one_length_location; buffer_write_int32_at_position( buffer, payload_one_length_location, (int32_t)payload_length); total_size += payload_length; } - - message_length = (size_t)pymongo_buffer_get_position(buffer) - - (size_t)length_location; - - if (!_check_int32_size(message_length, "OP_MSG message length")) { - goto fail; - } - + message_length = pymongo_buffer_get_position(buffer) - length_location; buffer_write_int32_at_position( buffer, length_location, (int32_t)message_length); - /* objectify buffer */ result = Py_BuildValue("iy#ii", request_id, pymongo_buffer_get_buffer(buffer), @@ -377,7 +333,6 @@ fail: return result; } - static void _set_document_too_large(int size, long max) { PyObject* DocumentTooLarge = _error("DocumentTooLarge"); @@ -396,7 +351,6 @@ _set_document_too_large(int size, long max) { #define _DELETE 2 /* OP_MSG ----------------------------------------------- */ - static int _batched_op_msg( unsigned char op, unsigned char ack, @@ -409,8 +363,8 @@ _batched_op_msg( long max_message_size; int idx = 0; int size_location; - size_t position; - size_t length; + int position; + int length; PyObject* max_bson_size_obj = NULL; PyObject* max_write_batch_size_obj = NULL; PyObject* max_message_size_obj = NULL; @@ -564,13 +518,8 @@ _batched_op_msg( goto fail; } - position = (size_t)pymongo_buffer_get_position(buffer); - length = position - (size_t)size_location; - - if (!_check_int32_size(length, "batched OP_MSG section length")) { - goto fail; - } - + position = pymongo_buffer_get_position(buffer); + length = position - size_location; buffer_write_int32_at_position(buffer, size_location, (int32_t)length); return 1; @@ -628,7 +577,7 @@ _cbson_encode_batched_op_msg(PyObject* self, PyObject* args) { pymongo_buffer_get_buffer(buffer), (Py_ssize_t)pymongo_buffer_get_position(buffer), to_publish); -fail: +failure: destroy_codec_options(&options); pymongo_buffer_free(buffer); Py_XDECREF(to_publish); @@ -640,7 +589,7 @@ _cbson_batched_op_msg(PyObject* self, PyObject* args) { unsigned char op; unsigned char ack; int request_id; - size_t position; + int position; PyObject* command = NULL; PyObject* docs = NULL; PyObject* ctx = NULL; @@ -692,19 +641,14 @@ _cbson_batched_op_msg(PyObject* self, PyObject* args) { } request_id = rand(); - position = (size_t)pymongo_buffer_get_position(buffer); - - if (!_check_int32_size(position, "batched OP_MSG message length")) { - goto fail; - } - + position = pymongo_buffer_get_position(buffer); buffer_write_int32_at_position(buffer, 0, (int32_t)position); buffer_write_int32_at_position(buffer, 4, (int32_t)request_id); result = Py_BuildValue("iy#O", request_id, pymongo_buffer_get_buffer(buffer), (Py_ssize_t)pymongo_buffer_get_position(buffer), to_publish); -fail: +failure: destroy_codec_options(&options); pymongo_buffer_free(buffer); Py_XDECREF(to_publish); @@ -712,7 +656,6 @@ fail: } /* End OP_MSG -------------------------------------------- */ - static int _batched_write_command( char* ns, Py_ssize_t ns_len, unsigned char op, @@ -904,21 +847,10 @@ _batched_write_command( goto fail; } - position = (size_t)pymongo_buffer_get_position(buffer); - length = position - (size_t)lst_len_loc - 1; - - if (!_check_int32_size(length, "batched write list length")) { - goto fail; - } - + position = pymongo_buffer_get_position(buffer); + length = position - lst_len_loc - 1; buffer_write_int32_at_position(buffer, lst_len_loc, (int32_t)length); - - length = position - (size_t)cmd_len_loc; - - if (!_check_int32_size(length, "batched write command length")) { - goto fail; - } - + length = position - cmd_len_loc; buffer_write_int32_at_position(buffer, cmd_len_loc, (int32_t)length); return 1; @@ -979,7 +911,7 @@ _cbson_encode_batched_write_command(PyObject* self, PyObject* args) { pymongo_buffer_get_buffer(buffer), (Py_ssize_t)pymongo_buffer_get_position(buffer), to_publish); -fail: +failure: PyMem_Free(ns); destroy_codec_options(&options); pymongo_buffer_free(buffer); @@ -1082,7 +1014,6 @@ fail: INITERROR; } - static PyModuleDef_Slot _cmessage_slots[] = { {Py_mod_exec, _cmessage_exec}, #ifdef Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED @@ -1094,7 +1025,6 @@ static PyModuleDef_Slot _cmessage_slots[] = { {0, NULL}, }; - static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_cmessage",