nautd: block adding a torrent that would overlap existing data

spawn_torrent parses each torrent's file list (at add and restore) and
refuses an add whose files would write where a registered torrent's data
lives (NAUT_ERR_EXIST). Magnets are checked once metadata is known is
out of scope; restore skips the check. webui surfaces it as HTTP 409.
Mark #10 done.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ookami125 2026-06-22 01:01:50 -04:00
parent 187e8f2db2
commit 7bbc1ee22c
5 changed files with 149 additions and 8 deletions

View file

@ -410,7 +410,9 @@ static bool serve_file(int fd, const char *request_path) {
return true;
}
static json_t *rpc_call_json(const char *method, json_t *params) {
static json_t *rpc_call_json_err(const char *method, json_t *params,
naut_err *out_err) {
if (out_err) *out_err = NAUT_ERR_INVAL;
if (!g_webui.host.call_rpc) return NULL;
char *request = json_dumps(params ? params : json_null(),
JSON_COMPACT | JSON_ENCODE_ANY);
@ -419,6 +421,7 @@ static json_t *rpc_call_json(const char *method, json_t *params) {
naut_err error = g_webui.host.call_rpc(g_webui.host.host_context,
method, request, &response);
free(request);
if (out_err) *out_err = error;
if (error != NAUT_OK || !response) {
free(response);
return NULL;
@ -430,6 +433,10 @@ static json_t *rpc_call_json(const char *method, json_t *params) {
return json;
}
static json_t *rpc_call_json(const char *method, json_t *params) {
return rpc_call_json_err(method, params, NULL);
}
static const char *json_string_or(const json_t *obj, const char *key,
const char *fallback) {
const char *value = json_string_value(json_object_get(obj, key));
@ -1402,12 +1409,18 @@ static void api_add(int fd, const char *body, size_t len) {
json_object_set_new(params, "category", json_string(category_name));
if (tags && json_array_size(tags) > 0)
json_object_set_new(params, "tags", json_deep_copy(tags));
json_t *result = rpc_call_json("add_torrent", params);
naut_err add_err = NAUT_OK;
json_t *result = rpc_call_json_err("add_torrent", params, &add_err);
json_decref(params);
json_decref(req);
if (!result) {
json_decref(tags);
http_text(fd, 502, "Bad Gateway", "add_torrent failed");
if (add_err == NAUT_ERR_EXIST)
http_text(fd, 409, "Conflict",
"this torrent's data would overlap an existing torrent; "
"choose a different save path");
else
http_text(fd, 502, "Bad Gateway", "add_torrent failed");
return;
}
uint64_t new_id = json_u64(result, "torrent_id");