diff --git a/TODOS.md b/TODOS.md index b2987e3..4f9e7c4 100644 --- a/TODOS.md +++ b/TODOS.md @@ -10,7 +10,7 @@ 5. Generate md and man pages again. -6. **db.odin:324-327** — Map iteration (`remote_set`) is non-deterministic. Same file can produce different JSON on each backup, causing spurious DB diffs. Sort remotes before storing. +6. Json may be an expensive encoding for remotes. Confirm with spall, and use null terminated strings if necessary. 7. Make sure official path separators are used when appropriate, rather than '/'. @@ -20,8 +20,6 @@ 10. **config.odin:178** — `search_paths` silently ignores `os.user_home_dir` error. If home is empty, `~` isn't expanded. Same class of bug as issue 3. -11. **db.odin:115** — `json.unmarshal_string` error not checked. Malformed JSON silently produces empty/partial data. - 12. **db.odin:352-353** — `hex.encode` error ignored. `string(hex_bytes)` aliases the byte slice. 13. **cmd_sync.odin:80, cmd_list.odin:33** — `make([]string, 2)` for table rows never freed. Leaks per row. Defer to memory pass. diff --git a/db.odin b/db.odin index 88dd604..22d29d4 100644 --- a/db.odin +++ b/db.odin @@ -219,7 +219,10 @@ db_list :: proc(db: ^Db) -> ([]EnvFile, bool) { remotes_json := string(sqlite.column_text(stmt, 1)) remotes: [dynamic]string = --- if len(remotes_json) > 0 { - json.unmarshal_string(remotes_json, &remotes, allocator = allocator) + err := json.unmarshal_string(remotes_json, &remotes, allocator = allocator) + if err != nil { + fmt.eprintf("Warning: malformed remotes JSON: %v\n", err) + } } path := clone_cstring(sqlite.column_text(stmt, 0), allocator) @@ -333,7 +336,10 @@ db_fetch :: proc(db: ^Db, path: string) -> (EnvFile, bool) { remotes_json := string(sqlite.column_text(stmt, 1)) remotes: [dynamic]string = --- if len(remotes_json) > 0 { - json.unmarshal_string(remotes_json, &remotes, allocator = allocator) + err := json.unmarshal_string(remotes_json, &remotes, allocator = allocator) + if err != nil { + fmt.eprintf("Warning: malformed remotes JSON: %v\n", err) + } } file_path := clone_cstring(sqlite.column_text(stmt, 0), allocator)