nextcloud / nextcloud/desktop

PropagateUploadFileV1: upload silently marked successful when 0 bytes were sent

Open
#9,910 0 comments 3 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
3.9k
Forks
1k
Avg merge
1d 21h
Merged PRs (30d)
127

Description

## Summary

`PropagateUploadFileV1::slotPutFinished()` determines upload success based solely on whether the server returned an ETag:

```cpp
QByteArray etag = getEtagFromReply(job->reply());
_finished = etag.length() > 0;
```

If the server returns an ETag but stored 0 bytes (because the client sent an empty request body — e.g. a virtual file that was not materialised locally, or a connection that aborted after headers were sent), the upload is silently recorded as successful in the sync journal. The file is never retried.

## Steps to reproduce

1. Have files in a sync folder that are in a virtual/cloud-only state (not locally materialised)
2. Trigger a sync
3. Server logs: `Expected filesize of X bytes but read (from Nextcloud client) and wrote (to Nextcloud storage) 0 bytes`
4. Client shows "All synced!" — files are missing from the server but the client has no record of failure

## Expected behaviour

The upload should be marked as failed and retried on the next sync cycle.

## Actual behaviour

The upload is silently marked as successful. Files are permanently missing from the server until the user manually investigates.

## Root cause

`PropagateUploadFileNG` already handles this correctly by tracking `_sent` (bytes dispatched to the network) and requiring `_sent == _item->_size` before setting `_finished = true` (line 449). The V1 path has no equivalent check.

## Fix

A fix is available in the linked PR. It mirrors the NG approach: adds a `_sent` member to `PropagateUploadFileV1`, increments it per chunk in `startNextChunk()`, and changes the `_finished` condition to require both an ETag and `_sent == _fileToUpload._size`.

When `_finished` stays false on the final chunk, the existing error path already calls `done(SyncFileItem::NormalError, "The server did not acknowledge the last chunk")`, so the file is properly queued for retry.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.