From: Sergey Matveev Date: Wed, 16 Oct 2024 14:06:55 +0000 (+0300) Subject: Unify size types and check overflows X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f889e4e20edf93ba386a70634e048370b560e757080046fb81c708067ae30ae3;p=keks.git Unify size types and check overflows --- diff --git a/cyac/cmd/cer-verify/cer-verify.c b/cyac/cmd/cer-verify/cer-verify.c index 8c4018d..07ac5d0 100644 --- a/cyac/cmd/cer-verify/cer-verify.c +++ b/cyac/cmd/cer-verify/cer-verify.c @@ -15,13 +15,13 @@ #include #include -#include #include #include #include -#include +#include #include +#include #include #include "../lib/mmap.h" @@ -36,20 +36,19 @@ main(int argc, char **argv) fprintf(stderr, "Usage: %s EE.cer [CA.cer ...]\n", argv[0]); return EXIT_FAILURE; } - const ptrdiff_t cersLen = (ptrdiff_t)argc - 1; - struct YACCer *cers = calloc((size_t)cersLen, sizeof(struct YACCer)); + const size_t cersLen = (size_t)argc - 1; + struct YACCer *cers = calloc(cersLen, sizeof(struct YACCer)); assert(cers != NULL); char *failReason = NULL; for (int i = 1; i < argc; i++) { unsigned char *buf = NULL; size_t len = 0; if (!Mmap(&buf, &len, argv[i])) { - fprintf(stderr, "%s\n", strerror(errno)); exit(EXIT_FAILURE); } fputs(argv[i], stdout); fputs(":\t", stdout); - ptrdiff_t off = 0; + size_t off = 0; enum YACErr err = YACCerParse(&(cers[i - 1]), &off, &failReason, buf, len); if (err != YACErrNo) { fprintf(stderr, "%s\n", failReason); @@ -64,8 +63,9 @@ main(int argc, char **argv) fputs("\n", stdout); } - struct timeval now; - if (gettimeofday(&now, NULL) != 0) { + struct timespec now; + errno = 0; + if (clock_gettime(CLOCK_REALTIME, &now) != 0) { fprintf(stderr, "%s\n", strerror(errno)); return EXIT_FAILURE; } @@ -94,8 +94,8 @@ main(int argc, char **argv) break; } { - ptrdiff_t ku = YACItemsGetByKey(&(verifier->items), verifier->load, "ku"); - if ((ku == -1) || YACItemsGetByKey(&(verifier->items), ku, "ca") == -1) { + size_t ku = YACItemsGetByKey(&(verifier->items), verifier->load, "ku"); + if ((ku == 0) || YACItemsGetByKey(&(verifier->items), ku, "ca") == 0) { fputs("no ca ku\n", stdout); return EXIT_FAILURE; } diff --git a/cyac/cmd/lib/mmap.c b/cyac/cmd/lib/mmap.c index 9a0c8ce..45f4b93 100644 --- a/cyac/cmd/lib/mmap.c +++ b/cyac/cmd/lib/mmap.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -21,6 +22,11 @@ Mmap(unsigned char **buf, size_t *len, const char *path) return false; } (*len) = (size_t)sb.st_size; + errno = 0; (*buf) = mmap(NULL, *len, PROT_READ, MAP_SHARED, fd, 0); + if ((*buf) == MAP_FAILED) { + fprintf(stderr, "mmap: %s\n", strerror(errno)); + return false; + } return true; } diff --git a/cyac/cmd/lib/printai.c b/cyac/cmd/lib/printai.c new file mode 100644 index 0000000..f762889 --- /dev/null +++ b/cyac/cmd/lib/printai.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include +#include + +#include "hex.h" +#include "printai.h" + +enum YACErr +PrintTAI64(const unsigned char *buf, const size_t len) +{ + char *hex = NULL; + if (len == 16) { + hex = HexEnc(buf, len); + fprintf(stdout, "TAI64NA(%s)\n", hex); + free(hex); + return YACErrNo; + } + switch (len) { + case 8: + fputs("TAI64(", stdout); + break; + case 12: + fputs("TAI64N(", stdout); + break; + } + struct timespec tv; + enum YACErr err = YACTAI64ToTimespec(&tv, buf, len); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wswitch-enum" + switch (err) { +#pragma clang diagnostic pop + case YACErrNo: + break; + case YACErrTAI64InPast: + hex = HexEnc(buf, len); + fprintf(stdout, "in past: %s)\n", hex); + free(hex); + return YACErrNo; + default: + return err; + } + time_t t = tv.tv_sec; + struct tm *tm = localtime(&t); + if (tm == NULL) { + hex = HexEnc(buf, len); + fprintf(stdout, "unrepresentable: %s)\n", hex); + free(hex); + return YACErrNo; + } + { + char human[20] = {0}; + strftime(human, sizeof human, "%Y-%m-%d %H:%M:%S", tm); + fputs(human, stdout); + } + if (len == 12) { + fprintf(stdout, ".%09zu", tv.tv_nsec); + } + fputs(")\n", stdout); + return YACErrNo; +} diff --git a/cyac/cmd/lib/printai.h b/cyac/cmd/lib/printai.h new file mode 100644 index 0000000..c408b4d --- /dev/null +++ b/cyac/cmd/lib/printai.h @@ -0,0 +1,11 @@ +#ifndef YAC_PRINTAI_H +#define YAC_PRINTAI_H + +#include + +#include + +enum YACErr +PrintTAI64(const unsigned char *buf, const size_t len); + +#endif // YAC_PRINTAI_H diff --git a/cyac/cmd/lib/printai.o.do b/cyac/cmd/lib/printai.o.do new file mode 100644 index 0000000..4d571c2 --- /dev/null +++ b/cyac/cmd/lib/printai.o.do @@ -0,0 +1,5 @@ +redo-ifchange ${1%.o}.c ../../conf/cc ../../conf/cflags ../../conf/prefix +read CC <../../conf/cc +CFLAGS=$(cat ../../conf/cflags) +read PREFIX <../../conf/prefix +$CC $CFLAGS -I$PREFIX/include -c -o $3 ${1%.o}.c diff --git a/cyac/cmd/print-items/print-items.c b/cyac/cmd/print-items/print-items.c index 38efb7c..a24c043 100644 --- a/cyac/cmd/print-items/print-items.c +++ b/cyac/cmd/print-items/print-items.c @@ -14,23 +14,19 @@ // License along with this program. If not, see . #include -#include #include #include -#include #include #include #include -#include -#include #include -#include #include #include #include "../lib/hex.h" #include "../lib/mmap.h" +#include "../lib/printai.h" #include "../lib/uuid.h" static const size_t maxStrLen = 40; @@ -45,9 +41,9 @@ static const char *ColourWhite = "\x1b[37m"; static const char *ColourReset = "\x1b[0m"; static void -printIndent(const ptrdiff_t indent) +printIndent(const size_t indent) { - for (ptrdiff_t i = 0; i < indent; i++) { + for (size_t i = 0; i < indent; i++) { fputs(" ", stdout); } } @@ -59,9 +55,10 @@ static char OffFmt[16] = {0}; static enum YACErr printer( const struct YACItems *items, - ptrdiff_t idx, - ptrdiff_t indent, - ptrdiff_t listIdx, + size_t idx, + size_t indent, + const bool inList, + size_t listIdx, const char *mapKey) { printf("%s%zd%s ", NoColour ? "" : ColourBlue, indent, NoColour ? "" : ColourReset); @@ -72,7 +69,7 @@ printer( assert(indent >= 0); } printIndent(indent); - if (listIdx >= 0) { + if (inList) { fprintf( stdout, "%s%zu:%s ", @@ -119,8 +116,8 @@ printer( indent++; idx = item->atom.v.list.head; listIdx = 0; - while (idx != -1) { - err = printer(items, idx, indent, listIdx, NULL); + while (idx != 0) { + err = printer(items, idx, indent, true, listIdx, NULL); if (err != YACErrNo) { return err; } @@ -143,12 +140,12 @@ printer( NoColour ? "" : ColourReset); indent++; idx = item->atom.v.list.head; - while (idx != -1) { + while (idx != 0) { str = strndup( (const char *)(items->list[idx].atom.v.str.ptr), items->list[idx].atom.v.str.len); idx = items->list[idx].next; - err = printer(items, idx, indent, -1, str); + err = printer(items, idx, indent, false, 0, str); free(str); if (err != YACErrNo) { return err; @@ -173,8 +170,8 @@ printer( indent++; idx++; listIdx = 0; - while (idx != -1) { - err = printer(items, idx, indent, listIdx, NULL); + while (idx != 0) { + err = printer(items, idx, indent, true, listIdx, NULL); if (err != YACErrNo) { return err; } @@ -192,46 +189,10 @@ printer( fputs("FLOAT: TODO\n", stdout); break; case YACItemTAI64: { - if ((item->atom.v.str.len) == 16) { - str = HexEnc(item->atom.v.str.ptr, item->atom.v.str.len); - fprintf(stdout, "TAI64NA(%s)\n", str); - free(str); - break; - } - switch (item->atom.v.str.len) { - case 8: - fputs("TAI64(", stdout); - break; - case 12: - fputs("TAI64N(", stdout); - break; - } - struct timeval tv; - err = YACTAI64ToTimeval(&tv, item->atom.v.str.ptr, item->atom.v.str.len); - if (err == YACErrTAI64BadNsec) { - str = HexEnc(item->atom.v.str.ptr, item->atom.v.str.len); - fprintf(stdout, "unrepresentable: %s)\n", str); - free(str); - break; - } + err = PrintTAI64(item->atom.v.str.ptr, item->atom.v.str.len); if (err != YACErrNo) { return err; } - time_t t = tv.tv_sec; - struct tm *tm = localtime(&t); - if (tm == NULL) { - str = HexEnc(item->atom.v.str.ptr, item->atom.v.str.len); - fprintf(stdout, "unrepresentable: %s)\n", str); - free(str); - break; - } - char human[20] = {0}; - strftime(human, sizeof human, "%Y-%m-%d %H:%M:%S", tm); - fputs(human, stdout); - if ((item->atom.v.str.len) == 12) { - fprintf(stdout, ".%zu", tv.tv_usec); - } - fputs(")\n", stdout); break; } case YACItemBin: { @@ -278,27 +239,33 @@ main(int argc, char **argv) size_t len = 0; unsigned char *buf = NULL; if (!Mmap(&buf, &len, argv[1])) { - fprintf(stderr, "%s\n", strerror(errno)); exit(EXIT_FAILURE); } - NoColour = getenv("NO_COLOR") != NULL; - OffDigits = (int)(1 + floor(log10((double)len))); snprintf(OffFmt, sizeof OffFmt, "%%s%%0%dzd%%s ", OffDigits); struct YACItems items; YACItemsInit(&items); - ptrdiff_t off = 0; + size_t off = 0; enum YACErr err = YACItemsParse(&items, &off, buf, len); if (err != YACErrNo) { fprintf(stderr, "err: %s\n", YACErr2Str(err)); return EXIT_FAILURE; } - err = printer(&items, 0, 0, -1, NULL); + err = printer(&items, 0, 0, false, 0, NULL); if (err != YACErrNo) { fprintf(stderr, "err: %s\n", YACErr2Str(err)); return EXIT_FAILURE; } + printf("items: %zu size: %zu\n", items.len, items.len * sizeof(struct YACItem)); + if (getenv("DO_ENCODE") != NULL) { + unsigned char *dst = malloc(len); + assert(dst != NULL); + off = 0; + assert(YACItemsEncode(&items, 0, &off, dst, len)); + assert(off == len); + assert(memcmp(dst, buf, len) == 0); + } return EXIT_SUCCESS; } diff --git a/cyac/cmd/print-items/print-items.do b/cyac/cmd/print-items/print-items.do index c735e34..7a01e52 100644 --- a/cyac/cmd/print-items/print-items.do +++ b/cyac/cmd/print-items/print-items.do @@ -1,4 +1,4 @@ -deps="../lib/hex.o ../lib/mmap.o ../lib/uuid.o" +deps="../lib/hex.o ../lib/mmap.o ../lib/printai.o ../lib/uuid.o" redo-ifchange $1.c $deps \ ../../conf/cc ../../conf/cflags ../../conf/ldflags ../../conf/prefix read CC <../../conf/cc diff --git a/cyac/cmd/print-itered/print-itered.c b/cyac/cmd/print-itered/print-itered.c index 1740c1e..ed2758b 100644 --- a/cyac/cmd/print-itered/print-itered.c +++ b/cyac/cmd/print-itered/print-itered.c @@ -14,37 +14,35 @@ // License along with this program. If not, see . #include -#include -#include +#include #include #include #include -#include -#include #include -#include #include #include #include "../lib/hex.h" #include "../lib/mmap.h" +#include "../lib/printai.h" #include "../lib/uuid.h" static const size_t maxStrLen = 40; struct CbState { - ptrdiff_t indent; + int indent; }; static enum YACErr myCb( const unsigned char *key, const size_t keyLen, - const ptrdiff_t idx, + const bool inList, + const size_t idx, void *cbState, struct YACAtom *atom, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len) { @@ -53,14 +51,14 @@ myCb( state->indent--; assert(state->indent >= 0); } - printf("%04zd ", *off); - for (ptrdiff_t i = 0; i < state->indent; i++) { + printf("%04zu ", *off); + for (int i = 0; i < state->indent; i++) { fputs(" ", stdout); } if (key != NULL) { fwrite(key, keyLen, 1, stdout); fputs(": ", stdout); - } else if (idx > -1) { + } else if (inList) { fprintf(stdout, "%zu: ", idx); } @@ -119,46 +117,10 @@ myCb( fputs("FLOAT: TODO\n", stdout); break; case YACItemTAI64: - if ((atom->v.str.len) == 16) { - hex = HexEnc(atom->v.str.ptr, atom->v.str.len); - fprintf(stdout, "TAI64NA(%s)\n", hex); - free(hex); - break; - } - switch (atom->v.str.len) { - case 8: - fputs("TAI64(", stdout); - break; - case 12: - fputs("TAI64N(", stdout); - break; - } - struct timeval tv; - err = YACTAI64ToTimeval(&tv, atom->v.str.ptr, atom->v.str.len); - if (err == YACErrTAI64BadNsec) { - hex = HexEnc(atom->v.str.ptr, atom->v.str.len); - fprintf(stdout, "unrepresentable: %s)\n", hex); - free(hex); - break; - } + err = PrintTAI64(atom->v.str.ptr, atom->v.str.len); if (err != YACErrNo) { return err; } - time_t t = tv.tv_sec; - struct tm *tm = localtime(&t); - if (tm == NULL) { - hex = HexEnc(atom->v.str.ptr, atom->v.str.len); - fprintf(stdout, "unrepresentable: %s)\n", hex); - free(hex); - break; - } - char human[20] = {0}; - strftime(human, sizeof human, "%Y-%m-%d %H:%M:%S", tm); - fputs(human, stdout); - if ((atom->v.str.len) == 12) { - fprintf(stdout, ".%zu", tv.tv_usec); - } - fputs(")\n", stdout); break; case YACItemBin: { const size_t l = (atom->v.str.len > maxStrLen) ? maxStrLen : atom->v.str.len; @@ -197,20 +159,20 @@ main(int argc, char **argv) size_t len = 0; unsigned char *buf = NULL; if (!Mmap(&buf, &len, argv[1])) { - fprintf(stderr, "%s\n", strerror(errno)); exit(EXIT_FAILURE); } struct YACAtom atom; memset(&atom, 0, sizeof(struct YACAtom)); - ptrdiff_t off = 0; - struct YACErrAndLen errLen = YACAtomDecode(&atom, buf, len); - if (errLen.err != YACErrNo) { - fprintf(stderr, "err: %s\n", YACErr2Str(errLen.err)); + size_t off = 0; + size_t got = 0; + enum YACErr err = YACAtomDecode(&got, &atom, buf, len); + if (err != YACErrNo) { + fprintf(stderr, "err: %s\n", YACErr2Str(err)); return EXIT_FAILURE; } - off += errLen.len; + off += got; struct CbState cbState = {.indent = 0}; - enum YACErr err = myCb(NULL, 0, -1, &cbState, &atom, &off, buf, len); + err = myCb(NULL, 0, false, 0, &cbState, &atom, &off, buf, len); if (err != YACErrNo) { fprintf(stderr, "err: %s\n", YACErr2Str(err)); return EXIT_FAILURE; diff --git a/cyac/cmd/print-itered/print-itered.do b/cyac/cmd/print-itered/print-itered.do index 3fdc613..9f9b1e3 100644 --- a/cyac/cmd/print-itered/print-itered.do +++ b/cyac/cmd/print-itered/print-itered.do @@ -1,4 +1,4 @@ -deps="../lib/hex.o ../lib/mmap.o ../lib/uuid.o" +deps="../lib/hex.o ../lib/mmap.o ../lib/printai.o ../lib/uuid.o" redo-ifchange $1.c $deps \ ../../conf/cc ../../conf/cflags ../../conf/ldflags ../../conf/prefix read CC <../../conf/cc diff --git a/cyac/cmd/test-vector/test-vector.c b/cyac/cmd/test-vector/test-vector.c index c30329e..3e54054 100644 --- a/cyac/cmd/test-vector/test-vector.c +++ b/cyac/cmd/test-vector/test-vector.c @@ -1,20 +1,22 @@ #include #include -#include #include #include -#include +#include #include #include #include #include +static size_t Off = 0; +static size_t Got = 0; + static void -adder(size_t *off, const ptrdiff_t add) +adder(const bool ok) { - assert(add > 0); - (*off) += (size_t)add; + assert(ok); + Off += Got; } int @@ -25,211 +27,195 @@ main(int argc, char **argv) assert(buf != NULL); unsigned char *bin = malloc(1 << 16); assert(bin != NULL); - size_t off = 0; - adder(&off, YACAtomMapEncode(buf + off, len - off)); // . + adder(YACAtomMapEncode(&Got, buf + Off, len - Off)); // . adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"nil", 3)); - adder(&off, YACAtomNILEncode(buf + off, len - off)); + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"nil", 3)); + adder(YACAtomNILEncode(&Got, buf + Off, len - Off)); adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"str", 3)); - adder(&off, YACAtomMapEncode(buf + off, len - off)); // .str + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"str", 3)); + adder(YACAtomMapEncode(&Got, buf + Off, len - Off)); // .str adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"bin", 3)); - adder(&off, YACAtomListEncode(buf + off, len - off)); // .str.bin - adder(&off, YACAtomBinEncode(buf + off, len - off, (const unsigned char *)"", 0)); + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"bin", 3)); + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .str.bin + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, (const unsigned char *)"", 0)); memset(bin, '0', 60); - adder(&off, YACAtomBinEncode(buf + off, len - off, bin, 60)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 60)); memset(bin, '1', 61); - adder(&off, YACAtomBinEncode(buf + off, len - off, bin, 61)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 61)); memset(bin, '2', 255); - adder(&off, YACAtomBinEncode(buf + off, len - off, bin, 255)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 255)); memset(bin, '3', 1024); - adder(&off, YACAtomBinEncode(buf + off, len - off, bin, 1024)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 1024)); memset(bin, '4', 1 << 16); - adder(&off, YACAtomBinEncode(buf + off, len - off, bin, 1 << 16)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .str.bin + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 1 << 16)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .str.bin adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"utf8", 4)); - adder( - &off, - YACAtomStrEncode( - buf + off, len - off, (const unsigned char *)"привет мир", 19)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .str + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"utf8", 4)); + adder(YACAtomStrEncode( + &Got, buf + Off, len - Off, (const unsigned char *)"привет мир", 19)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .str adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"blob", 4)); - adder(&off, YACAtomListEncode(buf + off, len - off)); // .blob + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"blob", 4)); + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .blob - adder(&off, YACAtomBlobEncode(buf + off, len - off, 12)); // .blob.0 + adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.0 memset(bin, '5', 1); - adder(&off, YACAtomBinEncode(buf + off, len - off, bin, 1)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 1)); - adder(&off, YACAtomBlobEncode(buf + off, len - off, 12)); // .blob.1 + adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.1 memset(bin, '6', 12); - adder(&off, YACAtomChunkEncode(buf + off, len - off, bin, 12)); - adder(&off, YACAtomBinEncode(buf + off, len - off, NULL, 0)); + adder(YACAtomChunkEncode(&Got, buf + Off, len - Off, bin, 12)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, NULL, 0)); - adder(&off, YACAtomBlobEncode(buf + off, len - off, 12)); // .blob.2 + adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.2 memset(bin, '7', 12); - adder(&off, YACAtomChunkEncode(buf + off, len - off, bin, 12)); - adder(&off, YACAtomBinEncode(buf + off, len - off, bin, 1)); - - adder(&off, YACAtomBlobEncode(buf + off, len - off, 5)); // .blob.3 - adder( - &off, - YACAtomChunkEncode(buf + off, len - off, (const unsigned char *)"12345", 5)); - adder( - &off, - YACAtomChunkEncode(buf + off, len - off, (const unsigned char *)"67890", 5)); - adder(&off, YACAtomBinEncode(buf + off, len - off, (const unsigned char *)"-", 1)); - - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .blob - - adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"bool", 4)); - adder(&off, YACAtomListEncode(buf + off, len - off)); // .bool - adder(&off, YACAtomBoolEncode(buf + off, len - off, true)); - adder(&off, YACAtomBoolEncode(buf + off, len - off, false)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .bool - - adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"ints", 4)); - adder(&off, YACAtomMapEncode(buf + off, len - off)); // .ints - - adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"neg", 3)); - adder(&off, YACAtomListEncode(buf + off, len - off)); // .ints.neg - adder(&off, YACAtomSintEncode(buf + off, len - off, -1)); - adder(&off, YACAtomSintEncode(buf + off, len - off, -2)); - adder(&off, YACAtomSintEncode(buf + off, len - off, -32)); - adder(&off, YACAtomSintEncode(buf + off, len - off, -33)); - adder(&off, YACAtomSintEncode(buf + off, len - off, -123)); - adder(&off, YACAtomSintEncode(buf + off, len - off, -1234)); - adder(&off, YACAtomSintEncode(buf + off, len - off, -12345678)); - adder( - &off, - YACAtomRawEncode( - buf + off, - len - off, - YACAtomIntNeg10, - (const unsigned char *)"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", - 10)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .ints.neg - - adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"pos", 3)); - adder(&off, YACAtomListEncode(buf + off, len - off)); // .ints.pos - adder(&off, YACAtomUintEncode(buf + off, len - off, 0)); - adder(&off, YACAtomUintEncode(buf + off, len - off, 1)); - adder(&off, YACAtomUintEncode(buf + off, len - off, 31)); - adder(&off, YACAtomUintEncode(buf + off, len - off, 32)); - adder(&off, YACAtomUintEncode(buf + off, len - off, 123)); - adder(&off, YACAtomUintEncode(buf + off, len - off, 1234)); - adder(&off, YACAtomUintEncode(buf + off, len - off, 12345678)); - adder( - &off, - YACAtomRawEncode( - buf + off, - len - off, - YACAtomIntPos11, - (const unsigned char *)"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", - 11)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .ints.pos - - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .ints - - adder( - &off, YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"uuid", 4)); - adder( - &off, - YACAtomUUIDEncode( - buf + off, - len - off, - (const unsigned char - *)"\x0e\x87\x5e\x3f\xd3\x85\x49\xeb\x87\xb4\xbe\x42\xd6\x41\xc3\x67")); - - adder( - &off, - YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"dates", 5)); - adder(&off, YACAtomListEncode(buf + off, len - off)); // .dates + adder(YACAtomChunkEncode(&Got, buf + Off, len - Off, bin, 12)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 1)); + + adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 5)); // .blob.3 + adder(YACAtomChunkEncode( + &Got, buf + Off, len - Off, (const unsigned char *)"12345", 5)); + adder(YACAtomChunkEncode( + &Got, buf + Off, len - Off, (const unsigned char *)"67890", 5)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, (const unsigned char *)"-", 1)); + + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .blob + + adder( + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"bool", 4)); + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .bool + adder(YACAtomBoolEncode(&Got, buf + Off, len - Off, true)); + adder(YACAtomBoolEncode(&Got, buf + Off, len - Off, false)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .bool + + adder( + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"ints", 4)); + adder(YACAtomMapEncode(&Got, buf + Off, len - Off)); // .ints + + adder( + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"neg", 3)); + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .ints.neg + adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -1)); + adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -2)); + adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -32)); + adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -33)); + adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -123)); + adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -1234)); + adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -12345678)); + adder(YACAtomRawEncode( + &Got, + buf + Off, + len - Off, + YACAtomIntNeg10, + (const unsigned char *)"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", + 10)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints.neg + + adder( + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"pos", 3)); + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .ints.pos + adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 0)); + adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 1)); + adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 31)); + adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 32)); + adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 123)); + adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 1234)); + adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 12345678)); + adder(YACAtomRawEncode( + &Got, + buf + Off, + len - Off, + YACAtomIntPos11, + (const unsigned char *)"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + 11)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints.pos + + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints + + adder( + YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"uuid", 4)); + adder(YACAtomUUIDEncode( + &Got, + buf + Off, + len - Off, + (const unsigned char + *)"\x0e\x87\x5e\x3f\xd3\x85\x49\xeb\x87\xb4\xbe\x42\xd6\x41\xc3\x67")); + + adder(YACAtomStrEncode( + &Got, buf + Off, len - Off, (const unsigned char *)"dates", 5)); + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .dates { - struct timeval tv; + struct timespec tv; tv.tv_sec = 1234567890; unsigned char tai[12] = {0}; - YACTimevalToTAI64(tai, &tv); - adder(&off, YACAtomTAI64Encode(buf + off, len - off, tai, 8)); - - tv.tv_usec = 456; - YACTimevalToTAI64(tai, &tv); - adder(&off, YACAtomTAI64Encode(buf + off, len - off, tai, 12)); - - adder( - &off, - YACAtomRawEncode( - buf + off, - len - off, - YACAtomTAI64N, - (const unsigned char - *)"\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55", - 12)); - - adder( - &off, - YACAtomRawEncode( - buf + off, - len - off, - YACAtomTAI64NA, - (const unsigned char - *)"\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55\x07\x5B\xCD\x15", - 16)); + assert(YACTimespecToTAI64(tai, &tv)); + adder(YACAtomTAI64Encode(&Got, buf + Off, len - Off, tai, 8)); + + tv.tv_nsec = 456000; + assert(YACTimespecToTAI64(tai, &tv)); + adder(YACAtomTAI64Encode(&Got, buf + Off, len - Off, tai, 12)); + + adder(YACAtomRawEncode( + &Got, + buf + Off, + len - Off, + YACAtomTAI64N, + (const unsigned char *)"\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55", + 12)); + + adder(YACAtomRawEncode( + &Got, + buf + Off, + len - Off, + YACAtomTAI64NA, + (const unsigned char + *)"\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55\x07\x5B\xCD\x15", + 16)); } - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .dates - - adder( - &off, - YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"floats", 6)); - adder(&off, YACAtomListEncode(buf + off, len - off)); // .floats - adder( - &off, - YACAtomRawEncode( - buf + off, - len - off, - YACAtomFloat32, - (const unsigned char *)"\x01\x02\x03\x04", - 4)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .floats - - adder( - &off, - YACAtomStrEncode(buf + off, len - off, (const unsigned char *)"empties", 7)); - adder(&off, YACAtomListEncode(buf + off, len - off)); // .empties - adder(&off, YACAtomListEncode(buf + off, len - off)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); - adder(&off, YACAtomMapEncode(buf + off, len - off)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); - adder(&off, YACAtomBlobEncode(buf + off, len - off, 123)); - adder(&off, YACAtomBinEncode(buf + off, len - off, NULL, 0)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .dates + + adder(YACAtomStrEncode( + &Got, buf + Off, len - Off, (const unsigned char *)"floats", 6)); + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .floats + adder(YACAtomRawEncode( + &Got, + buf + Off, + len - Off, + YACAtomFloat32, + (const unsigned char *)"\x01\x02\x03\x04", + 4)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .floats + + adder(YACAtomStrEncode( + &Got, buf + Off, len - Off, (const unsigned char *)"empties", 7)); + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .empties + adder(YACAtomListEncode(&Got, buf + Off, len - Off)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); + adder(YACAtomMapEncode(&Got, buf + Off, len - Off)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); + adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 123)); + adder(YACAtomBinEncode(&Got, buf + Off, len - Off, NULL, 0)); memset(bin, '\x00', 16); - adder(&off, YACAtomUUIDEncode(buf + off, len - off, bin)); - adder( - &off, - YACAtomRawEncode( - buf + off, - len - off, - YACAtomTAI64, - (const unsigned char *)"\x00\x00\x00\x00\x00\x00\x00\x00", - 8)); - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // .empties - - adder(&off, YACAtomEOCEncode(buf + off, len - off)); // . + adder(YACAtomUUIDEncode(&Got, buf + Off, len - Off, bin)); + adder(YACAtomRawEncode( + &Got, + buf + Off, + len - Off, + YACAtomTAI64, + (const unsigned char *)"\x00\x00\x00\x00\x00\x00\x00\x00", + 8)); + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .empties + + adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // . free(bin); - assert(write(STDOUT_FILENO, buf, off) == (ssize_t)off); + assert(write(STDOUT_FILENO, buf, Off) == (ssize_t)Off); free(buf); return EXIT_SUCCESS; diff --git a/cyac/lib/dec.c b/cyac/lib/dec.c index 73f5715..588744a 100644 --- a/cyac/lib/dec.c +++ b/cyac/lib/dec.c @@ -22,21 +22,24 @@ #include "frombe.h" #include "utf8.h" -struct YACErrAndLen -YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len) +enum YACErr +YACAtomDecode( + size_t *got, + struct YACAtom *atom, + const unsigned char *buf, + const size_t len) { atom->v.str.ptr = NULL; atom->v.str.len = 0; - struct YACErrAndLen ret = {.err = YACErrInvalid, .len = 1}; + (*got) = 1; if (len < 1) { - ret.err = YACErrNotEnough; - return ret; + return YACErrNotEnough; } atom->tag = buf[0]; if ((atom->tag & YACAtomStrings) > 0) { atom->typ = ((atom->tag & YACAtomIsUTF8) == 0) ? YACItemBin : YACItemStr; - size_t l = atom->tag & 63; + uint64_t l = atom->tag & 63; size_t ll = 0; switch (l) { case 61: @@ -50,56 +53,55 @@ YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len) break; } if (ll != 0) { - ret.len += ll; - if ((ptrdiff_t)len < ret.len) { - ret.err = YACErrNotEnough; - return ret; + (*got) += ll; + if (len < (*got)) { + return YACErrNotEnough; } l = yacFromBE(buf + 1, ll); if ((l < 61) || ((l < (1 << 8)) && (ll > 1)) || ((l < (1 << 16)) && (ll > 2))) { - ret.err = YACErrLenNonMinimal; - return ret; - } - if (l > ((uint64_t)(1) << 60)) { - ret.err = YACErrLenTooBig; - return ret; + return YACErrLenNonMinimal; } } - ret.len += l; - if ((ptrdiff_t)len < ret.len) { - ret.err = YACErrNotEnough; - return ret; + if (l > SIZE_MAX) { + return YACErrLenTooBig; } - atom->v.str.len = l; + const size_t ls = (size_t)l; + (*got) += ls; + if ((*got) <= ls) { + return YACErrLenTooBig; + } + if (len < (*got)) { + return YACErrNotEnough; + } + atom->v.str.len = ls; atom->v.str.ptr = buf + 1 + ll; if (atom->typ == YACItemStr) { + if (l > PTRDIFF_MAX) { + return YACErrLenTooBig; + } size_t cpl = 0; uint32_t cp = YACUTF8InvalidCp; for (size_t n = 0; n < l;) { - cpl = YACUTF8CpDecode(&cp, atom->v.str.ptr + n, l - n); + cpl = YACUTF8CpDecode(&cp, atom->v.str.ptr + (ptrdiff_t)n, l - n); if (cp == YACUTF8InvalidCp) { - ret.err = YACErrBadUTF8; - return ret; + return YACErrBadUTF8; } n += cpl; } } - ret.err = YACErrNo; - return ret; + return YACErrNo; } if ((atom->tag >= YACAtomInt0) && (atom->tag < YACAtomInt0 + 32)) { - atom->v.pint = (uint64_t)(atom->tag - YACAtomInt0); atom->typ = YACItemPint; - ret.err = YACErrNo; - return ret; + atom->v.pint = (uint64_t)(atom->tag - YACAtomInt0); + return YACErrNo; } if ((atom->tag >= YACAtomIntN1) && (atom->tag < YACAtomIntN1 + 32)) { - atom->v.nint = -1 - (int64_t)(atom->tag - YACAtomIntN1); atom->typ = YACItemNint; - ret.err = YACErrNo; - return ret; + atom->v.nint = -1 - (int64_t)(atom->tag - YACAtomIntN1); + return YACErrNo; } switch (atom->tag & 0xF0) { case YACAtomIntPos1: @@ -107,14 +109,12 @@ YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len) atom->typ = ((atom->tag & YACAtomIntNeg1) == YACAtomIntNeg1) ? YACItemNint : YACItemPint; const size_t l = (atom->tag & 0x0F) + 1; - ret.len += l; - if ((ptrdiff_t)len < ret.len) { - ret.err = YACErrNotEnough; - return ret; + (*got) += l; + if (len < (*got)) { + return YACErrNotEnough; } if (buf[1] == 0) { - ret.err = YACErrIntNonMinimal; - return ret; + return YACErrIntNonMinimal; } if (l > 8) { atom->typ = YACItemRaw; @@ -123,15 +123,19 @@ YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len) } else { atom->v.pint = yacFromBE(buf + 1, l); if ((atom->v.pint) < 32) { - ret.err = YACErrIntNonMinimal; - return ret; + return YACErrIntNonMinimal; } if (atom->typ == YACItemNint) { - atom->v.nint = -1 - (int64_t)(atom->v.pint); + if (atom->v.pint >= ((uint64_t)1 << 63)) { + atom->typ = YACItemRaw; + atom->v.str.len = l; + atom->v.str.ptr = buf + 1; + } else { + atom->v.nint = -1 - (int64_t)(atom->v.pint); + } } } - ret.err = YACErrNo; - return ret; + return YACErrNo; } } @@ -150,10 +154,9 @@ YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len) break; case YACAtomUUID: atom->typ = YACItemUUID; - ret.len += 16; - if ((ptrdiff_t)len < ret.len) { - ret.err = YACErrNotEnough; - return ret; + (*got) += 16; + if (len < (*got)) { + return YACErrNotEnough; } atom->v.uuid = buf + 1; break; @@ -164,23 +167,22 @@ YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len) case YACAtomMap: atom->typ = YACItemMap; break; - case YACAtomBlob: + case YACAtomBlob: { atom->typ = YACItemBlob; - ret.len += 8; - if ((ptrdiff_t)len < ret.len) { - ret.err = YACErrNotEnough; - return ret; + (*got) += 8; + if (len < (*got)) { + return YACErrNotEnough; } - atom->v.blob.chunkLen = yacFromBE(buf + 1, 8); - if (atom->v.blob.chunkLen == 0) { - ret.err = YACErrBlobBadLen; - return ret; + const uint64_t chunkLen = yacFromBE(buf + 1, 8); + if (chunkLen > SIZE_MAX) { + return YACErrLenTooBig; } - if (atom->v.blob.chunkLen > ((uint64_t)(1) << 60)) { - ret.err = YACErrNotEnough; - return ret; + if (chunkLen == 0) { + return YACErrBlobBadLen; } + atom->v.blob.chunkLen = (size_t)chunkLen; break; + } case YACAtomFloat16: case YACAtomFloat32: @@ -206,10 +208,9 @@ YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len) break; } atom->typ = YACItemFloat; - ret.len += l; - if ((ptrdiff_t)len < ret.len) { - ret.err = YACErrNotEnough; - return ret; + (*got) += l; + if (len < (*got)) { + return YACErrNotEnough; } atom->typ = YACItemRaw; atom->v.str.len = l; @@ -233,41 +234,35 @@ YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len) break; } atom->typ = YACItemTAI64; - ret.len += l; - if ((ptrdiff_t)len < ret.len) { - ret.err = YACErrNotEnough; - return ret; + (*got) += l; + if (len < (*got)) { + return YACErrNotEnough; } atom->v.str.len = l; atom->v.str.ptr = buf + 1; uint64_t v = yacFromBE(buf + 1, 8); - if (v > ((uint64_t)(1) << 63)) { - ret.err = YACErrTAI64TooBig; - return ret; + if (v > ((uint64_t)1 << 63)) { + return YACErrTAI64TooBig; } switch (l) { case 12: v = yacFromBE(buf + 1 + 8, 4); if (v > 999999999) { - ret.err = YACErrTAI64BadNsec; - return ret; + return YACErrTAI64BadNsec; } break; case 16: v = yacFromBE(buf + 1 + 8 + 4, 4); if (v > 999999999) { - ret.err = YACErrTAI64BadAsec; - return ret; + return YACErrTAI64BadAsec; } break; } break; } default: - ret.err = YACErrUnknownType; - return ret; + return YACErrUnknownType; } - ret.err = YACErrNo; - return ret; + return YACErrNo; } diff --git a/cyac/lib/dec.h b/cyac/lib/dec.h index 4b8b3a6..1930301 100644 --- a/cyac/lib/dec.h +++ b/cyac/lib/dec.h @@ -89,11 +89,11 @@ struct YACAtom { uint64_t pint; int64_t nint; struct { - ptrdiff_t head; + size_t head; size_t len; } list; struct { - uint64_t chunkLen; + size_t chunkLen; size_t chunks; } blob; struct { @@ -106,13 +106,11 @@ struct YACAtom { char _pad[3]; }; -struct YACErrAndLen { - ptrdiff_t len; - enum YACErr err; - char _pad[4]; -}; - -struct YACErrAndLen -YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len); +enum YACErr +YACAtomDecode( + size_t *got, + struct YACAtom *atom, + const unsigned char *buf, + const size_t len); #endif // YAC_DEC_H diff --git a/cyac/lib/dectai.c b/cyac/lib/dectai.c index b3d27dc..f36b993 100644 --- a/cyac/lib/dectai.c +++ b/cyac/lib/dectai.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include "dectai.h" #include "err.h" @@ -23,13 +23,16 @@ #include "leapsecs.h" enum YACErr -YACTAI64ToTimeval(struct timeval *tv, const unsigned char *buf, const size_t len) +YACTAI64ToTimespec(struct timespec *tv, const unsigned char *buf, const size_t len) { if (len > 12) { return YACErrTAI64BadAsec; } int64_t v = (int64_t)yacFromBE(buf, 8); v -= 0x4000000000000000; + if (v <= 0) { + return YACErrTAI64InPast; + } { int64_t diff = 0; for (size_t i = 0; i < YACLeapsecsN; i++) { @@ -40,13 +43,16 @@ YACTAI64ToTimeval(struct timeval *tv, const unsigned char *buf, const size_t len } v -= diff; } + if (v <= 0) { + return YACErrTAI64InPast; + } + if (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < (uint64_t)v) { + return YACErrTAI64TooBig; + } tv->tv_sec = (time_t)v; if (len > 8) { uint32_t n = (uint32_t)yacFromBE(buf + 8, 4); - if ((n % 1000) != 0) { - return YACErrTAI64BadNsec; - } - tv->tv_usec = n / 1000; + tv->tv_nsec = n; } return YACErrNo; } diff --git a/cyac/lib/dectai.h b/cyac/lib/dectai.h index a12a82f..efc573b 100644 --- a/cyac/lib/dectai.h +++ b/cyac/lib/dectai.h @@ -3,11 +3,11 @@ #define YAC_DECTAI_H #include -#include +#include #include "err.h" enum YACErr -YACTAI64ToTimeval(struct timeval *tv, const unsigned char *buf, const size_t len); +YACTAI64ToTimespec(struct timespec *tv, const unsigned char *buf, const size_t len); #endif // YAC_DECTAI_H diff --git a/cyac/lib/enc.c b/cyac/lib/enc.c index 765d452..b737e25 100644 --- a/cyac/lib/enc.c +++ b/cyac/lib/enc.c @@ -22,213 +22,247 @@ #include "enc.h" #include "tobe.h" -ptrdiff_t -YACAtomEOCEncode(unsigned char *buf, const size_t cap) +bool +YACAtomEOCEncode(size_t *len, unsigned char *buf, const size_t cap) { + (*len) = 1; if (cap < 1) { - return -1; + return false; } buf[0] = YACAtomEOC; - return 1; + return true; } -ptrdiff_t -YACAtomNILEncode(unsigned char *buf, const size_t cap) +bool +YACAtomNILEncode(size_t *len, unsigned char *buf, const size_t cap) { + (*len) = 1; if (cap < 1) { - return -1; + return false; } buf[0] = YACAtomNIL; - return 1; + return true; } -ptrdiff_t -YACAtomBoolEncode(unsigned char *buf, const size_t cap, const bool v) +bool +YACAtomBoolEncode(size_t *len, unsigned char *buf, const size_t cap, const bool v) { + (*len) = 1; if (cap < 1) { - return -1; + return false; } buf[0] = v ? YACAtomTrue : YACAtomFalse; - return 1; + return true; } -ptrdiff_t -YACAtomUUIDEncode(unsigned char *buf, const size_t cap, const unsigned char v[16]) +bool +YACAtomUUIDEncode( + size_t *len, + unsigned char *buf, + const size_t cap, + const unsigned char v[16]) { - if (cap < 1 + 16) { - return -(1 + 16); + (*len) = 1 + 16; + if (cap < (1 + 16)) { + return false; } buf[0] = YACAtomUUID; memcpy(buf + 1, v, 16); - return 1 + 16; + return true; } -static ptrdiff_t -yacAtomIntEncode(unsigned char *buf, const size_t cap, const uint64_t v) +static bool +yacAtomIntEncode(size_t *len, unsigned char *buf, const size_t cap, const uint64_t v) { if (v < 32) { + (*len) = 1; if (cap < 1) { - return -1; + return false; } buf[0] = (unsigned char)v; - return 1; + return true; } size_t bits = 8; size_t l = 0; for (;;) { - if (v < (((uint64_t)1) << bits)) { + if (v < ((uint64_t)1 << bits)) { break; } l++; bits += 8; } if (cap < (1 + l)) { - return -(1 + (ptrdiff_t)l); + return false; } buf[0] = (unsigned char)l; l++; yacToBE(buf + 1, l, v); - return 1 + (ptrdiff_t)l; + (*len) = 1 + l; + return true; } -ptrdiff_t -YACAtomUintEncode(unsigned char *buf, const size_t cap, uint64_t v) +bool +YACAtomUintEncode(size_t *len, unsigned char *buf, const size_t cap, uint64_t v) { - ptrdiff_t ret = yacAtomIntEncode(buf, cap, v); - if (ret < 0) { - return ret; + bool ok = yacAtomIntEncode(len, buf, cap, v); + if (ok) { + buf[0] |= (v < 32) ? YACAtomInt0 : YACAtomIntPos1; } - buf[0] |= (v < 32) ? YACAtomInt0 : YACAtomIntPos1; - return ret; + return ok; } -ptrdiff_t -YACAtomSintEncode(unsigned char *buf, const size_t cap, int64_t v) +bool +YACAtomSintEncode(size_t *len, unsigned char *buf, const size_t cap, int64_t v) { if (v >= 0) { - return YACAtomUintEncode(buf, cap, (uint64_t)v); + return YACAtomUintEncode(len, buf, cap, (uint64_t)v); } const uint64_t vp = (uint64_t)(-(v + 1)); - ptrdiff_t ret = yacAtomIntEncode(buf, cap, vp); - if (ret < 0) { - return ret; + bool ok = yacAtomIntEncode(len, buf, cap, vp); + if (ok) { + buf[0] |= (vp < 32) ? YACAtomIntN1 : YACAtomIntNeg1; } - buf[0] |= (vp < 32) ? YACAtomIntN1 : YACAtomIntNeg1; - return ret; + return ok; } -ptrdiff_t -YACAtomListEncode(unsigned char *buf, const size_t cap) +bool +YACAtomListEncode(size_t *len, unsigned char *buf, const size_t cap) { + (*len) = 1; if (cap < 1) { - return -1; + return false; } buf[0] = YACAtomList; - return 1; + return true; } -ptrdiff_t -YACAtomMapEncode(unsigned char *buf, const size_t cap) +bool +YACAtomMapEncode(size_t *len, unsigned char *buf, const size_t cap) { + (*len) = 1; if (cap < 1) { - return -1; + return false; } buf[0] = YACAtomMap; - return 1; + return true; } -ptrdiff_t -YACAtomBlobEncode(unsigned char *buf, const size_t cap, const size_t chunkLen) +bool +YACAtomBlobEncode( + size_t *len, + unsigned char *buf, + const size_t cap, + const size_t chunkLen) { + (*len) = 1 + 8; if (cap < 1 + 8) { - return -(1 + 8); + return false; } buf[0] = YACAtomBlob; - yacToBE(buf + 1, 8, chunkLen); - return 1 + 8; + yacToBE(buf + 1, 8, (uint64_t)chunkLen); + return true; } -static ptrdiff_t +static bool yacAtomStrEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t l, + const size_t srcLen, const bool utf8) { - unsigned char lv = 0; - size_t ll = 0; + unsigned char lVal = 0; + size_t lLen = 0; unsigned char lBuf[8] = {0}; - if (l >= (((uint64_t)1) << 16)) { - lv = 63; - ll = 8; - yacToBE(lBuf, 8, l); - } else if (l >= (((uint64_t)1) << 8)) { - lv = 62; - ll = 2; - yacToBE(lBuf, 2, l); - } else if (l > 60) { - lv = 61; - ll = 1; - lBuf[0] = (unsigned char)(l & 0xFF); + if (srcLen >= ((uint64_t)1 << 16)) { + lVal = 63; + lLen = 8; + yacToBE(lBuf, 8, (uint64_t)srcLen); + } else if (srcLen >= ((uint64_t)1 << 8)) { + lVal = 62; + lLen = 2; + yacToBE(lBuf, 2, (uint64_t)srcLen); + } else if (srcLen > 60) { + lVal = 61; + lLen = 1; + lBuf[0] = (unsigned char)(srcLen & 0xFF); } else { - lv = (unsigned char)l; + lVal = (unsigned char)srcLen; + } + (*len) = 1 + lLen + srcLen; + if ((*len) <= srcLen) { + (*len) = 0; + return false; } - if (cap < (1 + ll + l)) { - return -(ptrdiff_t)(1 + ll + l); + if (cap < (*len)) { + return false; } - buf[0] = YACAtomStrings | lv; + buf[0] = YACAtomStrings | lVal; if (utf8) { buf[0] |= YACAtomIsUTF8; } - memcpy(buf + 1, lBuf, ll); - memcpy(buf + 1 + ll, src, l); - return (ptrdiff_t)(1 + ll + l); + memcpy(buf + 1, lBuf, lLen); + memcpy(buf + 1 + lLen, src, srcLen); + return true; } -ptrdiff_t +bool YACAtomStrEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t len) + const size_t srcLen) { - return yacAtomStrEncode(buf, cap, src, len, true); + return yacAtomStrEncode(len, buf, cap, src, srcLen, true); } -ptrdiff_t +bool YACAtomBinEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t len) + const size_t srcLen) { - return yacAtomStrEncode(buf, cap, src, len, false); + return yacAtomStrEncode(len, buf, cap, src, srcLen, false); } -ptrdiff_t +bool YACAtomChunkEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t len) + const size_t srcLen) { - if (cap < (1 + len)) { - return -(ptrdiff_t)(1 + len); + (*len) = 1 + srcLen; + if ((*len) <= srcLen) { + (*len) = 0; + return false; + } + if (cap < (*len)) { + return false; } buf[0] = YACAtomNIL; - memcpy(buf + 1, src, len); - return (ptrdiff_t)(1 + len); + memcpy(buf + 1, src, srcLen); + return true; } -ptrdiff_t +bool YACAtomTAI64Encode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t len) + const size_t srcLen) { - switch (len) { + (*len) = 1 + srcLen; + if (cap < (*len)) { + return false; + } + switch (srcLen) { case 8: buf[0] = YACAtomTAI64; break; @@ -241,25 +275,28 @@ YACAtomTAI64Encode( default: return 0; } - if (cap < (1 + len)) { - return -(ptrdiff_t)(1 + len); - } - memcpy(buf + 1, src, len); - return (ptrdiff_t)(1 + len); + memcpy(buf + 1, src, srcLen); + return true; } -ptrdiff_t +bool YACAtomRawEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char typ, const unsigned char *src, - const size_t len) + const size_t srcLen) { - if (cap < (1 + len)) { - return -(ptrdiff_t)(1 + len); + (*len) = 1 + srcLen; + if ((*len) <= srcLen) { + (*len) = 0; + return false; + } + if (cap < (*len)) { + return false; } buf[0] = typ; - memcpy(buf + 1, src, len); - return (ptrdiff_t)(1 + len); + memcpy(buf + 1, src, srcLen); + return true; } diff --git a/cyac/lib/enc.h b/cyac/lib/enc.h index 78dfa8b..fcb551d 100644 --- a/cyac/lib/enc.h +++ b/cyac/lib/enc.h @@ -5,67 +5,80 @@ #include #include -ptrdiff_t -YACAtomEOCEncode(unsigned char *buf, const size_t cap); +bool +YACAtomEOCEncode(size_t *len, unsigned char *buf, const size_t cap); -ptrdiff_t -YACAtomNILEncode(unsigned char *buf, const size_t cap); +bool +YACAtomNILEncode(size_t *len, unsigned char *buf, const size_t cap); -ptrdiff_t -YACAtomBoolEncode(unsigned char *buf, const size_t cap, const bool v); +bool +YACAtomBoolEncode(size_t *len, unsigned char *buf, const size_t cap, const bool v); -ptrdiff_t -YACAtomUUIDEncode(unsigned char *buf, const size_t cap, const unsigned char v[16]); +bool +YACAtomUUIDEncode( + size_t *len, + unsigned char *buf, + const size_t cap, + const unsigned char v[16]); -ptrdiff_t -YACAtomUintEncode(unsigned char *buf, const size_t cap, uint64_t v); +bool +YACAtomUintEncode(size_t *len, unsigned char *buf, const size_t cap, uint64_t v); -ptrdiff_t -YACAtomSintEncode(unsigned char *buf, const size_t cap, int64_t v); +bool +YACAtomSintEncode(size_t *len, unsigned char *buf, const size_t cap, int64_t v); -ptrdiff_t -YACAtomListEncode(unsigned char *buf, const size_t cap); +bool +YACAtomListEncode(size_t *len, unsigned char *buf, const size_t cap); -ptrdiff_t -YACAtomMapEncode(unsigned char *buf, const size_t cap); +bool +YACAtomMapEncode(size_t *len, unsigned char *buf, const size_t cap); -ptrdiff_t -YACAtomBlobEncode(unsigned char *buf, const size_t cap, const size_t chunkLen); +bool +YACAtomBlobEncode( + size_t *len, + unsigned char *buf, + const size_t cap, + const size_t chunkLen); -ptrdiff_t +bool YACAtomStrEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t len); + const size_t srcLen); -ptrdiff_t +bool YACAtomBinEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t len); + const size_t srcLen); -ptrdiff_t +bool YACAtomChunkEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t len); + const size_t srcLen); -ptrdiff_t +bool YACAtomTAI64Encode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char *src, - const size_t len); + const size_t srcLen); -ptrdiff_t +bool YACAtomRawEncode( + size_t *len, unsigned char *buf, const size_t cap, const unsigned char typ, const unsigned char *src, - const size_t len); + const size_t srcLen); #endif // YAC_ENC_H diff --git a/cyac/lib/enctai.c b/cyac/lib/enctai.c index 6595a71..32afb56 100644 --- a/cyac/lib/enctai.c +++ b/cyac/lib/enctai.c @@ -13,28 +13,31 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . -#include #include -#include +#include #include "enctai.h" #include "leapsecs.h" #include "tobe.h" -void -YACTimevalToTAI64(unsigned char *buf, const struct timeval *tv) +bool +YACTimespecToTAI64(unsigned char *buf, const struct timespec *tv) { int64_t v = (int64_t)(tv->tv_sec); int64_t diff = YACLeapsecs1972; - for (size_t i = 0; i < sizeof YACLeapsecsN; i++) { + for (size_t i = 0; i < YACLeapsecsN; i++) { if (v > YACLeapsecs[i]) { diff += YACLeapsecsN - i; break; } } - v += 0x4000000000000000 + diff; - yacToBE(buf, 8, (uint64_t)v); - if (tv->tv_usec != 0) { - yacToBE(buf + 8, 4, (uint64_t)(tv->tv_usec) * 1000); + uint64_t val = (uint64_t)v + 0x4000000000000000 + (uint64_t)diff; + if (val <= (uint64_t)v) { + return false; } + yacToBE(buf, 8, val); + if (tv->tv_nsec != 0) { + yacToBE(buf + 8, 4, (uint64_t)(tv->tv_nsec)); + } + return true; } diff --git a/cyac/lib/enctai.h b/cyac/lib/enctai.h index 7487ae6..e965fe9 100644 --- a/cyac/lib/enctai.h +++ b/cyac/lib/enctai.h @@ -1,9 +1,10 @@ #ifndef YAC_ENCTAI_H #define YAC_ENCTAI_H -#include +#include +#include -void -YACTimevalToTAI64(unsigned char *buf, const struct timeval *tv); +bool +YACTimespecToTAI64(unsigned char *buf, const struct timespec *tv); #endif // YAC_ENCTAI_H diff --git a/cyac/lib/err.c b/cyac/lib/err.c index 0967b34..2040665 100644 --- a/cyac/lib/err.c +++ b/cyac/lib/err.c @@ -18,8 +18,6 @@ YACErr2Str(const enum YACErr err) return "LenTooBig"; case YACErrBadUTF8: return "BadUTF8"; - case YACErrIntZeroByte: - return "IntZeroByte"; case YACErrIntNonMinimal: return "IntNonMinimal"; case YACErrBlobBadLen: @@ -34,6 +32,8 @@ YACErr2Str(const enum YACErr err) return "TAI64BadNsec"; case YACErrTAI64BadAsec: return "TAI64BadAsec"; + case YACErrTAI64InPast: + return "TAI64InPast"; case YACErrMapBadKey: return "MapBadKey"; case YACErrMapNoVal: diff --git a/cyac/lib/err.h b/cyac/lib/err.h index e940f11..1f35725 100644 --- a/cyac/lib/err.h +++ b/cyac/lib/err.h @@ -51,7 +51,6 @@ enum YACErr { YACErrLenNonMinimal, YACErrLenTooBig, YACErrBadUTF8, - YACErrIntZeroByte, YACErrIntNonMinimal, YACErrBlobBadLen, YACErrBlobBadAtom, @@ -59,6 +58,7 @@ enum YACErr { YACErrTAI64TooBig, YACErrTAI64BadNsec, YACErrTAI64BadAsec, + YACErrTAI64InPast, YACErrMapBadKey, YACErrMapNoVal, YACErrMapUnordered, diff --git a/cyac/lib/items.c b/cyac/lib/items.c index 52e2ed2..a13b565 100644 --- a/cyac/lib/items.c +++ b/cyac/lib/items.c @@ -13,8 +13,10 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . +#include #include #include +#include #include #include @@ -23,7 +25,7 @@ #include "err.h" #include "items.h" -static const ptrdiff_t yacItemsPoolGrowLen = 32; +static const ptrdiff_t yacItemsPoolGrowLen = 64; enum YACErr YACItemsInit(struct YACItems *items) @@ -40,16 +42,25 @@ YACItemsInit(struct YACItems *items) enum YACErr yacItemsGrow(struct YACItems *items) { - items->cap += yacItemsPoolGrowLen; - if (items->cap <= 0) { + if (items->cap == -1) { + return YACErrNoMem; + } + if ((SIZE_MAX - yacItemsPoolGrowLen) < (size_t)(items->cap)) { return YACErrNoMem; } + items->cap += yacItemsPoolGrowLen; + { + const ptrdiff_t possibleN = SIZE_MAX / sizeof(struct YACItem); + if (items->cap > possibleN) { + return YACErrNoMem; + } + } const size_t size = (size_t)(items->cap) * sizeof(struct YACItem); items->list = realloc(items->list, size); if (items->list == NULL) { return YACErrNoMem; } - const size_t begin = (size_t)(items->len) * sizeof(struct YACItem); + const size_t begin = items->len * sizeof(struct YACItem); memset((unsigned char *)(items->list) + begin, 0, size - begin); return YACErrNo; } @@ -57,52 +68,56 @@ yacItemsGrow(struct YACItems *items) static enum YACErr yacItemsAdd( struct YACItems *items, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len) { enum YACErr err = YACErrInvalid; - if (items->len == items->cap) { + if (items->len == (size_t)(items->cap)) { err = yacItemsGrow(items); if (err != YACErrNo) { return err; } } struct YACItem *item = &(items->list[items->len]); - item->next = -1; + item->next = 0; item->off = *off; - struct YACErrAndLen errLen = - YACAtomDecode(&(item->atom), buf + *off, len - (size_t)(*off)); - if (errLen.err != YACErrNo) { + size_t got = 0; + assert(len >= (*off)); + err = YACAtomDecode(&got, &(item->atom), buf + *off, len - (*off)); + if (err != YACErrNo) { return err; } - (*off) += errLen.len; - items->len++; - if (items->len <= 0) { - return YACErrNoMem; + if ((SIZE_MAX - got) < (*off)) { + return YACErrLenTooBig; } + (*off) += got; + items->len++; return YACErrNo; } enum YACErr YACItemsParse( struct YACItems *items, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len) { - ptrdiff_t item = items->len; + size_t item = items->len; enum YACErr err = yacItemsAdd(items, off, buf, len); if (err != YACErrNo) { return err; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wswitch-enum" switch (items->list[item].atom.typ) { +#pragma clang diagnostic pop case YACItemList: { items->list[item].atom.v.list.head = item + 1; items->list[item].atom.v.list.len = 0; - ptrdiff_t prev = -1; - ptrdiff_t cur = -1; - ptrdiff_t idx = item; + size_t prev = 0; + size_t cur = 0; + size_t idx = item; for (;;) { err = YACItemsParse(items, off, buf, len); if (err != YACErrNo) { @@ -111,11 +126,11 @@ YACItemsParse( cur = idx + 1; if (items->list[cur].atom.typ == YACItemEOC) { if (items->list[item].atom.v.list.len == 0) { - items->list[item].atom.v.list.head = -1; + items->list[item].atom.v.list.head = 0; } return YACErrNo; } - if (prev != -1) { + if (prev != 0) { items->list[prev].next = cur; } prev = cur; @@ -126,9 +141,9 @@ YACItemsParse( case YACItemMap: { items->list[item].atom.v.list.head = item + 1; items->list[item].atom.v.list.len = 0; - ptrdiff_t idx = item; - ptrdiff_t prev = -1; - ptrdiff_t cur = -1; + size_t idx = item; + size_t prev = 0; + size_t cur = 0; size_t prevKeyLen = 0; const unsigned char *prevKey = NULL; for (;;) { @@ -137,27 +152,17 @@ YACItemsParse( return err; } cur = idx + 1; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wswitch-enum" switch (items->list[cur].atom.typ) { +#pragma clang diagnostic pop case YACItemEOC: if (items->list[item].atom.v.list.len == 0) { - items->list[item].atom.v.list.head = -1; + items->list[item].atom.v.list.head = 0; } return YACErrNo; case YACItemStr: break; - case YACItemNIL: - case YACItemFalse: - case YACItemTrue: - case YACItemUUID: - case YACItemPint: - case YACItemNint: - case YACItemList: - case YACItemMap: - case YACItemBlob: - case YACItemFloat: - case YACItemTAI64: - case YACItemBin: - case YACItemRaw: default: return YACErrMapBadKey; } @@ -173,7 +178,7 @@ YACItemsParse( } prevKeyLen = items->list[cur].atom.v.str.len; prevKey = items->list[cur].atom.v.str.ptr; - if (prev != -1) { + if (prev != 0) { items->list[prev].next = cur; } prev = cur; @@ -194,10 +199,10 @@ YACItemsParse( } case YACItemBlob: { items->list[item].atom.v.blob.chunks = 0; - const ptrdiff_t chunkLen = (ptrdiff_t)(items->list[item].atom.v.blob.chunkLen); - ptrdiff_t idx = item; - ptrdiff_t prev = -1; - ptrdiff_t cur = -1; + const size_t chunkLen = items->list[item].atom.v.blob.chunkLen; + size_t idx = item; + size_t prev = 0; + size_t cur = 0; bool eoc = false; while (!eoc) { err = YACItemsParse(items, off, buf, len); @@ -206,40 +211,33 @@ YACItemsParse( } cur = idx + 1; struct YACAtom *atom = &(items->list[cur].atom); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wswitch-enum" switch (atom->typ) { +#pragma clang diagnostic pop case YACItemNIL: - if (((ptrdiff_t)len - *off) <= chunkLen) { - atom->v.str.len = (size_t)chunkLen; + atom->v.str.len = chunkLen; + assert(len >= (*off)); + if ((len - (*off)) <= chunkLen) { return YACErrNotEnough; } atom->typ = YACItemBin; atom->v.str.ptr = buf + *off; - atom->v.str.len = (size_t)chunkLen; + if ((SIZE_MAX - chunkLen) < (*off)) { + return YACErrLenTooBig; + } (*off) += chunkLen; break; case YACItemBin: - if ((ptrdiff_t)(atom->v.str.len) >= chunkLen) { + if (atom->v.str.len >= chunkLen) { return YACErrBlobBadTerm; } eoc = true; break; - case YACItemEOC: - case YACItemFalse: - case YACItemTrue: - case YACItemUUID: - case YACItemPint: - case YACItemNint: - case YACItemList: - case YACItemMap: - case YACItemBlob: - case YACItemFloat: - case YACItemTAI64: - case YACItemStr: - case YACItemRaw: default: return YACErrBlobBadAtom; } - if (prev != -1) { + if (prev != 0) { items->list[prev].next = cur; } prev = cur; @@ -248,173 +246,170 @@ YACItemsParse( } break; } - case YACItemEOC: - case YACItemNIL: - case YACItemFalse: - case YACItemTrue: - case YACItemUUID: - case YACItemPint: - case YACItemNint: - case YACItemFloat: - case YACItemTAI64: - case YACItemBin: - case YACItemStr: - case YACItemRaw: default: break; } return YACErrNo; } -ptrdiff_t +bool YACItemsEncode( - struct YACItems *items, - ptrdiff_t idx, - ptrdiff_t *off, + const struct YACItems *items, + size_t idx, + size_t *off, unsigned char *buf, const size_t cap) { - struct YACItem *item = &(items->list[idx]); - ptrdiff_t diff = 0; + const struct YACItem *item = &(items->list[idx]); + size_t got = 0; + bool ok = false; + assert(cap >= (*off)); switch (item->atom.typ) { case YACItemEOC: - return -1; + return false; case YACItemNIL: - diff = YACAtomNILEncode(buf + *off, cap - (size_t)(*off)); + ok = YACAtomNILEncode(&got, buf + *off, cap - (*off)); break; case YACItemFalse: - diff = YACAtomBoolEncode(buf + *off, cap - (size_t)(*off), false); + ok = YACAtomBoolEncode(&got, buf + *off, cap - (*off), false); break; case YACItemTrue: - diff = YACAtomBoolEncode(buf + *off, cap - (size_t)(*off), true); + ok = YACAtomBoolEncode(&got, buf + *off, cap - (*off), true); break; case YACItemUUID: - diff = YACAtomUUIDEncode(buf + *off, cap - (size_t)(*off), item->atom.v.uuid); + ok = YACAtomUUIDEncode(&got, buf + *off, cap - (*off), item->atom.v.uuid); break; case YACItemPint: - diff = YACAtomUintEncode(buf + *off, cap - (size_t)(*off), item->atom.v.pint); + ok = YACAtomUintEncode(&got, buf + *off, cap - (*off), item->atom.v.pint); break; case YACItemNint: - diff = YACAtomSintEncode(buf + *off, cap - (size_t)(*off), item->atom.v.nint); + ok = YACAtomSintEncode(&got, buf + *off, cap - (*off), item->atom.v.nint); break; case YACItemList: - diff = YACAtomListEncode(buf + *off, cap - (size_t)(*off)); - if (diff < 0) { - return diff; + ok = YACAtomListEncode(&got, buf + *off, cap - (*off)); + if (!ok) { + return false; + } + if ((SIZE_MAX - got) < (*off)) { + return false; } - (*off) += diff; + (*off) += got; idx = item->atom.v.list.head; - while (idx != -1) { - diff = YACItemsEncode(items, idx, off, buf, cap); - if (diff < 0) { - return diff; + while (idx != 0) { + ok = YACItemsEncode(items, idx, off, buf, cap); + if (!ok) { + return false; } idx = items->list[idx].next; } - diff = YACAtomEOCEncode(buf + *off, cap - (size_t)(*off)); + assert(cap >= (*off)); + ok = YACAtomEOCEncode(&got, buf + *off, cap - (*off)); break; case YACItemMap: - diff = YACAtomMapEncode(buf + *off, cap - (size_t)(*off)); - if (diff < 0) { - return diff; + ok = YACAtomMapEncode(&got, buf + *off, cap - (*off)); + if (!ok) { + return false; + } + if ((SIZE_MAX - got) < (*off)) { + return false; } - (*off) += diff; + (*off) += got; idx = item->atom.v.list.head; - while (idx != -1) { - diff = YACItemsEncode(items, idx, off, buf, cap); - if (diff < 0) { - return diff; + while (idx != 0) { + ok = YACItemsEncode(items, idx, off, buf, cap); + if (!ok) { + return false; } idx = items->list[idx].next; } - diff = YACAtomEOCEncode(buf + *off, cap - (size_t)(*off)); + ok = YACAtomEOCEncode(&got, buf + *off, cap - (*off)); break; case YACItemBlob: { - size_t chunkLen = (size_t)(item->atom.v.blob.chunkLen); - diff = YACAtomBlobEncode( - buf + *off, cap - (size_t)(*off), item->atom.v.blob.chunkLen); - if (diff < 0) { - return diff; + const size_t chunkLen = (item->atom.v.blob.chunkLen); + ok = YACAtomBlobEncode(&got, buf + *off, cap - (*off), chunkLen); + if (!ok) { + return 0; } - (*off) += diff; + if ((SIZE_MAX - got) < (*off)) { + return false; + } + (*off) += got; for (;;) { idx++; item = &(items->list[idx]); if (item->atom.v.str.len != chunkLen) { break; } - diff = YACAtomChunkEncode( + assert(cap >= (*off)); + ok = YACAtomChunkEncode( + &got, buf + *off, - cap - (size_t)(*off), + cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len); - if (diff < 0) { - return diff; + if (!ok) { + return false; } - (*off) += diff; + if ((SIZE_MAX - got) < (*off)) { + return false; + } + (*off) += got; continue; } - diff = YACAtomBinEncode( - buf + *off, - cap - (size_t)(*off), - item->atom.v.str.ptr, - item->atom.v.str.len); + assert(cap >= (*off)); + ok = YACAtomBinEncode( + &got, buf + *off, cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len); break; } case YACItemFloat: - return -1; + return false; case YACItemTAI64: - diff = YACAtomTAI64Encode( - buf + *off, - cap - (size_t)(*off), - item->atom.v.str.ptr, - item->atom.v.str.len); + ok = YACAtomTAI64Encode( + &got, buf + *off, cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len); break; case YACItemBin: - diff = YACAtomBinEncode( - buf + *off, - cap - (size_t)(*off), - item->atom.v.str.ptr, - item->atom.v.str.len); + ok = YACAtomBinEncode( + &got, buf + *off, cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len); break; case YACItemStr: - diff = YACAtomStrEncode( - buf + *off, - cap - (size_t)(*off), - item->atom.v.str.ptr, - item->atom.v.str.len); + ok = YACAtomStrEncode( + &got, buf + *off, cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len); break; case YACItemRaw: - diff = YACAtomRawEncode( + ok = YACAtomRawEncode( + &got, buf + *off, - cap - (size_t)(*off), + cap - (*off), item->atom.tag, item->atom.v.str.ptr, item->atom.v.str.len); break; default: - return -1; + return false; } - if (diff < 0) { - return diff; + if (!ok) { + return false; } - (*off) += diff; - return 0; + if ((SIZE_MAX - got) < (*off)) { + return false; + } + (*off) += got; + return true; } -ptrdiff_t +size_t YACItemsGetByKeyLen( - struct YACItems *items, - const ptrdiff_t itemIdx, + const struct YACItems *items, + const size_t itemIdx, const char *key, const size_t keyLen) { - struct YACItem *item = &(items->list[itemIdx]); + const struct YACItem *item = &(items->list[itemIdx]); if (item->atom.typ != YACItemMap) { - return -1; + return 0; } - ptrdiff_t idx = item->atom.v.list.head; - while (idx != -1) { + size_t idx = item->atom.v.list.head; + while (idx != 0) { if ((items->list[idx].atom.v.str.len == keyLen) && (memcmp(items->list[idx].atom.v.str.ptr, key, keyLen) == 0)) { return idx + 1; @@ -422,41 +417,41 @@ YACItemsGetByKeyLen( idx = items->list[idx].next; idx = items->list[idx].next; } - return -1; + return 0; } -ptrdiff_t -YACItemsGetByKey(struct YACItems *items, const ptrdiff_t itemIdx, const char *key) +size_t +YACItemsGetByKey(const struct YACItems *items, const size_t itemIdx, const char *key) { return YACItemsGetByKeyLen(items, itemIdx, key, strlen(key)); } -ptrdiff_t +size_t YACItemsGetByKeyAndType( - struct YACItems *items, - const ptrdiff_t itemIdx, + const struct YACItems *items, + const size_t itemIdx, const char *key, const enum YACItemType typ) { - ptrdiff_t idx = YACItemsGetByKey(items, itemIdx, key); - if ((idx == -1) || (items->list[idx].atom.typ != typ)) { - return -1; + const size_t idx = YACItemsGetByKey(items, itemIdx, key); + if ((idx == 0) || (items->list[idx].atom.typ != typ)) { + return 0; } return idx; } bool -YACStrEqual(struct YACAtom *atom, const char *s) +YACStrEqual(const struct YACAtom *atom, const char *s) { return (atom->v.str.len == strlen(s)) && (memcmp(atom->v.str.ptr, s, atom->v.str.len) == 0); } bool -YACListHasOnlyType(struct YACItems *items, ptrdiff_t idx, const enum YACItemType typ) +YACListHasOnlyType(const struct YACItems *items, size_t idx, const enum YACItemType typ) { idx = items->list[idx].atom.v.list.head; - while (idx != -1) { + while (idx != 0) { if (items->list[idx].atom.typ != typ) { return false; } @@ -466,10 +461,10 @@ YACListHasOnlyType(struct YACItems *items, ptrdiff_t idx, const enum YACItemType } bool -YACMapHasOnlyType(struct YACItems *items, ptrdiff_t idx, const enum YACItemType typ) +YACMapHasOnlyType(const struct YACItems *items, size_t idx, const enum YACItemType typ) { idx = items->list[idx].atom.v.list.head; - while (idx != -1) { + while (idx != 0) { idx = items->list[idx].next; if (items->list[idx].atom.typ != typ) { return false; diff --git a/cyac/lib/items.h b/cyac/lib/items.h index 7645783..47770a1 100644 --- a/cyac/lib/items.h +++ b/cyac/lib/items.h @@ -24,8 +24,8 @@ // item, until its length is less than chunk len. // @end deftypevar struct YACItem { - ptrdiff_t off; - ptrdiff_t next; + size_t off; + size_t next; struct YACAtom atom; }; @@ -38,7 +38,7 @@ struct YACItem { // @end deftypevar struct YACItems { struct YACItem *list; - ptrdiff_t len; + size_t len; ptrdiff_t cap; }; @@ -51,42 +51,42 @@ yacItemsGrow(struct YACItems *); enum YACErr YACItemsParse( struct YACItems *, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len); -ptrdiff_t +bool YACItemsEncode( - struct YACItems *, - ptrdiff_t idx, - ptrdiff_t *off, + const struct YACItems *, + size_t idx, + size_t *off, unsigned char *buf, const size_t cap); -ptrdiff_t +size_t YACItemsGetByKeyLen( - struct YACItems *, - const ptrdiff_t itemIdx, + const struct YACItems *, + const size_t itemIdx, const char *key, const size_t keyLen); -ptrdiff_t -YACItemsGetByKey(struct YACItems *, const ptrdiff_t itemIdx, const char *key); +size_t +YACItemsGetByKey(const struct YACItems *, const size_t itemIdx, const char *key); -ptrdiff_t +size_t YACItemsGetByKeyAndType( - struct YACItems *, - const ptrdiff_t itemIdx, + const struct YACItems *, + const size_t itemIdx, const char *key, const enum YACItemType typ); bool -YACStrEqual(struct YACAtom *, const char *s); +YACStrEqual(const struct YACAtom *, const char *s); bool -YACListHasOnlyType(struct YACItems *, ptrdiff_t idx, const enum YACItemType typ); +YACListHasOnlyType(const struct YACItems *, size_t idx, const enum YACItemType typ); bool -YACMapHasOnlyType(struct YACItems *, ptrdiff_t idx, const enum YACItemType typ); +YACMapHasOnlyType(const struct YACItems *, size_t idx, const enum YACItemType typ); #endif // YAC_POOL_H diff --git a/cyac/lib/iter.c b/cyac/lib/iter.c index 99cf570..566fc73 100644 --- a/cyac/lib/iter.c +++ b/cyac/lib/iter.c @@ -13,8 +13,10 @@ // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see . +#include #include #include +#include #include #include "dec.h" @@ -25,22 +27,26 @@ enum YACErr YACIterList( void *cbState, struct YACAtom *atom, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len, YACIterCb cb) { - struct YACErrAndLen errLen = {.err = YACErrInvalid, .len = 0}; + size_t got = 0; enum YACErr err = YACErrInvalid; bool eoc = false; for (size_t n = 0;; n++) { - errLen = YACAtomDecode(atom, buf + *off, len - (size_t)(*off)); - if (errLen.err != YACErrNo) { - return errLen.err; + assert(len >= (*off)); + err = YACAtomDecode(&got, atom, buf + *off, len - (*off)); + if (err != YACErrNo) { + return err; } - (*off) += errLen.len; + if ((SIZE_MAX - got) < (*off)) { + return YACErrLenTooBig; + } + (*off) += got; eoc = atom->typ == YACItemEOC; - err = cb(NULL, 0, eoc ? -1 : (ptrdiff_t)n, cbState, atom, off, buf, len); + err = cb(NULL, 0, !eoc, n, cbState, atom, off, buf, len); if (err != YACErrNo) { return err; } @@ -55,23 +61,27 @@ enum YACErr YACIterMap( void *cbState, struct YACAtom *atom, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len, YACIterCb cb) { - struct YACErrAndLen errLen = {.err = YACErrInvalid, .len = 0}; enum YACErr err = YACErrInvalid; + size_t got = 0; const unsigned char *key = NULL; size_t keyLen = 0; for (;;) { - errLen = YACAtomDecode(atom, buf + *off, len - (size_t)(*off)); - if (errLen.err != YACErrNo) { - return errLen.err; + assert(len >= (*off)); + err = YACAtomDecode(&got, atom, buf + *off, len - (*off)); + if (err != YACErrNo) { + return err; + } + if ((SIZE_MAX - got) < (*off)) { + return YACErrLenTooBig; } - (*off) += errLen.len; + (*off) += got; if (atom->typ == YACItemEOC) { - err = cb(NULL, 0, -1, cbState, atom, off, buf, len); + err = cb(NULL, 0, false, 0, cbState, atom, off, buf, len); if (err != YACErrNo) { return err; } @@ -92,15 +102,19 @@ YACIterMap( } keyLen = atom->v.str.len; key = atom->v.str.ptr; - errLen = YACAtomDecode(atom, buf + *off, len - (size_t)(*off)); - if (errLen.err != YACErrNo) { - return errLen.err; + assert(len >= (*off)); + err = YACAtomDecode(&got, atom, buf + *off, len - (*off)); + if (err != YACErrNo) { + return err; + } + if ((SIZE_MAX - got) < (*off)) { + return YACErrLenTooBig; } - (*off) += errLen.len; + (*off) += got; if (atom->typ == YACItemEOC) { return YACErrMapNoVal; } - err = cb(key, keyLen, -1, cbState, atom, off, buf, len); + err = cb(key, keyLen, false, 0, cbState, atom, off, buf, len); if (err != YACErrNo) { return err; } @@ -112,30 +126,38 @@ enum YACErr YACIterBlob( void *cbState, struct YACAtom *atom, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len, YACIterCb cb) { - const size_t chunkLen = (size_t)(atom->v.blob.chunkLen); - struct YACErrAndLen errLen = {.err = YACErrInvalid, .len = 0}; + const size_t chunkLen = atom->v.blob.chunkLen; enum YACErr err = YACErrInvalid; + size_t got = 0; bool eoc = false; for (size_t n = 0; !eoc; n++) { - errLen = YACAtomDecode(atom, buf + *off, len - (size_t)(*off)); - if (errLen.err != YACErrNo) { - return errLen.err; + assert(len >= (*off)); + err = YACAtomDecode(&got, atom, buf + *off, len - (*off)); + if (err != YACErrNo) { + return err; + } + if ((SIZE_MAX - got) < (*off)) { + return YACErrLenTooBig; } - (*off) += errLen.len; + (*off) += got; switch (atom->typ) { case YACItemNIL: - if (((ptrdiff_t)len - *off) <= (ptrdiff_t)chunkLen) { + assert(len >= (*off)); + if ((len - *off) <= chunkLen) { atom->v.str.len = chunkLen; return YACErrNotEnough; } atom->typ = YACItemBin; atom->v.str.ptr = buf + *off; atom->v.str.len = chunkLen; + if ((SIZE_MAX - chunkLen) < (*off)) { + return YACErrLenTooBig; + } (*off) += chunkLen; break; case YACItemBin: @@ -144,28 +166,15 @@ YACIterBlob( } eoc = true; break; - case YACItemEOC: - case YACItemFalse: - case YACItemTrue: - case YACItemUUID: - case YACItemPint: - case YACItemNint: - case YACItemList: - case YACItemMap: - case YACItemBlob: - case YACItemFloat: - case YACItemTAI64: - case YACItemStr: - case YACItemRaw: default: return YACErrBlobBadAtom; } - err = cb(NULL, 0, (ptrdiff_t)n, cbState, atom, off, buf, len); + err = cb(NULL, 0, true, n, cbState, atom, off, buf, len); if (err != YACErrNo) { return err; } } atom->typ = YACItemEOC; - err = cb(NULL, 0, -1, cbState, atom, off, buf, len); + err = cb(NULL, 0, false, 0, cbState, atom, off, buf, len); return err; } diff --git a/cyac/lib/iter.h b/cyac/lib/iter.h index a310fc5..028ae6d 100644 --- a/cyac/lib/iter.h +++ b/cyac/lib/iter.h @@ -1,6 +1,7 @@ #ifndef YAC_ITER_H #define YAC_ITER_H +#include #include #include "dec.h" @@ -9,10 +10,11 @@ typedef enum YACErr (*YACIterCb)( const unsigned char *key, const size_t keyLen, - const ptrdiff_t idx, + const bool inList, + const size_t idx, void *cbState, struct YACAtom *atom, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len); @@ -20,7 +22,7 @@ enum YACErr YACIterList( void *cbState, struct YACAtom *atom, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len, YACIterCb cb); @@ -29,7 +31,7 @@ enum YACErr YACIterMap( void *cbState, struct YACAtom *atom, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len, YACIterCb cb); @@ -38,7 +40,7 @@ enum YACErr YACIterBlob( void *cbState, struct YACAtom *atom, - ptrdiff_t *off, + size_t *off, const unsigned char *buf, const size_t len, YACIterCb cb); diff --git a/cyac/lib/pki/cer.c b/cyac/lib/pki/cer.c index 9e01798..3448f1a 100644 --- a/cyac/lib/pki/cer.c +++ b/cyac/lib/pki/cer.c @@ -1,6 +1,5 @@ #include #include -#include #include "../dec.h" #include "../dectai.h" @@ -12,7 +11,7 @@ enum YACErr YACCerParse( struct YACCer *cer, - ptrdiff_t *off, + size_t *off, char **failReason, const unsigned char *buf, const size_t len) @@ -23,20 +22,20 @@ YACCerParse( if (err != YACErrNo) { return err; } - ptrdiff_t idx = 0; + size_t idx = 0; struct YACItem *item = NULL; - if (YACItemsGetByKey(items, 0, "hash") != -1) { + if (YACItemsGetByKey(items, 0, "hash") != 0) { (*failReason) = "unexpected /hash"; return YACErrUnsatisfiedSchema; } - ptrdiff_t loadIdx = YACItemsGetByKey(items, 0, "load"); + size_t loadIdx = YACItemsGetByKey(items, 0, "load"); { - if (loadIdx == -1) { + if (loadIdx == 0) { (*failReason) = "no /load"; return YACErrUnsatisfiedSchema; } idx = YACItemsGetByKeyAndType(items, loadIdx, "t", YACItemStr); - if (loadIdx == -1) { + if (loadIdx == 0) { (*failReason) = "no /load/t"; return YACErrUnsatisfiedSchema; } @@ -47,12 +46,12 @@ YACCerParse( } cer->load = YACItemsGetByKey(items, loadIdx, "v"); { - if (cer->load == -1) { + if (cer->load == 0) { (*failReason) = "no /load/v"; return YACErrUnsatisfiedSchema; } idx = YACItemsGetByKey(items, cer->load, "ku"); - if (idx != -1) { + if (idx != 0) { item = &(items->list[idx]); if (item->atom.v.list.len == 0) { (*failReason) = "empty /load/v/ku"; @@ -66,7 +65,7 @@ YACCerParse( } idx = YACItemsGetByKey(items, cer->load, "pub"); { - if (idx == -1) { + if (idx == 0) { (*failReason) = "no /load/v/pub"; return YACErrUnsatisfiedSchema; } @@ -77,19 +76,18 @@ YACCerParse( } idx = items->list[idx].atom.v.list.head; cer->pub = idx; - while (idx != -1) { - if (YACItemsGetByKeyAndType(items, idx, "a", YACItemStr) == -1) { + while (idx != 0) { + if (YACItemsGetByKeyAndType(items, idx, "a", YACItemStr) == 0) { (*failReason) = "no /load/v/pub/a"; return YACErrUnsatisfiedSchema; } - if (YACItemsGetByKeyAndType(items, idx, "v", YACItemBin) == -1) { + if (YACItemsGetByKeyAndType(items, idx, "v", YACItemBin) == 0) { (*failReason) = "no /load/v/pub/v"; return YACErrUnsatisfiedSchema; } { - ptrdiff_t pkidIdx = - YACItemsGetByKeyAndType(items, idx, "id", YACItemUUID); - if (pkidIdx == -1) { + size_t pkidIdx = YACItemsGetByKeyAndType(items, idx, "id", YACItemUUID); + if (pkidIdx == 0) { (*failReason) = "no /load/v/pub/id"; return YACErrUnsatisfiedSchema; } @@ -100,7 +98,7 @@ YACCerParse( } cer->sub = YACItemsGetByKey(items, cer->load, "sub"); { - if (cer->sub == -1) { + if (cer->sub == 0) { (*failReason) = "no /load/v/sub"; return YACErrUnsatisfiedSchema; } @@ -114,13 +112,13 @@ YACCerParse( return YACErrUnsatisfiedSchema; } } - if (YACItemsGetByKey(items, cer->load, "crit") != -1) { + if (YACItemsGetByKey(items, cer->load, "crit") != 0) { (*failReason) = "/load/v/crit is unsupported"; return YACErrUnsatisfiedSchema; } - ptrdiff_t sigsIdx = YACItemsGetByKey(items, 0, "sigs"); + size_t sigsIdx = YACItemsGetByKey(items, 0, "sigs"); { - if (sigsIdx == -1) { + if (sigsIdx == 0) { (*failReason) = "no /sigs"; return YACErrUnsatisfiedSchema; } @@ -129,54 +127,54 @@ YACCerParse( (*failReason) = "len(/load/sigs) != 1"; return YACErrUnsatisfiedSchema; } - ptrdiff_t sigIdx = items->list[sigsIdx].atom.v.list.head; + size_t sigIdx = items->list[sigsIdx].atom.v.list.head; cer->sig = sigIdx; - while (sigIdx != -1) { - if (YACItemsGetByKey(items, sigIdx, "hash") != -1) { + while (sigIdx != 0) { + if (YACItemsGetByKey(items, sigIdx, "hash") != 0) { (*failReason) = "unexpected /sigs/./hash met"; return YACErrUnsatisfiedSchema; } { idx = YACItemsGetByKey(items, sigIdx, "sign"); - if (idx == -1) { + if (idx == 0) { (*failReason) = "no /sigs/./sign"; return YACErrUnsatisfiedSchema; } - if (YACItemsGetByKeyAndType(items, idx, "a", YACItemStr) == -1) { + if (YACItemsGetByKeyAndType(items, idx, "a", YACItemStr) == 0) { (*failReason) = "no /sigs/./sign/a"; return YACErrUnsatisfiedSchema; } - if (YACItemsGetByKeyAndType(items, idx, "v", YACItemBin) == -1) { + if (YACItemsGetByKeyAndType(items, idx, "v", YACItemBin) == 0) { (*failReason) = "no /sigs/./sign/v"; return YACErrUnsatisfiedSchema; } } { idx = YACItemsGetByKey(items, sigIdx, "tbs"); - if (idx == -1) { + if (idx == 0) { (*failReason) = "no /sigs/./tbs"; return YACErrUnsatisfiedSchema; } { - ptrdiff_t cidIdx = + size_t cidIdx = YACItemsGetByKeyAndType(items, idx, "cid", YACItemUUID); - if (cidIdx == -1) { + if (cidIdx == 0) { (*failReason) = "no /sigs/./tbs/cid"; return YACErrUnsatisfiedSchema; } cer->cid = items->list[cidIdx].atom.v.uuid; } { - ptrdiff_t sidIdx = + size_t sidIdx = YACItemsGetByKeyAndType(items, idx, "sid", YACItemUUID); - if (sidIdx == -1) { + if (sidIdx == 0) { (*failReason) = "no /sigs/./tbs/sid"; return YACErrUnsatisfiedSchema; } cer->sid = items->list[sidIdx].atom.v.uuid; } idx = YACItemsGetByKeyAndType(items, idx, "exp", YACItemList); - if (idx == -1) { + if (idx == 0) { (*failReason) = "no /sigs/./tbs/exp"; return YACErrUnsatisfiedSchema; } @@ -189,19 +187,19 @@ YACCerParse( (*failReason) = "len(/sigs/./tbs/exp) != 2"; return YACErrUnsatisfiedSchema; } - err = YACTAI64ToTimeval( + err = YACTAI64ToTimespec( &(cer->since), items->list[idx + 1].atom.v.str.ptr, items->list[idx + 1].atom.v.str.len); - if ((err != YACErrNo) || (cer->since.tv_usec != 0)) { + if ((err != YACErrNo) || (cer->since.tv_nsec != 0)) { (*failReason) = "bad /sigs/./tbs/exp/since value"; return YACErrUnsatisfiedSchema; } - err = YACTAI64ToTimeval( + err = YACTAI64ToTimespec( &(cer->till), items->list[idx + 2].atom.v.str.ptr, items->list[idx + 2].atom.v.str.len); - if ((err != YACErrNo) || (cer->till.tv_usec != 0)) { + if ((err != YACErrNo) || (cer->till.tv_nsec != 0)) { (*failReason) = "bad /sigs/./tbs/exp/till value"; return YACErrUnsatisfiedSchema; } @@ -219,7 +217,7 @@ YACCerVerify( struct YACCer *cer, struct YACCer *pool, const size_t poolLen, - struct YACCerVerifyOpts opts) + const struct YACCerVerifyOpts opts) { if (opts.t.tv_sec <= cer->since.tv_sec) { (*failReason) = "unsatisfied since"; @@ -244,7 +242,7 @@ YACCerVerify( &((*verifier)->items), (*verifier)->pub, "a")]); struct YACItem *pubV = &((*verifier)->items.list[YACItemsGetByKey( &((*verifier)->items), (*verifier)->pub, "v")]); - ptrdiff_t signIdx = YACItemsGetByKey(&(cer->items), cer->sig, "sign"); + size_t signIdx = YACItemsGetByKey(&(cer->items), cer->sig, "sign"); struct YACItem *sigV = &(cer->items.list[YACItemsGetByKey(&(cer->items), signIdx, "v")]); { @@ -259,7 +257,7 @@ YACCerVerify( } const size_t cap = 1 << 10; unsigned char buf[1 << 10] = {0}; - ptrdiff_t off = 0; + size_t off = 0; { const size_t items = 5; struct YACItem tbsItems[5]; @@ -284,43 +282,43 @@ YACCerVerify( tbsItems[3].next = 4; tbsItems[4].atom.typ = YACItemNIL; - tbsItems[4].next = -1; + tbsItems[4].next = 0; - if (YACItemsEncode(&tbs, 0, &off, buf, cap) != 0) { - (*failReason) = "can not prepare tbs"; + if (!YACItemsEncode(&tbs, 0, &off, buf, cap)) { + (*failReason) = "can not prepare tbs: start"; return false; } } off -= 2; // strip off NIL and EOC, continue map generation - if (YACItemsEncode(&(cer->items), cer->load, &off, buf, cap) != 0) { - (*failReason) = "can not prepare tbs"; + if (!YACItemsEncode(&(cer->items), cer->load, &off, buf, cap)) { + (*failReason) = "can not prepare tbs: load"; return false; } { - ptrdiff_t diff = YACAtomStrEncode( - buf + off, cap - (size_t)off, (const unsigned char *)"tbs", 3); - if (diff < 1) { - (*failReason) = "can not prepare tbs"; + size_t got = 0; + if (!YACAtomStrEncode( + &got, buf + off, cap - off, (const unsigned char *)"tbs", 3)) { + (*failReason) = "can not prepare tbs: tbs key"; return false; } - off += diff; + off += got; } - if (YACItemsEncode( + if (!YACItemsEncode( &(cer->items), YACItemsGetByKey(&(cer->items), cer->sig, "tbs"), &off, buf, - cap) != 0) { - (*failReason) = "can not prepare tbs"; + cap)) { + (*failReason) = "can not prepare tbs: tbs"; return false; } { - ptrdiff_t diff = YACAtomEOCEncode(buf + off, cap - (size_t)off); - if (diff < 1) { - (*failReason) = "can not prepare tbs"; + size_t got = 0; + if (!YACAtomEOCEncode(&got, buf + off, cap - off)) { + (*failReason) = "can not prepare tbs: eoc"; return false; } - off += diff; + off += got; } for (size_t i = 0; i < opts.sigVerifiersLen; i++) { if (!YACStrEqual(&(pubA->atom), opts.sigVerifiers[i].algo)) { @@ -335,7 +333,7 @@ YACCerVerify( pubV->atom.v.str.ptr, pubV->atom.v.str.len, buf, - (size_t)off); + off); } (*failReason) = "no signature verifier found"; return false; diff --git a/cyac/lib/pki/cer.h b/cyac/lib/pki/cer.h index 052a0ab..e72b709 100644 --- a/cyac/lib/pki/cer.h +++ b/cyac/lib/pki/cer.h @@ -3,28 +3,28 @@ #include #include -#include +#include #include "../err.h" #include "../items.h" struct YACCer { struct YACItems items; - ptrdiff_t load; - ptrdiff_t pub; - ptrdiff_t sub; - ptrdiff_t sig; + size_t load; + size_t pub; + size_t sub; + size_t sig; const unsigned char *cid; const unsigned char *pkid; const unsigned char *sid; - struct timeval since; - struct timeval till; + struct timespec since; + struct timespec till; }; enum YACErr YACCerParse( struct YACCer *, - ptrdiff_t *off, + size_t *off, char **failReason, const unsigned char *buf, const size_t len); @@ -46,7 +46,7 @@ struct YACCerSigVerifier { }; struct YACCerVerifyOpts { - struct timeval t; + struct timespec t; struct YACCerSigVerifier *sigVerifiers; size_t sigVerifiersLen; }; @@ -58,6 +58,6 @@ YACCerVerify( struct YACCer *cer, struct YACCer *pool, const size_t poolLen, - struct YACCerVerifyOpts opts); + const struct YACCerVerifyOpts opts); #endif // YAC_CER_H diff --git a/cyac/lint/.clang-format b/cyac/lint/.clang-format new file mode 100644 index 0000000..c199ca8 --- /dev/null +++ b/cyac/lint/.clang-format @@ -0,0 +1,18 @@ +{ + BasedOnStyle: llvm, + ColumnLimit: 88, + IndentWidth: 4, + AlignAfterOpenBracket: AlwaysBreak, + AlignConsecutiveAssignments: false, + AllowAllParametersOfDeclarationOnNextLine: false, + AllowShortBlocksOnASingleLine: true, + AlwaysBreakAfterReturnType: TopLevel, + BinPackArguments: false, + BinPackParameters: false, + BreakBeforeTernaryOperators: false, + BreakStringLiterals: false, + BreakBeforeBraces: Custom, + BraceWrapping: { + AfterFunction: true, + }, +} diff --git a/cyac/lint/iwyu-maps.imp b/cyac/lint/iwyu-maps.imp new file mode 100644 index 0000000..446e7e9 --- /dev/null +++ b/cyac/lint/iwyu-maps.imp @@ -0,0 +1,5 @@ +[ + { symbol: ["CLOCK_REALTIME", "private", "", "public"] }, + { symbol: ["PTRDIFF_MAX", "private", "", "public"] }, + { symbol: ["SIZE_MAX", "private", "", "public"] }, +] diff --git a/gyac/dec.go b/gyac/dec.go index 5bc7a92..459b7c4 100644 --- a/gyac/dec.go +++ b/gyac/dec.go @@ -65,23 +65,22 @@ func (raw *Raw) String() string { } var ( - ErrNotEnough = errors.New("not enough data") - ErrLenNonMinimal = errors.New("non-minimal len") - ErrLenTooBig = errors.New("string len >1<<60") - ErrIntZeroByte = errors.New("zero byte int") - ErrUnknownType = errors.New("unknown type") - ErrBadUTF8 = errors.New("invalid UTF-8") - ErrMapBadKey = errors.New("map bad key") - ErrMapUnordered = errors.New("map unordered") - ErrMapBadVal = errors.New("map no value") - ErrBlobBadLen = errors.New("bad blob len") - ErrBlobBadAtom = errors.New("blob unexpected atom") - ErrBlobShortChunk = errors.New("blob short chunk") - ErrBlobBadTerm = errors.New("blob bad terminator") + ErrNotEnough = errors.New("not enough data") + ErrLenNonMinimal = errors.New("non-minimal len") + ErrLenTooBig = errors.New("string len >1<<60") + ErrIntNonMinimal = errors.New("int non minimal") + ErrUnknownType = errors.New("unknown type") + ErrBadUTF8 = errors.New("invalid UTF-8") + ErrMapBadKey = errors.New("map bad key") + ErrMapUnordered = errors.New("map unordered") + ErrMapNoVal = errors.New("map no value") + ErrBlobBadLen = errors.New("blob bad len") + ErrBlobBadAtom = errors.New("blob unexpected atom") + ErrBlobBadTerm = errors.New("blob bad terminator") ) func AtomDecode(buf []byte) (item *Item, off int, err error) { - off++ + off = 1 if len(buf) < 1 { err = ErrNotEnough return @@ -110,7 +109,7 @@ func AtomDecode(buf []byte) (item *Item, off int, err error) { return } ul := FromBE(buf[1 : 1+ll]) - if ul > (1 << 60) { + if ul > (1 << 63) { err = ErrLenTooBig return } @@ -121,6 +120,10 @@ func AtomDecode(buf []byte) (item *Item, off int, err error) { } } off += l + if off <= 0 { + err = ErrLenTooBig + return + } if len(buf) < off { err = ErrNotEnough return @@ -163,7 +166,7 @@ func AtomDecode(buf []byte) (item *Item, off int, err error) { return } if buf[1] == 0 { - err = ErrIntZeroByte + err = ErrIntNonMinimal return } if l > 8 { @@ -173,13 +176,18 @@ func AtomDecode(buf []byte) (item *Item, off int, err error) { } v := FromBE(buf[1 : 1+l]) if v < 32 { - err = ErrLenNonMinimal + err = ErrIntNonMinimal return } if item.Typ() == ItemUInt { item.V = v } else { - item.V = -1 - int64(v) + if v >= (1 << 63) { + item.T = byte(ItemRaw) + item.V = &Raw{T: AtomType(buf[0]), V: buf[1 : 1+l]} + } else { + item.V = -1 - int64(v) + } } return } @@ -219,7 +227,7 @@ func AtomDecode(buf []byte) (item *Item, off int, err error) { err = ErrBlobBadLen return } - if chunkLen > (1 << 60) { + if chunkLen >= (1 << 63) { err = ErrLenTooBig return } @@ -353,7 +361,7 @@ func DecodeItem(buf []byte) (item *Item, tail []byte, err error) { return } if sub.T == byte(ItemEOC) { - err = ErrMapBadVal + err = ErrMapNoVal return } v[keyPrev] = sub @@ -374,7 +382,7 @@ func DecodeItem(buf []byte) (item *Item, tail []byte, err error) { switch sub.T { case byte(ItemNIL): if len(buf) <= chunkLen { - err = ErrBlobShortChunk + err = ErrNotEnough return } v.Chunks = append(v.Chunks, buf[:chunkLen])