str, bench: three checks that guard nothing

sinit sets s->n = 0 as its first statement and no failure path restores
it, so stail's sclear after a failed sinit could never change anything;
say so in sinit's comment instead, where the contract belongs.  bench
compared a uintmax_t against UINT64_MAX and a size_t against UINT64_MAX,
both constant on any host this builds for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-18 16:14:16 +09:00
parent 4802b6593e
commit bdf05e3c4a
2 changed files with 5 additions and 5 deletions

View File

@@ -99,7 +99,7 @@ iterations(char *s)
goto Bad; goto Bad;
errno = 0; errno = 0;
n = strtoumax(s, &end, 10); n = strtoumax(s, &end, 10);
if(errno != 0 || *end != '\0' || n == 0 || n > UINT64_MAX) if(errno != 0 || *end != '\0' || n == 0)
goto Bad; goto Bad;
return n; return n;
Bad: Bad:
@@ -157,7 +157,7 @@ main(int argc, char **argv)
loadkeys(argv[1]); loadkeys(argv[1]);
niter = argc == 3 ? iterations(argv[2]) : 1000; niter = argc == 3 ? iterations(argv[2]) : 1000;
if(nkeys > UINT64_MAX || niter > UINT64_MAX / nkeys){ if(niter > UINT64_MAX / nkeys){
fprintf(stderr, "iteration count overflows key total\n"); fprintf(stderr, "iteration count overflows key total\n");
exit(1); exit(1);
} }

6
str.c
View File

@@ -1,7 +1,8 @@
#include "dat.h" #include "dat.h"
#include "fn.h" #include "fn.h"
/* Fills s from n bytes of UTF-8; whole, valid, and at most Maxrunes. */ /* Fills s from n bytes of UTF-8; whole, valid, and at most Maxrunes.
* Anything else leaves s empty. */
int int
sinit(Str *s, char *src, int n) sinit(Str *s, char *src, int n)
{ {
@@ -35,8 +36,7 @@ stail(Str *s, char *src, int n)
nr = utfnlen(src, n); nr = utfnlen(src, n);
for(p = src; nr > Maxrunes; nr--) for(p = src; nr > Maxrunes; nr--)
p += chartorune(&r, p); p += chartorune(&r, p);
if(!sinit(s, p, n - (p - src))) sinit(s, p, n - (p - src));
sclear(s);
} }
void void