Skip to content

Commit

Permalink
fixes overflow for trapv build, now for freescan (overflow in tests c…
Browse files Browse the repository at this point in the history
…lock-6.10e/clock-6.10f): rewritten with common str2int now
  • Loading branch information
sebres committed Mar 24, 2024
1 parent 6af7804 commit e82c68c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 60 deletions.
10 changes: 10 additions & 0 deletions generic/tclClockFmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ _str2wideInt(
return TCL_OK;
}

int
TclAtoWIe(
Tcl_WideInt *out,
const char *p,
const char *e,
int sign)
{
return _str2wideInt(out, p, e, sign);
}

#if defined(__GNUC__) || defined(__GNUG__)
# pragma GCC reset_options
#endif
Expand Down
56 changes: 26 additions & 30 deletions generic/tclDate.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ extern int TclDatedebug;
union YYSTYPE
{

long long Number;
Tcl_WideInt Number;
enum _MERIDIAN Meridian;


Expand Down Expand Up @@ -2534,44 +2534,40 @@ TclDatelex(

if (isdigit(UCHAR(c = *yyInput))) { /* INTL: digit */

/*
* Convert the string into a number; count the number of digits.
/*
* Count the number of digits.
*/
long long num = c - '0';
p = (char *)yyInput;
while (isdigit(UCHAR(c = *(++p)))) {
if (num >= 0) {
num *= 10; num += c - '0';
}
}
yylvalPtr->Number = num;
while (isdigit(UCHAR(*++p))) {};
yyDigitCount = p - yyInput;
/*
* A number with 12 or 14 digits is considered an ISO 8601 date.
*/
if (yyDigitCount == 14 || yyDigitCount == 12) {
/* long form of ISO 8601 (without separator), either
* YYYYMMDDhhmmss or YYYYMMDDhhmm, so reduce to date
* (8 chars is isodate) */
p = (char *)yyInput+8;
if (TclAtoWIe(&yylvalPtr->Number, yyInput, p, 1) != TCL_OK) {
return tID; /* overflow*/
}
yyDigitCount = 8;
yyInput = p;
location->last_column = yyInput - info->dateStart - 1;
return tISOBASL;
}
/*
* Convert the string into a number
*/
if (TclAtoWIe(&yylvalPtr->Number, yyInput, p, 1) != TCL_OK) {
return tID; /* overflow*/
}
yyInput = p;

/*
* A number with 6 or more digits is considered an ISO 8601 base.
*/

location->last_column = yyInput - info->dateStart - 1;
if (yyDigitCount >= 6) {
if (yyDigitCount == 14 || yyDigitCount == 12) {
/* long form of ISO 8601 (without separator), either
* YYYYMMDDhhmmss or YYYYMMDDhhmm, so reduce to date
* (8 chars is isodate) */
p = (char *)tokStart;
num = *p++ - '0';
do {
num *= 10; num += *p++ - '0';
} while (p - tokStart < 8);
yylvalPtr->Number = num;
yyDigitCount = 8;
yyInput = p;
location->last_column = yyInput - info->dateStart - 1;
return tISOBASL;
}
if (yyDigitCount > 14) { /* overflow */
return tID;
}
if (yyDigitCount == 8) {
return tISOBAS8;
}
Expand Down
2 changes: 2 additions & 0 deletions generic/tclDate.h
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,8 @@ MODULE_SCOPE int ClockMCSetIdx(ClockFmtScnCmdArgs *opts, int mcKey,

MODULE_SCOPE char *
TclItoAw(char *buf, int val, char padchar, unsigned short int width);
MODULE_SCOPE int
TclAtoWIe(Tcl_WideInt *out, const char *p, const char *e, int sign);

MODULE_SCOPE Tcl_Obj*
ClockFrmObjGetLocFmtKey(Tcl_Interp *interp,
Expand Down
56 changes: 26 additions & 30 deletions generic/tclGetDate.y
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ typedef enum _DSTMODE {
%}

%union {
long long Number;
Tcl_WideInt Number;
enum _MERIDIAN Meridian;
}

Expand Down Expand Up @@ -904,44 +904,40 @@ TclDatelex(

if (isdigit(UCHAR(c = *yyInput))) { /* INTL: digit */

/*
* Convert the string into a number; count the number of digits.
/*
* Count the number of digits.
*/
long long num = c - '0';
p = (char *)yyInput;
while (isdigit(UCHAR(c = *(++p)))) {
if (num >= 0) {
num *= 10; num += c - '0';
}
}
yylvalPtr->Number = num;
while (isdigit(UCHAR(*++p))) {};
yyDigitCount = p - yyInput;
/*
* A number with 12 or 14 digits is considered an ISO 8601 date.
*/
if (yyDigitCount == 14 || yyDigitCount == 12) {
/* long form of ISO 8601 (without separator), either
* YYYYMMDDhhmmss or YYYYMMDDhhmm, so reduce to date
* (8 chars is isodate) */
p = (char *)yyInput+8;
if (TclAtoWIe(&yylvalPtr->Number, yyInput, p, 1) != TCL_OK) {
return tID; /* overflow*/
}
yyDigitCount = 8;
yyInput = p;
location->last_column = yyInput - info->dateStart - 1;
return tISOBASL;
}
/*
* Convert the string into a number
*/
if (TclAtoWIe(&yylvalPtr->Number, yyInput, p, 1) != TCL_OK) {
return tID; /* overflow*/
}
yyInput = p;

/*
* A number with 6 or more digits is considered an ISO 8601 base.
*/

location->last_column = yyInput - info->dateStart - 1;
if (yyDigitCount >= 6) {
if (yyDigitCount == 14 || yyDigitCount == 12) {
/* long form of ISO 8601 (without separator), either
* YYYYMMDDhhmmss or YYYYMMDDhhmm, so reduce to date
* (8 chars is isodate) */
p = (char *)tokStart;
num = *p++ - '0';
do {
num *= 10; num += *p++ - '0';
} while (p - tokStart < 8);
yylvalPtr->Number = num;
yyDigitCount = 8;
yyInput = p;
location->last_column = yyInput - info->dateStart - 1;
return tISOBASL;
}
if (yyDigitCount > 14) { /* overflow */
return tID;
}
if (yyDigitCount == 8) {
return tISOBAS8;
}
Expand Down

0 comments on commit e82c68c

Please sign in to comment.