]> Cypherpunks repositories - keks.git/commitdiff
More TAI-related errors checks
authorSergey Matveev <stargrave@stargrave.org>
Thu, 19 Jun 2025 13:29:16 +0000 (16:29 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Thu, 19 Jun 2025 13:31:13 +0000 (16:31 +0300)
c/lib/dectai.c
c/lib/enctai.c
c/lib/leapsecs.c
c/lib/leapsecs.h

index 7da053741cb7029afa733da2f21c4481b6b61e6c1794ec74ef938330d478b778..072e0c56d59dd657c02ebb27e60d2d6cc0cd4467924f9bd635d51a8fd2a2ff91 100644 (file)
 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;
 }
index 7ac2ec18ef3edd4e326b6cdb256e7f8337d491924d77b92aa7994989bbb98029..6e629f62867a2cdb406bdac1a606a2227213d107f9afae104357353f6f69a121 100644 (file)
@@ -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;
index f8aff155a359d974b4e2306ad7550f84ee88180376b0885f8e06ba356129b545..0c49486109cc74e849bd6f739bf76283b928f793fba7a8bf7125cc5c54d818aa 100644 (file)
@@ -1,9 +1,10 @@
+#include <stddef.h>
 #include <stdint.h>
 
 #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
index 2f55f95917abbd2d745d86b231c0500be19e904cd31d84e53afcaee5502871aa..e806b5fd4f38d510874ad422d1510d476e5764ae37c8d69a08bfeb7e0b7f9bad 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef KEKS_LEAPSECS_H
 #define KEKS_LEAPSECS_H
 
+#include <stddef.h>
 #include <stdint.h>
 
 // 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