ref: c370b53dcac6e4f542e0549e589e6e861d2590be
parent: 9f6b8e1dbc8af694eab3abaac1a529be89b8b0ff
author: Noam Preil <noam@pixelhero.dev>
date: Wed Sep 17 22:58:55 EDT 2025
base: fix U16GET
--- a/neoventi.h
+++ b/neoventi.h
@@ -1,5 +1,5 @@
#define U8GET(p) ((p)[0])
-#define U16GET(p) (((p)[0]<<8)|(p)[1])
+#define U16GET(p) ((u16int)(((p)[0]<<8)|(p)[1]))
#define U32GET(p) ((u32int)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
#define U64GET(p) (((u64int)U32GET(p)<<32)|(u64int)U32GET((p)+4))
#define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v)
--- a/notebook
+++ b/notebook
@@ -3288,4 +3288,63 @@
./6.neoventi: syncarenas: clump 1 needs repair, at address 4: arenarepair: corrupt
-...other than that part. Repair code might be wrong, - yeah. Wasn't adding the clump size to address during computation. That's fixed.
\ No newline at end of file
+...other than that part. Repair code might be wrong, - yeah. Wasn't adding the clump size to address during computation. That's fixed.
+
+Can I break it easily still? Let's find out :D
+
+Yeah, pretty easily too :(
+
+• Start neoventi
+• vac a nonexistent file
+• Kill neoventi
+• Relaunch
+
+Attempting repair of a clump at a negative address???
+
+Initializing neoventi build 5... Resuming: used 1527, block 0, blocksize 8192, offset 1527
+clumps: 5, 0
+validating clump 0, offset 0, block 8092
+attempting repair of clump 0 , at address 0validating clump 1, offset 25, block 8092
+attempting repair of clump 1 , at address -85internal error: invalid key6.neoventi 2582: suicide: sys: trap: fault read addr=0x0 pc=0x20536c
+
+So, first clump is address 0, offset 0. Second clump is offset 25.
+
+That should have an address of 0+38+25+38 == 101.
+
+Moreover, addr is a u64. It can't be negative!!
+Printed correctly, that's an address like 18446744073709551531
+
+How is that even possible?? addr starts at 0. It's then hit with += on values that are U16GET + 38. Did it wrap around and get changed type??
+
+I - wait a minute. U32GET(ci) should == arena->clumpmagic.
+
+Why is this U16GET(ci+1), that's _definitely_ wrong. What am I _writing_?
+
+...we _also_ don't _have_ vtarenawritedirectory. Okay, this bug is obvious. We're
+
+- Not writing the directory
+- Detecting the unsynced blocks on startup
+- Fucking them up when we go to write them, and/or reading uninited disk data
+
+Okay, so there's Clump and ClumpInfo. Clump _info_ is what's stored in the trailer. It doesn't _have_ magic, so that check is silly. What it has:
+
+u8 type
+u16 size
+u16 uncsize
+u160 sha1
+
+So, how are we to actually check it? The magic should be found at the actual _clump_, and we want to verify _that_, not the clump _info_.
+
+We can verify clumpinfo against the clump header in the arena proper. We have the address - we need to verify that the clump at that address is readable, mark it as corrupt if not.
+
+If it's not readable, we probably shouldn't adjust the clumpinfo, just skip it - we won't index it, so it won't be accessible, and avoiding _ever_ overwriting the arena is a good principle.
+
+...but we're already doing this properly. We're checking the magic at _the address in the arena_. The mistake is that we're _also_ looking for the magic by clumpinfo, but we're not overwriting it, so what's going on? Are we not writing it properly / reading nonsense from it? Shouldn't matter regardless, since address is, again, _a u64_, that's only ever having small u16s added to it. What is going on here.
+
+We also need to rethink the repair check - we don't need to repair clumps based on magic of the clumpinfo, what _can_ we check? Anything? Type != unset, maybe?
+
+addr 0, adding u16 4294967173 + 38
+
+...sign extension of what's supposed to be a u16?????? Is U16GET returning something not usable inline?
+
+Hahahahahahah was missing a cast in U16GET that was present in U32GET and U64GET, okay.
--
⑨