Skip to content

fix(chunk-file-request): array index out of bound exception#2046

Open
alperozturk96 wants to merge 1 commit into
masterfrom
fix/aioobe-chunk-file-request-entity
Open

fix(chunk-file-request): array index out of bound exception#2046
alperozturk96 wants to merge 1 commit into
masterfrom
fix/aioobe-chunk-file-request-entity

Conversation

@alperozturk96

@alperozturk96 alperozturk96 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Issue

ChunkFromFileChannelRequestEntity created from ChunkedFileUploadRemoteOperation via channel and chunk.

Channel and chunk values may cause the following exception thus root cause of it can be from whether loop logic in ChunkFromFileChannelRequestEntity or creation logic from ChunkedFileUploadRemoteOperation.

java.lang.ArrayIndexOutOfBoundsException:
src.length=4096, srcPos=0,
dst.length=2048, dstPos=0,
length=-1

Exception

05-08 22:10:20.370 14592 14618 E UploadFileOperation:
Upload of
/storage/emulated/0/Android/media/com.t_example.android.webdav/
com.t_example.android.webdav/tmp/120049010000000300218142@example.com/
A090125/1GB.bin
to
/A090125/1GB.bin

Unexpected exception:

java.lang.ArrayIndexOutOfBoundsException:
src.length=4096, srcPos=0,
dst.length=2048, dstPos=0,
length=-1

Stack trace:
    at java.lang.System.arraycopy(System.java:528)
    at java.io.BufferedOutputStream.write(BufferedOutputStream.java:128)
    at com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity.writeRequest(ChunkFromFileChannelRequestEntity.java:110)
    at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
    at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
    at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
    at com.owncloud.android.lib.common.OwnCloudClient.executeMethod(OwnCloudClient.java:192)
    at com.owncloud.android.lib.resources.files.ChunkedFileUploadRemoteOperation.uploadChunk(ChunkedFileUploadRemoteOperation.java:294)
    at com.owncloud.android.lib.resources.files.ChunkedFileUploadRemoteOperation.run(ChunkedFileUploadRemoteOperation.java:201)
    at com.owncloud.android.lib.common.operations.RemoteOperation.execute(RemoteOperation.java:193)
    at com.owncloud.android.operations.UploadFileOperation.normalUpload(UploadFileOperation.java:1162)
    at com.owncloud.android.operations.UploadFileOperation.run(UploadFileOperation.java:503)
    at com.owncloud.android.lib.common.operations.RemoteOperation.execute(RemoteOperation.java:193)
    at com.nextcloud.client.jobs.upload.FileUploadWorker$upload$2.invokeSuspend(FileUploadWorker.kt:363)
    at com.nextcloud.client.jobs.upload.FileUploadWorker$upload$2.invoke(Unknown Source:8)
    at com.nextcloud.client.jobs.upload.FileUploadWorker$upload$2.invoke(Unknown Source:4)
    at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:42)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:164)
    at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
    at com.nextcloud.client.jobs.upload.FileUploadWorker.upload(FileUploadWorker.kt:358)
    at com.nextcloud.client.jobs.upload.FileUploadWorker.access$upload(FileUploadWorker.kt:56)
    at com.nextcloud.client.jobs.upload.FileUploadWorker$uploadFiles$2$result$1.invokeSuspend(FileUploadWorker.kt:287)
    at com.nextcloud.client.jobs.upload.FileUploadWorker$uploadFiles$2$result$1.invoke(Unknown Source:8)
    at com.nextcloud.client.jobs.upload.FileUploadWorker$uploadFiles$2$result$1.invoke(Unknown Source:4)
    at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:42)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:164)
    at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)

Changes

  • Reverses while loop condition to better readability (remaning = max count - chunk start)
  • Checks channel read and exit if invalid
  • Removes iterator

Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
@github-actions

Copy link
Copy Markdown
Contributor

SpotBugs

CategoryBaseNew
Bad practice3131
Correctness2928
Dodgy code1414
Internationalization66
Malicious code vulnerability2626
Multithreaded correctness77
Performance77
Total120119

@alperozturk96

alperozturk96 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

Why +1 added to nextByte here? Introduced with for S3 multipart upload but why +1? Because Validates the DAV chunk filename name to be numeric between 1 and 10000 ??

And here we.getContentLenght(); can be null thus nextByte is 0?

@tobiasKaminsky

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant