Revert all changes except fix: check downsize instead of size in buffer_write_bytes_ssize_t

This commit is contained in:
sarvesh patil 2026-02-24 19:21:25 +05:30
parent 52019517e0
commit 077648cc74

View File

@ -25,17 +25,6 @@
#include "_cbsonmodule.h"
#include "buffer.h"
#include <limits.h>
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",