#1471 check file length after metadata editing via PixyMeta

This commit is contained in:
Thibault Deckers 2025-03-11 00:24:03 +01:00
parent f646639055
commit dcd42b7048
3 changed files with 23 additions and 6 deletions

View file

@ -92,6 +92,7 @@ object PixyMetaHelper {
fun getXmp(input: InputStream): XMP? = Metadata.readMetadata(input)[MetadataType.XMP] as XMP?
// PixyMeta may fail with just a log, and write nothing to the output
fun setXmp(
input: InputStream,
output: OutputStream,

View file

@ -680,18 +680,19 @@ abstract class ImageProvider {
try {
edit(ExifInterface(editableFile))
if (editableFile.length() == 0L) {
callback.onFailure(Exception("editing Exif yielded an empty file"))
return false
}
val editedMimeType = detectMimeType(context, Uri.fromFile(editableFile), mimeType)
if (editedMimeType != mimeType) {
throw Exception("editing Exif changes mimeType=$mimeType -> $editedMimeType for uri=$uri path=$path")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// 1) as of androidx.exifinterface:exifinterface:1.3.6, editing some specific WEBP
// makes them undecodable by some decoders (including Android's and Chrome's)
// even though `BitmapFactory` successfully decodes their bounds,
// editing may corrupt the file for various reasons,
// so we check whether decoding it throws an exception
// 2) some users have reported corruption when editing JPEG as well,
// but conditions are unknown (specific image, custom ROM, low storage, race condition, etc.)
ImageDecoder.decodeBitmap(ImageDecoder.createSource(editableFile))
}
@ -781,6 +782,11 @@ abstract class ImageProvider {
}
}
if (editableFile.length() == 0L) {
callback.onFailure(Exception("editing IPTC yielded an empty file"))
return false
}
if (trailerVideoBytes != null) {
// append trailer video, if any
editableFile.appendBytes(trailerVideoBytes!!)
@ -917,6 +923,11 @@ abstract class ImageProvider {
}
}
if (editableFile.length() == 0L) {
callback.onFailure(Exception("editing XMP yielded an empty file"))
return false
}
try {
// copy the edited temporary file back to the original
editableFile.transferTo(outputStream(context, mimeType, uri, path))
@ -1330,6 +1341,11 @@ abstract class ImageProvider {
}
}
if (editableFile.length() == 0L) {
callback.onFailure(Exception("removing metadata yielded an empty file"))
return
}
try {
// copy the edited temporary file back to the original
editableFile.transferTo(outputStream(context, mimeType, uri, path))

View file

@ -144,8 +144,8 @@ class _MetadataSectionSliverState extends State<MetadataSectionSliver> {
}
Future<void> _getMetadata() async {
if (!mounted) return;
final titledDirectories = await entry.getMetadataDirectories(context);
if (!mounted) return;
metadataNotifier.value = Map.fromEntries(titledDirectories);
_expandedDirectoryNotifier.value = null;
}