From fbb185ab40f77279af0050aef91cbf770c5cf7ec78cf675f0e5347766c0ac10f Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Thu, 19 Jun 2025 16:28:02 +0300 Subject: [PATCH] More assertions against an empty buffers --- c/lib/cm/pub.c | 7 +++++++ c/lib/dec.c | 3 +++ c/lib/dectai.c | 1 + c/lib/enc.c | 23 +++++++++++++++++++++++ c/lib/enctai.c | 3 +++ c/lib/frombe.c | 17 +++++++++++++++++ c/lib/items.c | 15 +++++++++++++++ c/lib/schema.c | 12 ++++++++++++ c/lib/tobe.c | 17 +++++++++++++++++ 9 files changed, 98 insertions(+) diff --git a/c/lib/cm/pub.c b/c/lib/cm/pub.c index 06206b5..25b9601 100644 --- a/c/lib/cm/pub.c +++ b/c/lib/cm/pub.c @@ -20,6 +20,9 @@ KEKSCMPubParse( const unsigned char *buf, const size_t len) { + assert(cer != NULL); + assert(off != NULL); + assert(failReason != NULL); (*failReason) = "unspecified"; struct KEKSItems schema; enum KEKSErr err = KEKSItemsInit(&schema, 512); @@ -105,6 +108,10 @@ KEKSCMPubVerify( const size_t poolLen, const struct KEKSCMPubVerifyOpts opts) { + assert(failReason != NULL); + assert(verifier != NULL); + assert(cer != NULL); + assert(pool != NULL); (*failReason) = "unspecified"; if (opts.t.tv_sec <= cer->since.tv_sec) { (*failReason) = "unsatisfied since"; diff --git a/c/lib/dec.c b/c/lib/dec.c index 408f83e..8df815f 100644 --- a/c/lib/dec.c +++ b/c/lib/dec.c @@ -32,12 +32,15 @@ KEKSAtomDecode( // NOLINT(misc-no-recursion) const unsigned char *buf, const size_t len) { + assert(atom != NULL); + assert(got != NULL); atom->v.str.ptr = NULL; atom->v.str.len = 0; (*got) = 1; if (len < 1) { return KEKSErrNotEnough; } + assert(buf != NULL); unsigned char tag = buf[0]; if ((tag & (uint8_t)KEKSAtomStrings) > 0) { diff --git a/c/lib/dectai.c b/c/lib/dectai.c index b302d53..7da0537 100644 --- a/c/lib/dectai.c +++ b/c/lib/dectai.c @@ -13,6 +13,7 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . +#include #include #include #include diff --git a/c/lib/enc.c b/c/lib/enc.c index 237a152..5d2cabc 100644 --- a/c/lib/enc.c +++ b/c/lib/enc.c @@ -13,6 +13,7 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . +#include #include #include #include @@ -25,10 +26,12 @@ bool KEKSAtomEOCEncode(size_t *len, unsigned char *buf, const size_t cap) { + assert(len != NULL); (*len) = 1; if (cap < 1) { return false; } + assert(buf != NULL); buf[0] = KEKSAtomEOC; return true; } @@ -36,10 +39,12 @@ KEKSAtomEOCEncode(size_t *len, unsigned char *buf, const size_t cap) bool KEKSAtomNILEncode(size_t *len, unsigned char *buf, const size_t cap) { + assert(len != NULL); (*len) = 1; if (cap < 1) { return false; } + assert(buf != NULL); buf[0] = KEKSAtomNIL; return true; } @@ -47,10 +52,12 @@ KEKSAtomNILEncode(size_t *len, unsigned char *buf, const size_t cap) bool KEKSAtomBoolEncode(size_t *len, unsigned char *buf, const size_t cap, const bool v) { + assert(len != NULL); (*len) = 1; if (cap < 1) { return false; } + assert(buf != NULL); buf[0] = v ? KEKSAtomTrue : KEKSAtomFalse; return true; } @@ -62,10 +69,12 @@ KEKSAtomHexletEncode( const size_t cap, const unsigned char v[16]) { + assert(len != NULL); (*len) = 1 + 16; if (cap < (1 + 16)) { return false; } + assert(buf != NULL); buf[0] = KEKSAtomHexlet; memcpy(buf + 1, v, 16); return true; @@ -82,10 +91,12 @@ KEKSAtomMagicEncode( if (vlen > 12) { return false; } + assert(len != NULL); (*len) = 1 + 15; if (cap < (1 + 15)) { return false; } + assert(buf != NULL); buf[0] = 'K'; buf[1] = 'E'; buf[2] = 'K'; @@ -101,6 +112,8 @@ keksAtomIntEncode(size_t *len, unsigned char *buf, const size_t cap, const uint6 if (cap < 1) { return false; } + assert(len != NULL); + assert(buf != NULL); if (v == 0) { const bool ok = KEKSAtomBinEncode(len, buf + 1, cap - 1, (const unsigned char *)"", 0); @@ -148,10 +161,12 @@ KEKSAtomSintEncode(size_t *len, unsigned char *buf, const size_t cap, const int6 bool KEKSAtomListEncode(size_t *len, unsigned char *buf, const size_t cap) { + assert(len != NULL); (*len) = 1; if (cap < 1) { return false; } + assert(buf != NULL); buf[0] = KEKSAtomList; return true; } @@ -159,10 +174,12 @@ KEKSAtomListEncode(size_t *len, unsigned char *buf, const size_t cap) bool KEKSAtomMapEncode(size_t *len, unsigned char *buf, const size_t cap) { + assert(len != NULL); (*len) = 1; if (cap < 1) { return false; } + assert(buf != NULL); buf[0] = KEKSAtomMap; return true; } @@ -174,10 +191,12 @@ KEKSAtomBlobEncode( const size_t cap, const size_t chunkLen) { + assert(len != NULL); (*len) = 1 + 8; if (cap < 1 + 8) { return false; } + assert(buf != NULL); buf[0] = KEKSAtomBlob; keksToBE(buf + 1, 8, (uint64_t)chunkLen - 1); return true; @@ -210,6 +229,7 @@ keksAtomStrEncode( } else { lVal = (unsigned char)srcLen; } + assert(len != NULL); (*len) = 1 + lLen + srcLen; if ((*len) <= srcLen) { (*len) = 0; @@ -218,6 +238,7 @@ keksAtomStrEncode( if (cap < (*len)) { return false; } + assert(buf != NULL); buf[0] = (uint8_t)KEKSAtomStrings | lVal; if (utf8) { buf[0] |= (unsigned char)KEKSAtomIsUTF8; @@ -271,10 +292,12 @@ KEKSAtomTAI64Encode( default: return false; } + assert(len != NULL); (*len) = 1 + srcLen; if (cap < (*len)) { return false; } + assert(buf != NULL); buf[0] = tag; memcpy(buf + 1, src, srcLen); return true; diff --git a/c/lib/enctai.c b/c/lib/enctai.c index f695f25..7ac2ec1 100644 --- a/c/lib/enctai.c +++ b/c/lib/enctai.c @@ -13,6 +13,7 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . +#include #include #include @@ -23,11 +24,13 @@ bool KEKSTimespecToTAI64(unsigned char *buf, const struct timespec *ts) { + assert(ts != NULL); int64_t v = (int64_t)(ts->tv_sec); uint64_t val = (uint64_t)v + 0x4000000000000000; if (val <= (uint64_t)v) { return false; } + assert(buf != NULL); keksToBE(buf, 8, val); if (ts->tv_nsec != 0) { keksToBE(buf + 8, 4, (uint64_t)(ts->tv_nsec)); diff --git a/c/lib/frombe.c b/c/lib/frombe.c index b535b39..efefe2a 100644 --- a/c/lib/frombe.c +++ b/c/lib/frombe.c @@ -1,3 +1,19 @@ +// KEKS -- C99 KEKS encoder implementation +// Copyright (C) 2024-2025 Sergey Matveev +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this program. If not, see . + +#include #include #include @@ -6,6 +22,7 @@ uint64_t keksFromBE(const unsigned char *buf, const size_t len) { + assert(buf != NULL); uint64_t v = 0; switch (len) { case 1: diff --git a/c/lib/items.c b/c/lib/items.c index e0285b9..64ca405 100644 --- a/c/lib/items.c +++ b/c/lib/items.c @@ -30,6 +30,7 @@ static const size_t parseMaxRecursionDepth = 1024; enum KEKSErr KEKSItemsInit(struct KEKSItems *items, const ptrdiff_t initialLen) { + assert(items != NULL); items->len = 0; items->cap = initialLen; items->reallocs = 0; @@ -47,6 +48,7 @@ KEKSItemsInit(struct KEKSItems *items, const ptrdiff_t initialLen) void KEKSItemsNoOffsets(struct KEKSItems *items) { + assert(items != NULL); if (items->offsets == NULL) { return; } @@ -57,6 +59,7 @@ KEKSItemsNoOffsets(struct KEKSItems *items) void KEKSItemsFree(struct KEKSItems *items) { + assert(items != NULL); items->len = 0; items->cap = 0; if (items->list != NULL) { @@ -69,6 +72,7 @@ KEKSItemsFree(struct KEKSItems *items) enum KEKSErr KEKSItemsGrow(struct KEKSItems *items) { + assert(items != NULL); if (items->cap == -1) { return KEKSErrNoMem; } @@ -111,6 +115,9 @@ keksItemsAdd( const unsigned char *buf, const size_t len) { + assert(items != NULL); + assert(off != NULL); + assert(buf != NULL); enum KEKSErr err = KEKSErrInvalid; if (items->len == (size_t)(items->cap)) { err = KEKSItemsGrow(items); @@ -146,6 +153,9 @@ keksItemsParse( // NOLINT(misc-no-recursion) const bool allowContainers, const size_t recursionDepth) { + assert(items != NULL); + assert(off != NULL); + assert(buf != NULL); if (recursionDepth >= parseMaxRecursionDepth) { return KEKSErrDeepRecursion; } @@ -312,6 +322,9 @@ KEKSItemsEncode( // NOLINT(misc-no-recursion) unsigned char *buf, const size_t cap) { + assert(items != NULL); + assert(off != NULL); + assert(buf != NULL); const struct KEKSItem *item = &(items->list[idx]); size_t got = 0; bool ok = false; @@ -460,6 +473,7 @@ KEKSItemsGetByKeyLen( const char *key, const size_t keyLen) { + assert(items != NULL); const struct KEKSItem *item = &(items->list[itemIdx]); if (item->atom.typ != KEKSItemMap) { return 0; @@ -485,6 +499,7 @@ KEKSItemsGetByKey(const struct KEKSItems *items, const size_t itemIdx, const cha bool KEKSStrEqual(const struct KEKSAtom *atom, const char *s) { + assert(atom != NULL); return (atom->v.str.len == strlen(s)) && (memcmp(atom->v.str.ptr, s, atom->v.str.len) == 0); } diff --git a/c/lib/schema.c b/c/lib/schema.c index bfe5734..5b2474c 100644 --- a/c/lib/schema.c +++ b/c/lib/schema.c @@ -13,6 +13,7 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . +#include #include #include #include @@ -69,6 +70,10 @@ keksSchemaLens( size_t idxSchema, size_t idxData) { + assert(our != NULL); + assert(their != NULL); + assert(schema != NULL); + assert(data != NULL); switch (schema->list[idxSchema].atom.typ) { case KEKSItemPint: (*our) = (int64_t)(schema->list[idxSchema].atom.v.pint); @@ -150,6 +155,11 @@ keksSchemaCmd( // NOLINT(misc-no-recursion) size_t idxSchema, size_t idxData) { + assert(taken != NULL); + assert(eachInList != NULL); + assert(eachInMap != NULL); + assert(schema != NULL); + assert(data != NULL); size_t origIdxSchema = idxSchema; struct KEKSSchemaErr err; size_t v = *taken; @@ -629,6 +639,8 @@ KEKSSchemaValidate( // NOLINT(misc-no-recursion) size_t idxSchema, size_t idxData) { + assert(schema != NULL); + assert(data != NULL); struct KEKSSchemaErr err = (struct KEKSSchemaErr){ .offSchema = schema->offsets[idxSchema], .offData = data->offsets[idxData], diff --git a/c/lib/tobe.c b/c/lib/tobe.c index d079e2a..7ff337a 100644 --- a/c/lib/tobe.c +++ b/c/lib/tobe.c @@ -1,3 +1,19 @@ +// KEKS -- C99 KEKS encoder implementation +// Copyright (C) 2024-2025 Sergey Matveev +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this program. If not, see . + +#include #include #include @@ -6,6 +22,7 @@ void keksToBE(unsigned char *buf, const size_t len, const uint64_t v) { + assert(buf != NULL); switch (len) { case 1: buf[0] = (v & (uint64_t)0x00000000000000FF); -- 2.50.0