Bug fixes: composite PK, nl_to_sql sandbox, FK check, SQL injection, storage correctness
Critical fixes: - Composite PK: execInsert + validateConstraints use all PK columns - nl_to_sql: non-SELECT SQL no longer executed directly during validation - FK check: removed O(N) scanMemTable fallback, uses db.get() with SSTables - exprToSql: nkIdent wrapped in quotes to prevent SQL injection - restoreSchema: try/except around tokenize/parse for crash resilience - recovery.nim: lastTxnId tracking + putUnsafe/deleteUnsafe without WAL - SCRAM: verifyClientProof length check + DefaultIterationCount restored Storage fixes: - lsm.nim: SSTable sort order fixed (ascending), close() flushes all memtables - compaction.nim: tombstones preserved during compaction - wal.nim: header written for empty existing files, readEntries checks magic - btree.nim: B+ tree leaf split keeps boundary key - bloom.nim: deserialize raises on short data - mmap.nim: bounds checks for adviseWillNeed/DontNeed + posix.close() Protocol fixes: - zerocopy.nim: readString bounds check - wire.nim: deserializeValue 32-bit underflow check - auth.nim: JWT JSON escaping for claims - server.nim: readUint32BE bounds check + specific exception handling - raft.nim: readData checks + specific exception handling Tests: - Added Composite Primary Key test suite (4 tests) Build: 0 warnings, 0 errors
This commit is contained in:
@@ -54,14 +54,18 @@ proc openMmap*(path: string, mode: MmapMode = mmReadOnly): MmapFile =
|
||||
|
||||
let mapped = mmap(nil, fileSize, prot, flags, fd, 0)
|
||||
if mapped == MAP_FAILED:
|
||||
discard close(fd)
|
||||
discard posix.close(fd)
|
||||
return MmapFile(path: path, regions: @[], totalSize: 0, pageSize: PageSize)
|
||||
|
||||
# Kernel keeps the mapping alive independently of the fd; close it now
|
||||
# to avoid leaking one fd per SSTable.
|
||||
discard posix.close(fd)
|
||||
|
||||
let region = MmapRegion(
|
||||
data: cast[ptr UncheckedArray[byte]](mapped),
|
||||
size: fileSize,
|
||||
offset: 0,
|
||||
fd: fd,
|
||||
fd: -1,
|
||||
mode: mode,
|
||||
)
|
||||
|
||||
@@ -116,16 +120,21 @@ proc adviseRandom*(mf: MmapFile) =
|
||||
|
||||
proc adviseWillNeed*(mf: MmapFile, offset: int, size: int) =
|
||||
if mf.regions.len > 0:
|
||||
if offset < 0 or offset + size > mf.regions[0].size:
|
||||
return
|
||||
discard madvise(addr mf.regions[0].data[offset], size, MADV_WILLNEED)
|
||||
|
||||
proc adviseDontNeed*(mf: MmapFile, offset: int, size: int) =
|
||||
if mf.regions.len > 0:
|
||||
if offset < 0 or offset + size > mf.regions[0].size:
|
||||
return
|
||||
discard madvise(addr mf.regions[0].data[offset], size, MADV_DONTNEED)
|
||||
|
||||
proc close*(mf: MmapFile) =
|
||||
for region in mf.regions:
|
||||
discard munmap(region.data, region.size)
|
||||
discard close(cint(region.fd))
|
||||
if region.fd != -1:
|
||||
discard close(cint(region.fd))
|
||||
mf.regions.setLen(0)
|
||||
|
||||
proc size*(mf: MmapFile): int = mf.totalSize
|
||||
|
||||
Reference in New Issue
Block a user