-
Notifications
You must be signed in to change notification settings - Fork 0
Refine recursive mode design: type conflicts, cycle detection, delete semantics #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,7 +10,7 @@ Tento dokument popisuje návrh implementace volby `--recursive` pro nástroj blo | |||||||
|
|
||||||||
| 1. **Jednosměrný tok dat** - zachován stávající model: checksum → retrieve → save | ||||||||
| 2. **Přenos pouze rozdílů** - přečtou se a zahashují všechny soubory na obou stranách, přenesou se jen změněné bloky | ||||||||
| 3. **Deterministické pořadí** - položky se zpracovávají v abecedním pořadí relativních cest (lexikografické řazení UTF-8 bytů), což zajišťuje reprodukovatelné chování | ||||||||
| 3. **Deterministické pořadí** - checksum odesílá položky v abecedním pořadí relativních cest (lexikografické řazení UTF-8 bytů). Retrieve odpovídá ve stejném pořadí, pak přidává nové položky ze source (abecedně), a nakonec příkazy `remv`. Toto zajišťuje reprodukovatelné chování a správné pořadí vytváření (rodiče před potomky). | ||||||||
|
|
||||||||
| ## Návrh protokolu | ||||||||
|
|
||||||||
|
|
@@ -245,17 +245,19 @@ done | |||||||
| c. Pro každý `'file'` z dest: | ||||||||
| - Přidat cestu do `seen_paths` | ||||||||
| - Zkontrolovat on-demand, jestli soubor existuje na source | ||||||||
| - Pokud existuje: porovnat hashe, poslat `'file'` + změněné datové bloky + `'meta'` | ||||||||
| - Pokud existuje jako soubor: porovnat hashe, poslat `'file'` + změněné datové bloky + `'meta'` | ||||||||
| - Pokud existuje jako adresář: vypsat warning "type changed: file → dir", přeskočit | ||||||||
| - Pokud neexistuje na source: přidat cestu do `to_delete` | ||||||||
| d. Pro každý `'dire'` z dest: | ||||||||
| - Přidat cestu do `seen_paths` | ||||||||
| - Zkontrolovat on-demand, jestli adresář existuje na source | ||||||||
| - Pokud existuje: poslat `'dire'` + `'dmet'` | ||||||||
| - Pokud existuje jako adresář: poslat `'dire'` + `'dmet'` | ||||||||
| - Pokud existuje jako soubor: vypsat warning "type changed: dir → file", přeskočit | ||||||||
|
||||||||
| - Pokud existuje jako soubor: vypsat warning "type changed: dir → file", přeskočit | |
| - Pokud existuje jako soubor: vypsat warning "type changed: dir → file", cesta zůstává v `seen_paths` (nesmí být znovu poslána jako nová položka ve kroku (e)), přeskočit |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The algorithm specifies sending remv commands for items in to_delete but doesn't specify the order. Section "Pořadí mazání (--delete)" at line 407 states that remv commands should be sorted in descending order by path depth (children before parents) to enable proper deletion. The algorithm should clarify that remv commands are sent in descending depth order, or that they use recursive deletion.
| - Poslat `'remv'` pro položky v `to_delete` (save bez `--delete` je ignoruje) | |
| - Seřadit položky v `to_delete` podle hloubky cesty sestupně (potomci před rodiči, při stejné hloubce např. abecedně podle cesty) | |
| - Poslat `'remv'` pro položky v `to_delete` v tomto pořadí (save bez `--delete` je ignoruje) |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The design of walk_directory() with followlinks=True and always following symlinks ("Symlinky se následují (followlinks=True)") introduces a path traversal / data exfiltration risk: an unprivileged user can place a symlink inside the synced tree pointing to any path readable by the blockcopy process (e.g., /etc/shadow), and the recursive sync will read and transfer the target contents under the symlink path. In multi-user or partially untrusted source directories, this lets less-privileged users cause the tool (often running with elevated privileges) to leak arbitrary files outside the intended source root. To mitigate this, avoid following symlinks by default for recursive mode (treat them as symlinks or skip them), or make symlink following an explicit opt-in with strict checks that the resolved target remains within the allowed source root and does not cross sensitive filesystem boundaries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The algorithm for handling type conflicts appears incomplete. When a file on dest exists as a directory on source (line 249), the item is skipped but it's unclear whether the path is added to
seen_paths. If it's not added toseen_paths, then step (e) at line 257-259 would later send the directory and all its children as new items when walking the source. However, save cannot create these because the conflicting file still exists on dest. The algorithm should clarify that type-conflicted paths should be added toseen_pathsto prevent attempting to send the source version, and should also skip all descendants of type-conflicted directories to avoid attempting impossible operations.