Skip to content

Commit cc41bff

Browse files
committed
Address comments in the PR.
1 parent 1f0e4ad commit cc41bff

File tree

2 files changed

+60
-37
lines changed

2 files changed

+60
-37
lines changed

src/_path.h

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -956,9 +956,11 @@ void quad2cubic(double x0, double y0,
956956
char *__append_to_string(char *p, char *buffer, size_t buffersize,
957957
const char *content)
958958
{
959+
int buffersize_int = (int)buffersize;
960+
959961
for (const char *i = content; *i; ++i) {
960-
if (p < buffer || p - buffer >= (int)buffersize) {
961-
return p;
962+
if (p < buffer || p - buffer >= buffersize_int) {
963+
return NULL;
962964
}
963965

964966
*p++ = *i;
@@ -968,12 +970,12 @@ char *__append_to_string(char *p, char *buffer, size_t buffersize,
968970
}
969971

970972
template <class PathIterator>
971-
void __convert_to_string(PathIterator &path,
972-
int precision,
973-
char **codes,
974-
bool postfix,
975-
char *buffer,
976-
size_t *buffersize)
973+
int __convert_to_string(PathIterator &path,
974+
int precision,
975+
char **codes,
976+
bool postfix,
977+
char *buffer,
978+
size_t *buffersize)
977979
{
978980
#if PY_VERSION_HEX < 0x02070000
979981
char format[64];
@@ -992,75 +994,86 @@ void __convert_to_string(PathIterator &path,
992994

993995
while ((code = path.vertex(&x[0], &y[0])) != agg::path_cmd_stop) {
994996
if (code == 0x4f) {
995-
p = __append_to_string(p, buffer, *buffersize, codes[4]);
997+
if ((p = __append_to_string(p, buffer, *buffersize, codes[4])) == NULL) return 1;
996998
} else {
997999
size = sizes[code - 1];
9981000

9991001
for (int i = 1; i < size; ++i) {
1000-
path.vertex(&x[i], &y[i]);
1002+
unsigned subcode = path.vertex(&x[i], &y[i]);
1003+
if (subcode != code) {
1004+
return 2;
1005+
}
10011006
}
10021007

10031008
/* For formats that don't support quad curves, convert to
10041009
cubic curves */
1005-
if (codes[code - 1][0] == '\0') {
1010+
if (code == CURVE3 && codes[code - 1][0] == '\0') {
10061011
quad2cubic(last_x, last_y, x[0], y[0], x[1], y[1], x, y);
10071012
code++;
10081013
size = 3;
10091014
}
10101015

10111016
if (!postfix) {
1012-
p = __append_to_string(p, buffer, *buffersize, codes[code - 1]);
1013-
p = __append_to_string(p, buffer, *buffersize, " ");
1017+
if ((p = __append_to_string(p, buffer, *buffersize, codes[code - 1])) == NULL) return 1;
1018+
if ((p = __append_to_string(p, buffer, *buffersize, " ")) == NULL) return 1;
10141019
}
10151020

10161021
for (int i = 0; i < size; ++i) {
10171022
#if PY_VERSION_HEX >= 0x02070000
10181023
char *str;
10191024
str = PyOS_double_to_string(x[i], 'g', precision, 0, NULL);
1020-
p = __append_to_string(p, buffer, *buffersize, str);
1025+
if ((p = __append_to_string(p, buffer, *buffersize, str)) == NULL) {
1026+
PyMem_Free(str);
1027+
return 1;
1028+
}
10211029
PyMem_Free(str);
1022-
p = __append_to_string(p, buffer, *buffersize, " ");
1030+
if ((p = __append_to_string(p, buffer, *buffersize, " ")) == NULL) return 1;
10231031
str = PyOS_double_to_string(y[i], 'g', precision, 0, NULL);
1024-
p = __append_to_string(p, buffer, *buffersize, str);
1032+
if ((p = __append_to_string(p, buffer, *buffersize, str)) == NULL) {
1033+
PyMem_Free(str);
1034+
return 1;
1035+
}
10251036
PyMem_Free(str);
1026-
p = __append_to_string(p, buffer, *buffersize, " ");
1037+
if ((p = __append_to_string(p, buffer, *buffersize, " ")) == NULL) return 1;
10271038
#else
10281039
char str[64];
10291040
PyOS_ascii_formatd(str, 64, format, x[i]);
1030-
p = __append_to_string(p, buffer, *buffersize, str);
1041+
if ((p = __append_to_string(p, buffer, *buffersize, str)) == NULL) return 1;
10311042
p = __append_to_string(p, buffer, *buffersize, " ");
10321043
PyOS_ascii_formatd(str, 64, format, y[i]);
1033-
p = __append_to_string(p, buffer, *buffersize, str);
1034-
p = __append_to_string(p, buffer, *buffersize, " ");
1044+
if ((p = __append_to_string(p, buffer, *buffersize, str)) == NULL) return 1;
1045+
if ((p = __append_to_string(p, buffer, *buffersize, " ")) == NULL) return 1;
10351046
#endif
10361047
}
10371048

10381049
if (postfix) {
1039-
p = __append_to_string(p, buffer, *buffersize, codes[code - 1]);
1050+
if ((p = __append_to_string(p, buffer, *buffersize, codes[code - 1])) == NULL) return 1;
10401051
}
10411052

10421053
last_x = x[size - 1];
10431054
last_y = y[size - 1];
10441055
}
10451056

1046-
p = __append_to_string(p, buffer, *buffersize, "\n");
1057+
if ((p = __append_to_string(p, buffer, *buffersize, "\n")) == NULL) return 1;
10471058
}
10481059

10491060
*p = '\0';
10501061
*buffersize = p - buffer;
1062+
1063+
return 0;
10511064
}
10521065

10531066
template <class PathIterator>
1054-
void convert_to_string(PathIterator &path,
1055-
agg::trans_affine &trans,
1056-
agg::rect_d &clip_rect,
1057-
bool simplify,
1058-
SketchParams sketch_params,
1059-
int precision,
1060-
char **codes,
1061-
bool postfix,
1062-
char *buffer,
1063-
size_t *buffersize)
1067+
int convert_to_string(PathIterator &path,
1068+
agg::trans_affine &trans,
1069+
agg::rect_d &clip_rect,
1070+
bool simplify,
1071+
SketchParams sketch_params,
1072+
int precision,
1073+
char **codes,
1074+
bool postfix,
1075+
char *buffer,
1076+
size_t *buffersize)
10641077
{
10651078
typedef agg::conv_transform<py::PathIterator> transformed_path_t;
10661079
typedef PathNanRemover<transformed_path_t> nan_removal_t;
@@ -1077,11 +1090,11 @@ void convert_to_string(PathIterator &path,
10771090
simplify_t simplified(clipped, simplify, path.simplify_threshold());
10781091

10791092
if (sketch_params.scale == 0.0) {
1080-
__convert_to_string(simplified, precision, codes, postfix, buffer, buffersize);
1093+
return __convert_to_string(simplified, precision, codes, postfix, buffer, buffersize);
10811094
} else {
10821095
curve_t curve(simplified);
10831096
sketch_t sketch(curve, sketch_params.scale, sketch_params.length, sketch_params.randomness);
1084-
__convert_to_string(sketch, precision, codes, postfix, buffer, buffersize);
1097+
return __convert_to_string(sketch, precision, codes, postfix, buffer, buffersize);
10851098
}
10861099

10871100
}

src/_path_wrapper.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ static PyObject *Py_convert_to_string(PyObject *self, PyObject *args, PyObject *
628628
PyObject *codesobj;
629629
char *codes[5];
630630
int postfix;
631+
int status;
631632

632633
if (!PyArg_ParseTuple(args,
633634
"O&O&O&OO&iOi:convert_to_string",
@@ -677,9 +678,18 @@ static PyObject *Py_convert_to_string(PyObject *self, PyObject *args, PyObject *
677678
buffer.reserve(buffersize);
678679

679680
CALL_CPP("convert_to_string",
680-
(convert_to_string(path, trans, cliprect, simplify, sketch,
681-
precision, codes, (bool)postfix, &buffer[0],
682-
&buffersize)));
681+
(status = convert_to_string(
682+
path, trans, cliprect, simplify, sketch,
683+
precision, codes, (bool)postfix, &buffer[0],
684+
&buffersize)));
685+
686+
if (status == 1) {
687+
PyErr_SetString(PyExc_MemoryError, "Buffer overflow");
688+
return NULL;
689+
} else if (status == 2) {
690+
PyErr_SetString(PyExc_ValueError, "Malformed path codes");
691+
return NULL;
692+
}
683693

684694
return PyBytes_FromStringAndSize(&buffer[0], buffersize);
685695
}

0 commit comments

Comments
 (0)