summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2018-05-29 17:21:09 (GMT)
committersebres <sebres@users.sourceforge.net>2018-05-29 17:21:09 (GMT)
commitda19723bdc4dadba4289f4f357a0891f0950be48 (patch)
tree0e0a8d313d8703ee75c737c4434a873e1cccc82e
parentd1b1eb61ee0797c47516c143c37e76b3dc676a1d (diff)
downloadtcl-da19723bdc4dadba4289f4f357a0891f0950be48.zip
tcl-da19723bdc4dadba4289f4f357a0891f0950be48.tar.gz
tcl-da19723bdc4dadba4289f4f357a0891f0950be48.tar.bz2
first simple validation rules introduced
-rw-r--r--generic/tclClock.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 0074de1..643cf69 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -137,6 +137,9 @@ static int ClockCalcRelTime(
static int ClockAddObjCmd(
ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
+static int ClockValidDate(
+ ClientData, register DateInfo *,
+ register ClockFmtScnCmdArgs *);
static struct tm * ThreadSafeLocalTime(const time_t *);
static size_t TzsetIfNecessary(void);
static void ClockDeleteCmdProc(ClientData);
@@ -3660,6 +3663,13 @@ ClockScanCommit(
}
}
+ /* Apply validation rules, if expected */
+ if ( (opts->flags & CLF_VALIDATE) ) {
+ if (ClockValidDate(clientData, info, opts) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+
/* Local seconds to UTC (stored in yydate.seconds) */
if (info->flags & (CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY)) {
@@ -3685,6 +3695,67 @@ ClockScanCommit(
/*----------------------------------------------------------------------
*
+ * ClockValidDate --
+ *
+ * Validate date info structure for wrong data (e. g. out of ranges).
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ClockValidDate(
+ ClientData clientData, /* Client data containing literal pool */
+ register DateInfo *info, /* Clock scan info structure */
+ register
+ ClockFmtScnCmdArgs *opts) /* Format, locale, timezone and base */
+{
+ const char *errMsg;
+
+ //printf("yyMonth %d, yyDay %d, yyHour %d, yyMinutes %d, yySeconds %d\n", yyMonth, yyDay, yyHour, yyMinutes, yySeconds);
+
+ /* first month (used later in hath) */
+ if ( yyMonth < 1 || yyMonth > 12 ) {
+ errMsg = "invalid month"; goto error;
+ }
+ /* day of month */
+ if ( yyDay < 1 || yyDay > 31 ) {
+ errMsg = "invalid day"; goto error;
+ } else {
+ const int *h = hath[IsGregorianLeapYear(&yydate)];
+ if ( yyDay > h[yyMonth-1] ) {
+ errMsg = "invalid day"; goto error;
+ }
+ }
+ /* hour */
+ if ( yyHour < 0 || yyHour > ((yyMeridian == MER24) ? 24 : 12) ) {
+ errMsg = "invalid time (hour)"; goto error;
+ }
+ /* minutes */
+ if ( yyMinutes < 0 || yyMinutes > 59 ) {
+ errMsg = "invalid time (minutes)"; goto error;
+ }
+ /* oldscan could return secondOfDay (parsedTime) -1 by invalid time (ex.: 25:00:00) */
+ if (yySeconds <= -1) {
+ errMsg = "invalid time"; goto error;
+ }
+
+ return TCL_OK;
+
+ error:
+ Tcl_SetObjResult(opts->interp,
+ Tcl_ObjPrintf("unable to convert input string: %s", errMsg));
+ Tcl_SetErrorCode(opts->interp, "CLOCK", "invInpStr", NULL);
+ return TCL_ERROR;
+}
+
+/*----------------------------------------------------------------------
+ *
* ClockFreeScan --
*
* Used by ClockScanObjCmd for free scanning without format.