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

Merge pull request !18 from Luan-233/master
This commit is contained in:
opengauss_bot
2023-09-11 08:45:36 +00:00
committed by Gitee
2 changed files with 84 additions and 71 deletions

View File

@ -78,6 +78,8 @@
* Agreement.
*/
#include <string.h>
#define PSYCOPG_MODULE
#include "psycopg/psycopg.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_buffer = NULL; // Bytes_AS_STRING(args_value)
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 *arg_usecnt = NULL; // used to test if args are all used
if (format == NULL || !Bytes_Check(format) || args == NULL) { // check if arguments are valid
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
memset(args_list, NULL, sizeof(char *) * arglen);
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
Py_ssize_t length = 0;
@ -253,6 +257,9 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
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
fmtcnt = Bytes_GET_SIZE(format); // get length of format
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]);
rescnt -= args_len[args_id];
res += args_len[args_id];
++arg_usecnt[args_id];
++args_id;
++fmt;
}
@ -363,6 +371,7 @@ PyObject *Bytes_Format(PyObject *format, PyObject *args, char place_holder) {
Py_MEMCPY(res, args_list[index], args_len[index]);
rescnt -= args_len[index];
res += args_len[index];
++arg_usecnt[index];
}
else { // invalid place holder
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");
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) {
while (--argidx >= 0) free(args_list[argidx]);
free(args_list);
free(args_len);
free(args_list), free(args_len), free(arg_usecnt);
}
if (args_owned) Py_DECREF(args);
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:
if (args_list != NULL) { // release all the refcnt
while (--argidx >= 0) free(args_list[argidx]);
free(args_list);
free(args_len);
free(args_list), free(args_len), free(arg_usecnt);
}
Py_DECREF(result);
if (args_owned) Py_DECREF(args);