[BUG][high] --backup / --suffix broken: NULL-vs-empty wire loss (plain --backup fails every file; --suffix silently keeps no backup) #252

Closed
opened 2026-09-05 12:08:20 +02:00 by TapTap · 1 comment
Owner

Found by code review + empirical test of dev (9f8b588).

Where: src/shared/config.c:276,303-305 (unset strings sent as ""), :358-360,388-394 (received back as non-NULL ""); consumed src/shared/file_receive.c:32-43,105-133.

Problem: Client backup_dir/suffix default to NULL; the wire format has no presence bit, so they travel as "" and the server reconstructs them as non-NULL "". file_save_to_disk treats non-NULL as user-configured:

  • Plain --backup (no --suffix): server suffix becomes "", fails backup_suffix[0]=='\0' guard -> every file rejected with Invalid file or path received, sync fails.
  • --backup --suffix .bak: server backup_dir=="" treated as a real dir == root -> backup is a rename-to-itself no-op, old version overwritten, no backup retained (verified).

Fix: Preserve NULL-vs-empty on the wire (presence flags) OR canonicalize received "" back to NULL for options whose default is unset (backup_dir, suffix, temp_dir, partial_dir).

Regression tests required: unit config round-trip (NULL vs "") + integration for --backup / --backup-dir / --suffix.

Found by code review + empirical test of `dev` (9f8b588). **Where:** src/shared/config.c:276,303-305 (unset strings sent as `""`), :358-360,388-394 (received back as non-NULL `""`); consumed src/shared/file_receive.c:32-43,105-133. **Problem:** Client `backup_dir`/`suffix` default to NULL; the wire format has no presence bit, so they travel as `""` and the server reconstructs them as non-NULL `""`. file_save_to_disk treats non-NULL as user-configured: - Plain `--backup` (no `--suffix`): server suffix becomes `""`, fails `backup_suffix[0]=='\0'` guard -> **every file rejected** with `Invalid file or path received`, sync fails. - `--backup --suffix .bak`: server `backup_dir==""` treated as a real dir == root -> backup is a rename-to-itself no-op, old version overwritten, **no backup retained** (verified). **Fix:** Preserve NULL-vs-empty on the wire (presence flags) OR canonicalize received `""` back to NULL for options whose default is unset (backup_dir, suffix, temp_dir, partial_dir). Regression tests required: unit config round-trip (NULL vs "") + integration for --backup / --backup-dir / --suffix.
Author
Owner

Resolved on dev (HEAD f7c6c91).

Fixed on dev via fix/receiver-correctness (14c064a): empty wire strings canonicalized back to NULL for backup_dir/temp_dir/partial_dir/suffix; plain --backup now keeps ~, --backup --suffix keeps .bak. Unit (test_config.c) + integration (TestBackup) coverage added.

CI run #461: all jobs green (lint, build-and-test, sanitizers address+undefined, fuzz-build, coverage, valgrind). Unit 25/25, integration 83 passed / 10 skipped / 1 xpassed. Closing.

**Resolved on `dev`** (HEAD f7c6c91). Fixed on dev via fix/receiver-correctness (14c064a): empty wire strings canonicalized back to NULL for backup_dir/temp_dir/partial_dir/suffix; plain --backup now keeps <file>~, --backup --suffix keeps <file>.bak. Unit (test_config.c) + integration (TestBackup) coverage added. CI run #461: all jobs green (lint, build-and-test, sanitizers address+undefined, fuzz-build, coverage, valgrind). Unit 25/25, integration 83 passed / 10 skipped / 1 xpassed. Closing.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: TapTap/FastSync#252