From b9c9df9825e6d917882c26004edfef7b57d0a11c9b45a44f27c5580d06f2e2f9 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Thu, 21 Nov 2024 12:03:28 +0300 Subject: [PATCH] Fixed TAI64N[A] *seconds validation --- cyac/lib/dec.c | 16 +++++++++------- cyac/lib/err.c | 2 ++ cyac/lib/err.h | 1 + gyac/dec.go | 20 +++++++++++++++----- pyac/pyac.py | 4 ++-- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/cyac/lib/dec.c b/cyac/lib/dec.c index ad1c776..2bdc739 100644 --- a/cyac/lib/dec.c +++ b/cyac/lib/dec.c @@ -241,21 +241,23 @@ YACAtomDecode( // NOLINT(misc-no-recursion) if (v > ((uint64_t)1 << (uint8_t)63)) { return YACErrTAI64TooBig; } - switch (l) { - case 12: + if (l > 8) { v = yacFromBE(buf + 1 + 8, 4); + if ((l == 8) && (v == 0)) { + return YACErrTAI64NonMinimal; + } if (v > 999999999) { return YACErrTAI64BadNsec; } - break; - case 16: + } + if (l > 12) { v = yacFromBE(buf + 1 + 8 + 4, 4); + if (v == 0) { + return YACErrTAI64NonMinimal; + } if (v > 999999999) { return YACErrTAI64BadAsec; } - break; - default: - break; } break; } diff --git a/cyac/lib/err.c b/cyac/lib/err.c index c951942..2eb870b 100644 --- a/cyac/lib/err.c +++ b/cyac/lib/err.c @@ -34,6 +34,8 @@ YACErr2Str(const enum YACErr err) return "TAI64InPast"; case YACErrTAI64IsLeap: return "TAI64IsLeap"; + case YACErrTAI64NonMinimal: + return "TAI64NonMinimal"; case YACErrMapBadKey: return "MapBadKey"; case YACErrMapNoVal: diff --git a/cyac/lib/err.h b/cyac/lib/err.h index 00726a6..55898d7 100644 --- a/cyac/lib/err.h +++ b/cyac/lib/err.h @@ -57,6 +57,7 @@ enum YACErr { YACErrTAI64BadAsec, YACErrTAI64InPast, YACErrTAI64IsLeap, + YACErrTAI64NonMinimal, YACErrMapBadKey, YACErrMapNoVal, YACErrMapUnordered, diff --git a/gyac/dec.go b/gyac/dec.go index 17ba262..7c4d825 100644 --- a/gyac/dec.go +++ b/gyac/dec.go @@ -281,14 +281,24 @@ func AtomDecode(buf []byte) (item *Item, off int, err error) { err = errors.New("reserved TAI64 values in use") return } - switch l { - case 12: - if FromBE(buf[1+8:1+8+4]) > 999999999 { + if l > 8 { + nsecs := FromBE(buf[1+8 : 1+8+4]) + if l == 8 && nsecs == 0 { + err = errors.New("non-minimal TAI64N") + return + } + if nsecs > 999999999 { err = errors.New("too many nanoseconds") return } - case 16: - if FromBE(buf[1+8+4:1+8+4+4]) > 999999999 { + } + if l > 12 { + asecs := FromBE(buf[1+8+4 : 1+8+4+4]) + if asecs == 0 { + err = errors.New("non-minimal TAI64NA") + return + } + if asecs > 999999999 { err = errors.New("too many attoseconds") return } diff --git a/pyac/pyac.py b/pyac/pyac.py index dbdcc69..bac693c 100755 --- a/pyac/pyac.py +++ b/pyac/pyac.py @@ -299,14 +299,14 @@ def loads(v, sets=False, leapsecUTCAllow=False): if l > 8: nsecs = int.from_bytes(v[1+8:1+8+4], "big") if (l == 8) and (nsecs == 0): - raise DecodeError("non-minimal encoding") + raise DecodeError("non-minimal TAI64N") if nsecs > 999999999: raise DecodeError("too many nanoseconds") asecs = 0 if l > 12: asecs = int.from_bytes(v[1+8+4:1+8+4+4], "big") if asecs == 0: - raise DecodeError("non-minimal encoding") + raise DecodeError("non-minimal TAI64NA") if asecs > 999999999: raise DecodeError("too many attoseconds") secs = tai2utc(secs - TAI64Base, leapsecUTCAllow) -- 2.50.0