修复一个bug,当format参数未被完全使用的时候产生段错误

This commit is contained in:
Luan-233
2023-09-05 22:26:17 -07:00
parent d81dec06b9
commit 43dcbfe50a
2 changed files with 84 additions and 71 deletions

View File

@ -78,6 +78,8 @@
* Agreement. * Agreement.
*/ */
#include <string.h>
#define PSYCOPG_MODULE #define PSYCOPG_MODULE
#include "psycopg/psycopg.h" #include "psycopg/psycopg.h"
#include "pyport.h" #include "pyport.h"
@ -121,8 +123,9 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
char **args_list = NULL; // arguments list as char ** char **args_list = NULL; // arguments list as char **
char *args_buffer = NULL; // Bytes_AS_STRING(args_value) char *args_buffer = NULL; // Bytes_AS_STRING(args_value)
Py_ssize_t * args_len = NULL; // every argument's length in args_list Py_ssize_t * args_len = NULL; // every argument's length in args_list
int args_id = 0; //index of arguments(when generating result) int args_id = 0; // index of arguments(when generating result and check args of no use)
int index_type = 0; // if exists $number, it will be 1, otherwise 0 int index_type = 0; // if exists $number, it will be 1, otherwise 0
int *arg_usecnt = NULL; // used to test if args are all used
if (format == NULL || !Bytes_Check(format) || args == NULL) { // check if arguments are valid if (format == NULL || !Bytes_Check(format) || args == NULL) { // check if arguments are valid
PyErr_SetString(PyExc_SystemError, "bad argument to internal function"); PyErr_SetString(PyExc_SystemError, "bad argument to internal function");
@ -235,6 +238,7 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
} }
args_list = (char **)malloc(sizeof(char *) * arglen); // buffer args_list = (char **)malloc(sizeof(char *) * arglen); // buffer
memset(args_list, NULL, sizeof(char *) * arglen);
args_len = (Py_ssize_t *)malloc(sizeof(Py_ssize_t *) * arglen); // length of every argument args_len = (Py_ssize_t *)malloc(sizeof(Py_ssize_t *) * arglen); // length of every argument
while ((args_value = getnextarg(args, arglen, &argidx)) != NULL) { // stop when receive NULL while ((args_value = getnextarg(args, arglen, &argidx)) != NULL) { // stop when receive NULL
Py_ssize_t length = 0; Py_ssize_t length = 0;
@ -253,6 +257,9 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
Py_XDECREF(args_value); Py_XDECREF(args_value);
} }
arg_usecnt = (int *)malloc(sizeof(int) * arglen);
memset(arg_usecnt, 0, sizeof(char *) * arglen);
fmt = Bytes_AS_STRING(format); // get pointer of format fmt = Bytes_AS_STRING(format); // get pointer of format
fmtcnt = Bytes_GET_SIZE(format); // get length of format fmtcnt = Bytes_GET_SIZE(format); // get length of format
reslen = rescnt = 1; reslen = rescnt = 1;
@ -310,6 +317,7 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
Py_MEMCPY(res, args_list[args_id], args_len[args_id]); Py_MEMCPY(res, args_list[args_id], args_len[args_id]);
rescnt -= args_len[args_id]; rescnt -= args_len[args_id];
res += args_len[args_id]; res += args_len[args_id];
++arg_usecnt[args_id];
++args_id; ++args_id;
++fmt; ++fmt;
} }
@ -363,6 +371,7 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
Py_MEMCPY(res, args_list[index], args_len[index]); Py_MEMCPY(res, args_list[index], args_len[index]);
rescnt -= args_len[index]; rescnt -= args_len[index];
res += args_len[index]; res += args_len[index];
++arg_usecnt[index];
} }
else { // invalid place holder else { // invalid place holder
PyErr_Format(PyExc_ValueError, "unsupported format character '%c' (0x%x) " PyErr_Format(PyExc_ValueError, "unsupported format character '%c' (0x%x) "
@ -373,14 +382,19 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
} }
} }
} }
if ((args_id < arglen) && (!dict) && (!index_type)) { //not all arguments are used if ((args_id < arglen) && (!dict) && (!index_type)) { // not all arguments are used, '%' type
PyErr_SetString(PyExc_TypeError, "not all arguments converted during string formatting"); PyErr_SetString(PyExc_TypeError, "not all arguments converted during string formatting");
goto error; goto error;
} }
for (args_id = 0; args_id < arglen; ++args_id) { // not all arguments are used, '$' type
if (!arg_usecnt[args_id]) {
PyErr_SetString(PyExc_TypeError, "not all arguments converted during string formatting");
goto error;
}
}
if (args_list != NULL) { if (args_list != NULL) {
while (--argidx >= 0) free(args_list[argidx]); while (--argidx >= 0) free(args_list[argidx]);
free(args_list); free(args_list), free(args_len), free(arg_usecnt);
free(args_len);
} }
if (args_owned) Py_DECREF(args); if (args_owned) Py_DECREF(args);
if (!(result = resize_bytes(result, reslen - rescnt))) return NULL; // resize if (!(result = resize_bytes(result, reslen - rescnt))) return NULL; // resize
@ -389,8 +403,7 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
error: error:
if (args_list != NULL) { // release all the refcnt if (args_list != NULL) { // release all the refcnt
while (--argidx >= 0) free(args_list[argidx]); while (--argidx >= 0) free(args_list[argidx]);
free(args_list); free(args_list), free(args_len), free(arg_usecnt);
free(args_len);
} }
Py_DECREF(result); Py_DECREF(result);
if (args_owned) Py_DECREF(args); if (args_owned) Py_DECREF(args);