From 674c1320aaba9dbf53a94b75f385ed8080c532c83f3b12771afa7427308a4b53 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Thu, 19 Jun 2025 16:29:16 +0300 Subject: [PATCH] More TAI-related errors checks --- c/lib/dectai.c | 40 +++++++++++++++++++++++++++++----------- c/lib/enctai.c | 14 +++++++++++--- c/lib/leapsecs.c | 5 +++-- c/lib/leapsecs.h | 5 +++-- 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/c/lib/dectai.c b/c/lib/dectai.c index 7da0537..072e0c5 100644 --- a/c/lib/dectai.c +++ b/c/lib/dectai.c @@ -26,20 +26,34 @@ enum KEKSErr KEKSTAI64ToTimespec(struct timespec *ts, const unsigned char *buf, const size_t len) { - if (len > 12) { + switch (len) { + case 8: + case 12: + break; + case 16: + default: return KEKSErrTAI64BadAsec; } - int64_t v = (int64_t)keksFromBE(buf, 8); + assert(buf != NULL); + int64_t v = 0; + { + uint64_t uv = keksFromBE(buf, 8); + if (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < uv) { + return KEKSErrTAI64TooBig; + } + v = (int64_t)uv; + } v -= 0x4000000000000000; if (v <= 0) { return KEKSErrTAI64InPast; } - if (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < (uint64_t)v) { - return KEKSErrTAI64TooBig; - } + assert(ts != NULL); ts->tv_sec = (time_t)v; if (len > 8) { uint32_t n = (uint32_t)keksFromBE(buf + 8, 4); + if (n >= 1000000000) { + return KEKSErrTAI64BadNsec; + } ts->tv_nsec = n; } return KEKSErrNo; @@ -48,11 +62,15 @@ KEKSTAI64ToTimespec(struct timespec *ts, const unsigned char *buf, const size_t enum KEKSErr KEKSTimespecToUTC(struct timespec *ts) { - int64_t v = (int64_t)(ts->tv_sec); + assert(ts != NULL); + if (ts->tv_sec < 0) { + return KEKSErrTAI64InPast; + } + uint64_t v = (uint64_t)(ts->tv_sec); enum KEKSErr err = KEKSErrNo; { - int64_t diff = 10; - for (int64_t i = 0; i < KEKSLeapsecsN; i++) { + uint64_t diff = 10; + for (size_t i = 0; i < KEKSLeapsecsN; i++) { if (v < KEKSLeapsecs[i]) { break; } @@ -62,11 +80,11 @@ KEKSTimespecToUTC(struct timespec *ts) break; } } + if (diff > v) { + return KEKSErrTAI64InPast; + } v -= diff; } - if (v <= 0) { - return KEKSErrTAI64InPast; - } ts->tv_sec = (time_t)v; return err; } diff --git a/c/lib/enctai.c b/c/lib/enctai.c index 7ac2ec1..6e629f6 100644 --- a/c/lib/enctai.c +++ b/c/lib/enctai.c @@ -33,6 +33,9 @@ KEKSTimespecToTAI64(unsigned char *buf, const struct timespec *ts) assert(buf != NULL); keksToBE(buf, 8, val); if (ts->tv_nsec != 0) { + if (ts->tv_nsec >= 1000000000) { + return false; + } keksToBE(buf + 8, 4, (uint64_t)(ts->tv_nsec)); } return true; @@ -41,13 +44,18 @@ KEKSTimespecToTAI64(unsigned char *buf, const struct timespec *ts) bool KEKSTimespecToTAI(struct timespec *ts) { - int64_t v = 10 + (int64_t)(ts->tv_sec); - for (int64_t i = 0; i < KEKSLeapsecsN; i++) { + assert(ts != NULL); + if (ts->tv_sec < 0) { + return false; + } + uint64_t v = 10 + (uint64_t)(ts->tv_sec); + for (size_t i = 0; i < KEKSLeapsecsN; i++) { if (v >= KEKSLeapsecs[i]) { v++; } } - if (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < (uint64_t)v) { + if ((v < (uint64_t)(ts->tv_sec)) || + (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < v)) { return false; } ts->tv_sec = (time_t)v; diff --git a/c/lib/leapsecs.c b/c/lib/leapsecs.c index f8aff15..0c49486 100644 --- a/c/lib/leapsecs.c +++ b/c/lib/leapsecs.c @@ -1,9 +1,10 @@ +#include #include #include "leapsecs.h" -const int64_t KEKSLeapsecsN = 27; -const int64_t KEKSLeapsecs[] = { +const size_t KEKSLeapsecsN = 27; +const uint64_t KEKSLeapsecs[] = { 78796810, // 1972-07 94694411, // 1973-01 126230412, // 1974-01 diff --git a/c/lib/leapsecs.h b/c/lib/leapsecs.h index 2f55f95..e806b5f 100644 --- a/c/lib/leapsecs.h +++ b/c/lib/leapsecs.h @@ -1,6 +1,7 @@ #ifndef KEKS_LEAPSECS_H #define KEKS_LEAPSECS_H +#include #include // TEXINFO: KEKSLeapsecs @@ -9,7 +10,7 @@ // second was added. @var{KEKSLeapsecsN} variable holds the length of // that list. // @end deftypevar -extern const int64_t KEKSLeapsecsN; -extern const int64_t KEKSLeapsecs[]; +extern const size_t KEKSLeapsecsN; +extern const uint64_t KEKSLeapsecs[]; #endif // KEKS_LEAPSECS_H -- 2.50.0