!18 修复一个bug,当format参数未被完全使用的时候产生段错误
Merge pull request !18 from Luan-233/master
This commit is contained in:
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user