@@ -125,8 +125,8 @@ RealNumber_Check(PyObject *obj);
125125static double
126126PySequence_GetItem_AsDouble (PyObject * seq , Py_ssize_t index );
127127static int
128- PySequence_AsVectorCoords (PyObject * seq , double * const coords ,
129- const Py_ssize_t size );
128+ pg_VectorCoordsFromObjOldDontUseInNewCode (PyObject * seq , double * const coords ,
129+ Py_ssize_t size );
130130static int
131131pgVectorCompatible_Check (PyObject * obj , Py_ssize_t dim );
132132static int
@@ -397,13 +397,26 @@ PySequence_GetItem_AsDouble(PyObject *seq, Py_ssize_t index)
397397 return value ;
398398}
399399
400+ /* Use pg_VectorCoordsFromObj instead of this function. That does exact dim
401+ * checking.
402+ * Note that this function sets a python exception on failures */
400403static int
401- PySequence_AsVectorCoords (PyObject * seq , double * const coords ,
402- const Py_ssize_t size )
404+ pg_VectorCoordsFromObjOldDontUseInNewCode (PyObject * seq , double * const coords ,
405+ Py_ssize_t size )
403406{
404407 Py_ssize_t i ;
405408
409+ /* This codepath does not do exact size checking, but for compat reasons
410+ * we are gonna keep it as it is */
406411 if (pgVector_Check (seq )) {
412+ Py_ssize_t seq_dim = ((pgVector * )seq )-> dim ;
413+ if (size > seq_dim ) {
414+ /* Prevent undefined behaviour by consistently 0-ing extra dims */
415+ for (i = seq_dim ; i < size ; ++ i ) {
416+ coords [i ] = 0.0 ;
417+ }
418+ size = seq_dim ;
419+ }
407420 memcpy (coords , ((pgVector * )seq )-> coords , sizeof (double ) * size );
408421 return 1 ;
409422 }
@@ -464,8 +477,7 @@ pgVectorCompatible_Check(PyObject *obj, Py_ssize_t dim)
464477// copies vector coordinates into "coords" array of size >= dim
465478// managed by caller. Returns 0 if obj is not compatible or an error
466479// occurred. If 0 is returned, the error flag will not normally be set.
467- // Callers should set error themselves. This function is a combo of
468- // pgVectorCompatible_Check and PySequence_AsVectorCoords
480+ // Callers should set error themselves.
469481static int
470482pg_VectorCoordsFromObj (PyObject * obj , Py_ssize_t dim , double * const coords )
471483{
@@ -1129,7 +1141,7 @@ vector_SetSlice(pgVector *self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
11291141 }
11301142
11311143 len = ihigh - ilow ;
1132- if (!PySequence_AsVectorCoords (v , new_coords , len )) {
1144+ if (!pg_VectorCoordsFromObjOldDontUseInNewCode (v , new_coords , len )) {
11331145 return -1 ;
11341146 }
11351147
@@ -1250,7 +1262,8 @@ vector_ass_subscript(pgVector *self, PyObject *key, PyObject *value)
12501262 double seqitems [VECTOR_MAX_SIZE ];
12511263 Py_ssize_t cur , i ;
12521264
1253- if (!PySequence_AsVectorCoords (value , seqitems , slicelength )) {
1265+ if (!pg_VectorCoordsFromObjOldDontUseInNewCode (value , seqitems ,
1266+ slicelength )) {
12541267 return -1 ;
12551268 }
12561269 for (cur = start , i = 0 ; i < slicelength ; cur += step , i ++ ) {
@@ -1381,7 +1394,7 @@ vector_richcompare(PyObject *o1, PyObject *o2, int op)
13811394 vec = (pgVector * )o2 ;
13821395 other = o1 ;
13831396 }
1384- if (!pgVectorCompatible_Check (other , vec -> dim )) {
1397+ if (!pg_VectorCoordsFromObj (other , vec -> dim , other_coords )) {
13851398 if (op == Py_EQ ) {
13861399 Py_RETURN_FALSE ;
13871400 }
@@ -1394,10 +1407,6 @@ vector_richcompare(PyObject *o1, PyObject *o2, int op)
13941407 }
13951408 }
13961409
1397- if (!PySequence_AsVectorCoords (other , other_coords , vec -> dim )) {
1398- return NULL ;
1399- }
1400-
14011410 switch (op ) {
14021411 case Py_EQ :
14031412 for (i = 0 ; i < vec -> dim ; i ++ ) {
@@ -1493,7 +1502,8 @@ static PyObject *
14931502vector_dot (pgVector * self , PyObject * other )
14941503{
14951504 double other_coords [VECTOR_MAX_SIZE ];
1496- if (!PySequence_AsVectorCoords (other , other_coords , self -> dim )) {
1505+ if (!pg_VectorCoordsFromObjOldDontUseInNewCode (other , other_coords ,
1506+ self -> dim )) {
14971507 return RAISE (PyExc_TypeError ,
14981508 "Cannot perform dot product with this type." );
14991509 }
@@ -1630,7 +1640,8 @@ vector_slerp(pgVector *self, PyObject *args)
16301640 if (!PyArg_ParseTuple (args , "Od:slerp" , & other , & t )) {
16311641 return NULL ;
16321642 }
1633- if (!PySequence_AsVectorCoords (other , other_coords , self -> dim )) {
1643+ if (!pg_VectorCoordsFromObjOldDontUseInNewCode (other , other_coords ,
1644+ self -> dim )) {
16341645 return RAISE (PyExc_TypeError , "Argument 1 must be a vector." );
16351646 }
16361647 if (fabs (t ) > 1 ) {
@@ -1701,7 +1712,8 @@ vector_lerp(pgVector *self, PyObject *args)
17011712 if (!PyArg_ParseTuple (args , "Od:Vector.lerp" , & other , & t )) {
17021713 return NULL ;
17031714 }
1704- if (!PySequence_AsVectorCoords (other , other_coords , self -> dim )) {
1715+ if (!pg_VectorCoordsFromObjOldDontUseInNewCode (other , other_coords ,
1716+ self -> dim )) {
17051717 return RAISE (PyExc_TypeError , "Expected Vector as argument 1" );
17061718 }
17071719 if (t < 0 || t > 1 ) {
@@ -1730,7 +1742,8 @@ vector_smoothstep(pgVector *self, PyObject *args)
17301742 if (!PyArg_ParseTuple (args , "Od:Vector.smoothstep" , & other , & t )) {
17311743 return NULL ;
17321744 }
1733- if (!PySequence_AsVectorCoords (other , other_coords , self -> dim )) {
1745+ if (!pg_VectorCoordsFromObjOldDontUseInNewCode (other , other_coords ,
1746+ self -> dim )) {
17341747 return RAISE (PyExc_TypeError , "Expected Vector as argument 1" );
17351748 }
17361749
@@ -1765,7 +1778,7 @@ _vector_reflect_helper(double *dst_coords, const double *src_coords,
17651778 double norm_coords [VECTOR_MAX_SIZE ];
17661779
17671780 /* normalize the normal */
1768- if (!PySequence_AsVectorCoords (normal , norm_coords , dim )) {
1781+ if (!pg_VectorCoordsFromObjOldDontUseInNewCode (normal , norm_coords , dim )) {
17691782 return 0 ;
17701783 }
17711784
@@ -1992,7 +2005,8 @@ vector_project_onto(pgVector *self, PyObject *other)
19922005 double a_dot_b ;
19932006 double b_dot_b ;
19942007
1995- if (!PySequence_AsVectorCoords (other , other_coords , self -> dim )) {
2008+ if (!pg_VectorCoordsFromObjOldDontUseInNewCode (other , other_coords ,
2009+ self -> dim )) {
19962010 return RAISE (PyExc_TypeError , "Expected Vector as argument 1" );
19972011 }
19982012
@@ -3795,12 +3809,8 @@ vector_elementwiseproxy_richcompare(PyObject *o1, PyObject *o2, int op)
37953809 }
37963810 dim = vec -> dim ;
37973811
3798- if (pgVectorCompatible_Check (other , dim )) {
3799- double other_coords [VECTOR_MAX_SIZE ];
3800-
3801- if (!PySequence_AsVectorCoords (other , other_coords , dim )) {
3802- return NULL ;
3803- }
3812+ double other_coords [VECTOR_MAX_SIZE ];
3813+ if (pg_VectorCoordsFromObj (other , dim , other_coords )) {
38043814 /* use diff == diff to check for NaN */
38053815 /* TODO: how should NaN be handled with LT/LE/GT/GE? */
38063816 switch (op ) {
@@ -3955,11 +3965,8 @@ vector_elementwiseproxy_generic_math(PyObject *o1, PyObject *o2, int op)
39553965 other = (PyObject * )((vector_elementwiseproxy * )other )-> vec ;
39563966 }
39573967
3958- if (pgVectorCompatible_Check (other , dim )) {
3968+ if (pg_VectorCoordsFromObj (other , dim , other_coords )) {
39593969 op |= OP_ARG_VECTOR ;
3960- if (!PySequence_AsVectorCoords (other , other_coords , dim )) {
3961- return NULL ;
3962- }
39633970 }
39643971 else {
39653972 other_value = PyFloat_AsDouble (other );
0 commit comments