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