Summary: | kio_sftp.so corrupts files when reading | ||
---|---|---|---|
Product: | [Unmaintained] kio | Reporter: | Albert Flügel <albert.fluegel> |
Component: | sftp | Assignee: | Andreas Schneider <asn> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | rdieter |
Priority: | NOR | ||
Version: | 4.14.1 | ||
Target Milestone: | --- | ||
Platform: | Fedora RPMs | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: | Patch to fix this issue with a Redhat-like build system |
Description
Albert Flügel
2015-01-01 15:55:04 UTC
I found a fix. Please check, if this is correct. At least here it fixes the problem. I replaced daeling with mFile->offset with a sftp_seek64 . Imo the mFile structure should be considered opaque, so fiddling with it's internals may lead to inconsistencies. The respective section in sftpProtocol::GetRequest::readChunks now reads: if (bytesread < request.expectedLength) { // If less data is read than expected - requeue the request data.resize(data.size() - (request.expectedLength - bytesread)); // Save current file offset // uint64_t oldOffset = mFile->offset; // mFile->offset = request.startOffset + bytesread; // Modify current request request.expectedLength -= bytesread; request.startOffset += bytesread; if (sftp_seek64(mFile, request.startOffset) < 0) { // Failed to continue reading return -1; } request.id = sftp_async_read_begin(mFile, request.expectedLength); // Restore the file offset // mFile->offset = oldOffset; if (request.id < 0) { // Failed to dispatch rerequest return -1; } return totalRead; } I've just tested it and it works without any issues for me. How big is the file you try to open? I think the code should use sftp_tell64() and sftp_seek64() here. kioslave/sftp/kio_sftp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kioslave/sftp/kio_sftp.cpp b/kioslave/sftp/kio_sftp.cpp index 21cffac..7e9065c 100644 --- a/kioslave/sftp/kio_sftp.cpp +++ b/kioslave/sftp/kio_sftp.cpp @@ -2165,16 +2165,16 @@ int sftpProtocol::GetRequest::readChunks(QByteArray &data) { data.resize(data.size() - (request.expectedLength - bytesread)); // Save current file offset - uint64_t oldOffset = mFile->offset; - mFile->offset = request.startOffset + bytesread; + uint64_t oldOffset = sftp_tell64(mFile); + sftp_seek64(request.startOffset + bytesread); // Modify current request request.expectedLength = request.expectedLength - bytesread; - request.startOffset = mFile->offset; + request.startOffset = sftp_tell64(mFile); request.id = sftp_async_read_begin(mFile, request.expectedLength); // Restore the file offset - mFile->offset = oldOffset; + sftp_seek64(mFile, oldOffset); if (request.id < 0) { // Failed to dispatch rerequest I tried with files with between about 30 kB and 4 MB. Frankly i don't understand what's the use of all the 2nd sftp_tell64 and seek calls. If the seek succeeds, this is the new offset. If it fails, there's hardly a chance to continue. The sftp_async_read_begin might not change the offset and to get the offset after the next read, the tell should be done after sftp_async_read . From the sftp documentation i do not get a real clue, when the read pointer is updated and in which of the functions, so i would refrain from relying on it. However. My 2c I guess your changes from comment #1 are probably correct. Can you create a git format patch? Created attachment 90277 [details]
Patch to fix this issue with a Redhat-like build system
my 2c
Never created git format-patch stuff, sorry. The attached patch works for redhat like systems with these lines in the spec file: Patch110: kde-runtime-4.14.3-sftp-offset.patch %patch110 -p1 -b .sftp-offset Thanks, I've pushed the fix to master and KDE/4.14. |