fix: delete abandoned compressed video when larger than original

fix: eagerly delete intermediate temp files in upload pipeline
fix: delete temp file from MediaCompressorFileUtils after image compression
refactor: simplify temp file cleanup logic
- Remove TOCTOU anti-pattern (file.exists() before file.delete())
- Consolidate double deleteTempUri calls into single conditional
- Remove restating comments
This commit is contained in:
davotoula
2026-03-25 10:19:16 +01:00
parent 390edf311d
commit 60b7c6bd0d
3 changed files with 24 additions and 15 deletions
@@ -31,6 +31,7 @@ import com.vitorpamplona.quartz.utils.Log
import id.zelory.compressor.Compressor
import id.zelory.compressor.constraint.default
import kotlinx.coroutines.CancellationException
import java.io.File
class MediaCompressorResult(
val uri: Uri,
@@ -89,19 +90,23 @@ class MediaCompressor {
else -> 60
}
var tempFile: File? = null
return try {
Log.d("MediaCompressor", "Using image compression $mediaQuality")
val tempFile = MediaCompressorFileUtils.from(uri, context)
tempFile = MediaCompressorFileUtils.from(uri, context)
val compressedImageFile =
Compressor.compress(context, tempFile) {
default(width = 640, format = Bitmap.CompressFormat.JPEG, quality = imageQuality)
}
Log.d("MediaCompressor", "Image compression success. Original size [${tempFile.length()}], new size [${compressedImageFile.length()}]")
if (tempFile != compressedImageFile && !tempFile.delete()) {
Log.w("MediaCompressor", "Failed to delete temp file: ${tempFile.absolutePath}")
}
Log.d("MediaCompressor", "Image compression success. New size [${compressedImageFile.length()}]")
MediaCompressorResult(compressedImageFile.toUri(), MimeTypes.IMAGE_JPEG, compressedImageFile.length())
} catch (e: Exception) {
Log.d("MediaCompressor", "Image compression failed: ${e.message}")
if (e is CancellationException) throw e
e.printStackTrace()
Log.d("MediaCompressor", "Image compression failed: ${e.message}")
tempFile?.delete()
MediaCompressorResult(uri, contentType, null)
}
}
@@ -338,7 +338,7 @@ class UploadOrchestrator {
try {
val path = tempUri.path ?: return
val file = File(path)
if (file.exists() && file.delete()) {
if (file.delete()) {
Log.d("UploadOrchestrator", "Deleted temp file: $path")
}
} catch (e: Exception) {
@@ -363,7 +363,11 @@ class UploadOrchestrator {
val finalUri =
stripAfterCompression(uri, compressed, mimeType, compressionQuality, stripMetadata, onStrippingFailed, context)
?: return error(R.string.upload_cancelled)
?: return error(R.string.upload_cancelled).also {
deleteTempUri(compressed.uri, uri)
}
if (compressed.uri != finalUri) deleteTempUri(compressed.uri, uri)
try {
return when (server.type) {
@@ -372,10 +376,7 @@ class UploadOrchestrator {
ServerType.Blossom -> uploadBlossom(finalUri, compressed.contentType, compressed.size, alt, contentWarningReason, server.baseUrl, null, null, account, context)
}
} finally {
// Clean up intermediate temp files created by stripping and compression.
// Delete stripped file first (if different from compressed), then compressed (if different from original).
deleteTempUri(finalUri, compressed.uri)
deleteTempUri(compressed.uri, uri)
deleteTempUri(finalUri, uri)
}
}
@@ -397,9 +398,14 @@ class UploadOrchestrator {
val finalUri =
stripAfterCompression(uri, compressed, mimeType, compressionQuality, stripMetadata, onStrippingFailed, context)
?: return error(R.string.upload_cancelled)
?: return error(R.string.upload_cancelled).also {
deleteTempUri(compressed.uri, uri)
}
if (compressed.uri != finalUri) deleteTempUri(compressed.uri, uri)
val encrypted = EncryptFiles().encryptFile(context, finalUri, encrypt)
deleteTempUri(finalUri, uri)
try {
return when (server.type) {
@@ -408,10 +414,7 @@ class UploadOrchestrator {
ServerType.Blossom -> uploadBlossom(encrypted.uri, encrypted.contentType, encrypted.size, alt, contentWarningReason, server.baseUrl, compressed.contentType, encrypted.originalHash, account, context)
}
} finally {
// Clean up all intermediate temp files: encrypted, stripped, and compressed.
deleteTempUri(encrypted.uri, finalUri)
deleteTempUri(finalUri, compressed.uri)
deleteTempUri(compressed.uri, uri)
deleteTempUri(encrypted.uri, uri)
}
}
}
@@ -233,6 +233,7 @@ object VideoCompressionHelper {
// Sanity check: compression not smaller than original
if (originalSize > 0 && size >= originalSize) {
File(path).delete()
applicationContext.notifyUser(
"Compressed file larger than original. Using original.",
Log.WARN,