react-native-image-resizer
react-native-image-resizer copied to clipboard
Fix InputStream resource leak in `ImageResizer.getOrientationMatrix()`
Fix: Resource leak in ImageResizer.getOrientationMatrix()
Problem
The InputStream opened in getOrientationMatrix() was not being properly closed, causing a resource leak.
We discovered this when we turned on StrictMode on our Android app to trace memory related problems:
StrictMode policy violation: android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. (Ask Gemini)
at android.os.StrictMode$AndroidCloseGuardReporter.report(StrictMode.java:2011)
at dalvik.system.CloseGuard.warnIfOpen(CloseGuard.java:336)
at java.io.FileInputStream.finalize(FileInputStream.java:662)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:370)
at java.lang.Daemons$FinalizerDaemon.processReference(Daemons.java:350)
at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:322)
at java.lang.Daemons$Daemon.run(Daemons.java:131)
at java.lang.Thread.run(Thread.java:1012)
Caused by: java.lang.Throwable: Explicit termination method 'close' not called
at dalvik.system.CloseGuard.openWithCallSite(CloseGuard.java:288)
at dalvik.system.CloseGuard.open(CloseGuard.java:257)
at java.io.FileInputStream.<init>(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:133)
at android.content.ContentResolver.openInputStream(ContentResolver.java:1526)
at com.reactnativeimageresizer.ImageResizer.getOrientation(ImageResizer.java:323)
at com.reactnativeimageresizer.ImageResizer.createResizedImage(ImageResizer.java:552)
at com.reactnativeimageresizer.ImageResizerModule.createResizedImageWithExceptions(ImageResizerModule.java:68)
at com.reactnativeimageresizer.ImageResizerModule.-$$Nest$mcreateResizedImageWithExceptions(Unknown Source:0)
at com.reactnativeimageresizer.ImageResizerModule$1.doInBackgroundGuarded(ImageResizerModule.java:49)
at com.reactnativeimageresizer.ImageResizerModule$1.doInBackgroundGuarded(ImageResizerModule.java:45)
at com.facebook.react.bridge.GuardedAsyncTask.doInBackground(GuardedAsyncTask.java:34)
at com.facebook.react.bridge.GuardedAsyncTask.doInBackground(GuardedAsyncTask.java:19)
at android.os.AsyncTask$3.call(AsyncTask.java:394)
at java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at java.lang.Thread.run(Thread.java:1012)
Solution
Wrapped the InputStream in a try-with-resources statement to ensure automatic resource cleanup.
Changes
- Updated
android/src/main/java/com/reactnativeimageresizer/ImageResizer.javaline 322-324 - Changed from manual
InputStreammanagement to try-with-resources pattern
Impact
- Prevents resource leaks when reading image orientation metadata
- Follows Java best practices for resource management
- No functional changes to the API
Testing
- Existing functionality remains unchanged
- Resource cleanup is now guaranteed even if exceptions occur