d247213bdd9d
refuse a steal address whose repo is not a name Kepr serves, before it reaches a URL or a folder (3.0.107)
- time
- 2026-09-28 05:15 UTC · 2 weeks ago
- machine
- Junes-MacBook-Pro.local
- agent
- claude-opus-5-5
- session
- fix a2 review findings
- parent
- 7ec030db3e06
↓ koh-d247213b.tar.gzatlas at this save
files changed4 files
VERSION+1 −1src/cli/cmd_steal.v+9 −3tests/cli_test.v+3 −1v.mod+1 −1src/cli/cmd_steal.v+9 −3
@@ -385,15 +385,21 @@385385 386386 // web_address splits a `<host>/<repo>` argument out of a steal name: a slash makes it an address387387 // (`kepr.uk/nina`, `http://127.0.0.1:3917/shipped`), a bare name is this machine's own remote. An388-// addressed value that is missing either half is an error, never a name.388+// addressed value that is missing either half is an error, never a name. The repo half becomes a389+// URL path segment and a folder here, so it must be a name Kepr serves: letters, digits, `.`, `_`390+// and `-`, and never `.` or `..`.389391 fn web_address(value string) ![]string {390392 if !value.contains('/') {391393 return []string{}392394 }393395 repo := value.all_after_last('/')394396 host := value.all_before_last('/')395- if repo == '' || host == '' {396- return error('"${value}" is not <host>/<repo>')397+ if host == '' || repo in ['', '.', '..'] || !repo.bytes().all(it.is_alnum() || it in [398+ `.`,399+ `_`,400+ `-`,401+ ]) {402+ return error('"${value}" is not <host>/<repo> — a repo name is letters, digits, ., _ and -')397403 }398404 return [host, repo]399405 }tests/cli_test.v+3 −1
@@ -1487,7 +1487,9 @@14871487 home := temp_repo('steal-address-home')14881488 defer { os.rmdir_all(outside) or {} }14891489 defer { os.rmdir_all(home) or {} }1490- for bad in ['kepr.uk/', '/shipped', 'kepr.uk/'] {1490+ // The repo half becomes a URL path segment and a folder here, so it is a name Kepr serves.1491+ for bad in ['kepr.uk/', '/shipped', 'kepr.uk/..', 'kepr.uk/.', 'kepr.uk/a b', 'kepr.uk/nina?x',1492+ 'kepr.uk/nina#x', 'kepr.uk/nína'] {14911493 refused := run_home(outside, home, 'steal', bad)14921494 assert refused.code == 1, bad14931495 assert refused.err.contains('is not <host>/<repo>'), '${bad}: ${refused.err}'v.mod+1 −1
@@ -1,6 +1,6 @@11 Module {22 name: 'koh3'3- version: '3.0.106'3+ version: '3.0.107'44 description: 'One SQLite file per repo, one line of history.'55 license: 'MIT'66 }