]> Cypherpunks repositories - keks.git/commitdiff
Ability to limit number of parse cycles
authorSergey Matveev <stargrave@stargrave.org>
Thu, 23 Jan 2025 07:47:24 +0000 (10:47 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Thu, 23 Jan 2025 07:47:24 +0000 (10:47 +0300)
c/cmd/pp/pp.c
go/cmd/pp/main.go

index a5964462c30934217a115afaab2910fc5860fbf456511bb61a5dcaa643efd494..070dc1505c0f75b3e79517e6ec39a0e8e641bbf972f92b95c3de9a5a903741e5 100644 (file)
@@ -255,6 +255,7 @@ main(int argc, char **argv)
     bool noTotals = false;
     bool onlyTotals = false;
     ptrdiff_t itemsInitialLen = 2048;
+    ptrdiff_t maxParseCycles = PTRDIFF_MAX;
     struct option longopts[] = {
         {"max-str-len", required_argument, NULL, 'a'},
         {"do-encode", no_argument, NULL, 'b'},
@@ -262,6 +263,7 @@ main(int argc, char **argv)
         {"no-totals", no_argument, NULL, 'd'},
         {"only-totals", no_argument, NULL, 'e'},
         {"items-initial-len", required_argument, NULL, 'f'},
+        {"max-parse-cycles", required_argument, NULL, 'g'},
         {NULL, 0, NULL, 0}};
     int ch = 0;
     for (;;) {
@@ -310,6 +312,20 @@ main(int argc, char **argv)
             itemsInitialLen = (ptrdiff_t)tmp;
             break;
         }
+        case 'g': { // max-parse-cycles
+            errno = 0;
+            long tmp = strtol(optarg, NULL, 10);
+            if (errno != 0) {
+                fprintf(stderr, "--max-parse-cycles: %s\n", strerror(errno));
+                exit(EXIT_FAILURE);
+            }
+            if (tmp < 0) {
+                fputs("--max-parse-cycles: is negative\n", stderr);
+                exit(EXIT_FAILURE);
+            }
+            maxParseCycles = (ptrdiff_t)tmp;
+            break;
+        }
         case '?':
         default:
             usage();
@@ -353,6 +369,7 @@ main(int argc, char **argv)
     size_t off = 0;
     struct timespec started;
     struct timespec finished;
+    ptrdiff_t parseCycles = 0;
     while (off < len) {
         errno = 0;
         if (clock_gettime(CLOCK_MONOTONIC_PRECISE, &started) != 0) {
@@ -386,6 +403,10 @@ main(int argc, char **argv)
                 1000000000 * (finished.tv_sec - started.tv_sec) + finished.tv_nsec -
                     started.tv_nsec);
         }
+        parseCycles++;
+        if (parseCycles >= maxParseCycles) {
+            break;
+        }
     }
     if (off < len) {
         char *hex = HexEnc(buf + off, len - off);
index fcee45e77eaaaef5424f9a0bbe5adbf5f25a5117ad8051f126c622b607c92d7d..48fc6c1161b549ccc23c36507f4733bb78986751ee8e247a69fe1959feeff1e2 100644 (file)
@@ -32,7 +32,11 @@ import (
        "go.cypherpunks.su/tai64n/v4"
 )
 
-var MaxStrLen = flag.Uint("max-str-len", 40, "Maximal string length to print")
+var (
+       MaxStrLen      = flag.Uint("max-str-len", 40, "Maximal string length to print")
+       MaxParseCycles = flag.Uint64("max-parse-cycles", 1<<63,
+               "Maximal number of parse cycles to perform")
+)
 
 func prindent(depth int) {
        fmt.Print(strings.Repeat("  ", depth))
@@ -175,7 +179,7 @@ func main() {
        var off int64
        var ctx *keks.Decoder
        var err error
-       for {
+       for i := uint64(0); i < *MaxParseCycles; i++ {
                ctx = keks.NewDecoderFromReader(br, &keks.DecodeOpts{SaveOffsets: true})
                ctx.Read = off
                if _, err = ctx.Parse(); err != nil {
@@ -187,5 +191,5 @@ func main() {
                printer(ctx.Iter(), 1, false, false)
                off = ctx.Read
        }
-       fmt.Println(ctx.Read, "bytes")
+       fmt.Println(off, "bytes")
 }