3636
3737Tcl_Interp * RTcl_interp ;
3838
39+ /* For Tcl < 8.7 */
40+ #ifndef TCL_SIZE_MAX
41+ typedef int Tcl_Size ;
42+ #endif
43+
3944static void RTcl_dec_refcount (SEXP R_tclobj )
4045{
4146 Tcl_DecrRefCount ((Tcl_Obj * ) R_ExternalPtrAddr (R_tclobj ));
@@ -331,20 +336,20 @@ SEXP RTcl_StringFromObj(SEXP args)
331336
332337SEXP RTcl_ObjAsCharVector (SEXP args )
333338{
334- int count ;
339+ Tcl_Size count , i ;
335340 Tcl_Obj * * elem , * obj ;
336- int ret , i ;
341+ int ret ;
337342 SEXP ans ;
338343
339344 if (TYPEOF (CADR (args )) != EXTPTRSXP )
340345 error (_ ("invalid argument" ));
341346 obj = (Tcl_Obj * ) R_ExternalPtrAddr (CADR (args ));
342347 if (!obj ) error (_ ("invalid tclObj -- perhaps saved from another session?" ));
343348 ret = Tcl_ListObjGetElements (RTcl_interp , obj , & count , & elem );
344- if (ret != TCL_OK )
349+ if (ret != TCL_OK || count > R_XLEN_T_MAX )
345350 return RTcl_StringFromObj (args );
346-
347- PROTECT (ans = allocVector (STRSXP , count ));
351+
352+ PROTECT (ans = allocVector (STRSXP , ( R_xlen_t ) count ));
348353 for (i = 0 ; i < count ; i ++ ) {
349354 char * s ;
350355 Tcl_DString s_ds ;
@@ -405,9 +410,9 @@ SEXP RTcl_ObjFromCharVector(SEXP args)
405410
406411SEXP RTcl_ObjAsDoubleVector (SEXP args )
407412{
408- int count ;
413+ Tcl_Size count , i ;
409414 Tcl_Obj * * elem , * obj ;
410- int ret , i ;
415+ int ret ;
411416 double x ;
412417 SEXP ans ;
413418
@@ -422,10 +427,10 @@ SEXP RTcl_ObjAsDoubleVector(SEXP args)
422427
423428 /* Then try as list */
424429 ret = Tcl_ListObjGetElements (RTcl_interp , obj , & count , & elem );
425- if (ret != TCL_OK ) /* didn't work, return NULL */
430+ if (ret != TCL_OK || count > R_XLEN_T_MAX ) /* didn't work, return NULL */
426431 return R_NilValue ;
427-
428- ans = allocVector (REALSXP , count );
432+
433+ ans = allocVector (REALSXP , ( R_xlen_t ) count );
429434 for (i = 0 ; i < count ; i ++ ){
430435 ret = Tcl_GetDoubleFromObj (RTcl_interp , elem [i ], & x );
431436 if (ret != TCL_OK ) x = NA_REAL ;
@@ -470,9 +475,9 @@ SEXP RTcl_ObjFromDoubleVector(SEXP args)
470475
471476SEXP RTcl_ObjAsIntVector (SEXP args )
472477{
473- int count ;
478+ Tcl_Size count , i ;
474479 Tcl_Obj * * elem , * obj ;
475- int ret , i ;
480+ int ret ;
476481 int x ;
477482 SEXP ans ;
478483
@@ -487,10 +492,10 @@ SEXP RTcl_ObjAsIntVector(SEXP args)
487492
488493 /* Then try as list */
489494 ret = Tcl_ListObjGetElements (RTcl_interp , obj , & count , & elem );
490- if (ret != TCL_OK ) /* didn't work, return NULL */
495+ if (ret != TCL_OK || count > R_XLEN_T_MAX ) /* didn't work, return NULL */
491496 return R_NilValue ;
492-
493- ans = allocVector (INTSXP , count );
497+
498+ ans = allocVector (INTSXP , ( R_xlen_t ) count );
494499 for (i = 0 ; i < count ; i ++ ){
495500 ret = Tcl_GetIntFromObj (RTcl_interp , elem [i ], & x );
496501 if (ret != TCL_OK ) x = NA_INTEGER ;
@@ -525,7 +530,7 @@ SEXP RTcl_ObjFromIntVector(SEXP args)
525530
526531SEXP RTcl_ObjAsRawVector (SEXP args )
527532{
528- int nb , count , i , j ;
533+ Tcl_Size count , nb , i , j ;
529534 Tcl_Obj * * elem , * obj ;
530535 unsigned char * ret ;
531536 SEXP ans , el ;
@@ -536,18 +541,19 @@ SEXP RTcl_ObjAsRawVector(SEXP args)
536541 if (!obj ) error (_ ("invalid tclObj -- perhaps saved from another session?" ));
537542 ret = Tcl_GetByteArrayFromObj (obj , & nb );
538543 if (ret ) {
539- ans = allocVector (RAWSXP , nb );
544+ ans = allocVector (RAWSXP , ( R_xlen_t ) nb );
540545 for (j = 0 ; j < nb ; j ++ ) RAW (ans )[j ] = ret [j ];
541546 return ans ;
542547 }
543548
544549 /* Then try as list */
545550 if (Tcl_ListObjGetElements (RTcl_interp , obj , & count , & elem )
546551 != TCL_OK ) return R_NilValue ;
547-
548- PROTECT (ans = allocVector (VECSXP , count ));
552+ if (count > R_XLEN_T_MAX ) return R_NilValue ;
553+
554+ PROTECT (ans = allocVector (VECSXP , (R_xlen_t ) count ));
549555 for (i = 0 ; i < count ; i ++ ) {
550- el = allocVector (RAWSXP , nb );
556+ el = allocVector (RAWSXP , ( R_xlen_t ) nb );
551557 SET_VECTOR_ELT (ans , i , el );
552558 ret = Tcl_GetByteArrayFromObj (elem [i ], & nb );
553559 for (j = 0 ; j < nb ; j ++ ) RAW (el )[j ] = ret [j ];
0 commit comments