Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

**Collective memory, encrypted.**

[![tests: 416](https://img.shields.io/badge/tests-416-brightgreen?style=flat)](test/)
[![tests: 419](https://img.shields.io/badge/tests-419-brightgreen?style=flat)](test/)
![lints: 8](https://img.shields.io/badge/lints-8-blue?style=flat)
[![license: MIT](https://img.shields.io/badge/license-MIT-blue?style=flat)](LICENSE)

Expand Down
18 changes: 17 additions & 1 deletion lib/obfuscate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ build_obfuscation_plan() {
if ! awk -F '\t' -v OFS='\t' -v candidates="$candidates" '
FILENAME != candidates {
if ($1 != "") {
if (($1 in id_names) && id_names[$1] != $2) duplicate_ids[$1] = 1
id_names[$1] = $2
ids[$1] = 1
if (!($2 in names)) names[$2] = $1
}
Expand All @@ -97,7 +99,11 @@ build_obfuscation_plan() {
if (base ~ /^[a-f0-9]{8}$/) {
print "invalid", "-", relpath
} else if (relpath in names) {
print "known", names[relpath], relpath
if (names[relpath] in duplicate_ids) {
print "collision", names[relpath], relpath
} else {
print "known", names[relpath], relpath
}
} else {
print "new", "-", relpath
}
Expand All @@ -114,6 +120,16 @@ build_obfuscation_plan() {
refuse_if_hex_basename "$relpath"
return 1
fi
if [ "$kind" = "collision" ]; then
rm -rf "$workspace"
echo "Error: manifest ID '$id' maps to multiple readable paths" >&2
return 1
fi
if [ "$kind" = "known" ] && { [ -e "$notes_dir/$id" ] || [ -L "$notes_dir/$id" ]; }; then
rm -rf "$workspace"
echo "Error: refusing to overwrite existing obfuscated path: $id" >&2
return 1
fi
done < "$plan_file"

rm -rf "$workspace"
Expand Down
51 changes: 51 additions & 0 deletions test/obfuscate.bats
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,57 @@ setup() {
[ -f "$NOTES_CALLER_PWD/notes/$alpha_id" ]
}

@test "obfuscate refuses to overwrite an existing known-ID destination" {
notes obfuscate
local alpha_id
alpha_id=$(grep $'\talpha\.md$' "$NOTES_CALLER_PWD/notes/.manifest" | cut -f1)
git -C "$NOTES_CALLER_PWD" commit -q --no-verify -m "obfuscated"

# Simulate an interrupted or stale state containing both representations.
printf 'dirty readable content\n' > "$NOTES_CALLER_PWD/notes/alpha.md"
local obfuscated_before
obfuscated_before=$(cat "$NOTES_CALLER_PWD/notes/$alpha_id")

run notes obfuscate alpha.md

[ "$status" -ne 0 ]
[[ "$output" == *"refusing to overwrite existing obfuscated path: $alpha_id"* ]]
[ "$(cat "$NOTES_CALLER_PWD/notes/$alpha_id")" = "$obfuscated_before" ]
[ "$(cat "$NOTES_CALLER_PWD/notes/alpha.md")" = "dirty readable content" ]
}

@test "obfuscate refuses to replace a dangling known-ID symlink" {
notes obfuscate
local alpha_id
alpha_id=$(grep $'\talpha\.md$' "$NOTES_CALLER_PWD/notes/.manifest" | cut -f1)
rm "$NOTES_CALLER_PWD/notes/$alpha_id"
printf 'readable content\n' > "$NOTES_CALLER_PWD/notes/alpha.md"
ln -s missing-target "$NOTES_CALLER_PWD/notes/$alpha_id"

run notes obfuscate alpha.md

[ "$status" -ne 0 ]
[[ "$output" == *"refusing to overwrite existing obfuscated path: $alpha_id"* ]]
[ -L "$NOTES_CALLER_PWD/notes/$alpha_id" ]
[ "$(readlink "$NOTES_CALLER_PWD/notes/$alpha_id")" = "missing-target" ]
[ "$(cat "$NOTES_CALLER_PWD/notes/alpha.md")" = "readable content" ]
}

@test "obfuscate refuses a manifest ID shared by planned readable paths" {
notes obfuscate
local alpha_id
alpha_id=$(grep $'\talpha\.md$' "$NOTES_CALLER_PWD/notes/.manifest" | cut -f1)
notes deobfuscate
printf '%s\tbeta.md\n' "$alpha_id" >> "$NOTES_CALLER_PWD/notes/.manifest"

run notes obfuscate alpha.md beta.md

[ "$status" -ne 0 ]
[[ "$output" == *"manifest ID '$alpha_id' maps to multiple readable paths"* ]]
[ -f "$NOTES_CALLER_PWD/notes/alpha.md" ]
[ -f "$NOTES_CALLER_PWD/notes/beta.md" ]
}

@test "full obfuscate batches Fold-scale known-entry classification and staging" {
local count=535 i=1 id name mock_bin command real_command call_log
rm -rf "$NOTES_CALLER_PWD/notes"
Expand Down
Loading