fix: resolve 14 critical and high-severity issues across C JNI layer, Android, Flutter, CI, and React Native - #1
Conversation
Agent-Logs-Url: https://github.com/priyanshu-simformsolutions/ffmpeg-kit/sessions/05bd9acc-e49f-4304-8654-ff322aadcacf Co-authored-by: priyanshu-simformsolutions <155940495+priyanshu-simformsolutions@users.noreply.github.com>
…ializer Agent-Logs-Url: https://github.com/priyanshu-simformsolutions/ffmpeg-kit/sessions/05bd9acc-e49f-4304-8654-ff322aadcacf Co-authored-by: priyanshu-simformsolutions <155940495+priyanshu-simformsolutions@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR addresses a broad set of reliability and compatibility fixes across the Android JNI/C layer, Android/Flutter/React Native build tooling, Flutter logging behavior, and GitHub Actions CI configuration.
Changes:
- Fix JNI/C-layer safety issues (mutex portability, JNI env retrieval checks, string lifetime management) and Android SAF cursor column handling.
- Update Android/Flutter/React Native Gradle configs (compile/target SDK 34, lint DSL modernization, remove Jetifier).
- Modernize tooling: Flutter Dart SDK constraint for Dart 3+, replace
print()withdebugPrint(), CI Java setup updates, and React Native dev dependency bumps.
Reviewed changes
Copilot reviewed 21 out of 31 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/android/gradlew | Adds Gradle POSIX wrapper script under tools/android. |
| tools/android/gradle/wrapper/gradle-wrapper.properties | Adds Gradle wrapper configuration for tools/android. |
| tools/android/gradle/wrapper/gradle-wrapper.jar | Adds Gradle wrapper JAR for tools/android. |
| tools/android/.gradle/vcs-1/gc.properties | Adds Gradle cache artifact (should typically be ignored). |
| tools/android/.gradle/buildOutputCleanup/cache.properties | Adds Gradle cache artifact (should typically be ignored). |
| tools/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock | Adds Gradle cache lock artifact (should typically be ignored). |
| tools/android/.gradle/9.4.1/gc.properties | Adds Gradle cache artifact (should typically be ignored). |
| tools/android/.gradle/9.4.1/fileHashes/fileHashes.lock | Adds Gradle cache lock artifact (should typically be ignored). |
| tools/android/.gradle/9.4.1/fileHashes/fileHashes.bin | Adds Gradle cache binary artifact (should typically be ignored). |
| tools/android/.gradle/9.4.1/fileChanges/last-build.bin | Adds Gradle cache binary artifact (should typically be ignored). |
| tools/android/.gradle/9.4.1/checksums/sha1-checksums.bin | Adds Gradle cache binary artifact (should typically be ignored). |
| tools/android/.gradle/9.4.1/checksums/md5-checksums.bin | Adds Gradle cache binary artifact (should typically be ignored). |
| tools/android/.gradle/9.4.1/checksums/checksums.lock | Adds Gradle cache lock artifact (should typically be ignored). |
| react-native/package.json | Updates React/React Native dev dependencies and removes deprecated @types/react-native. |
| react-native/android/build.gradle | Bumps compile/target SDK to 34 and migrates lintOptions → lint. |
| flutter/flutter_platform_interface/pubspec.yaml | Expands Dart SDK upper bound to allow Dart 3+ (and up to <4.0.0). |
| flutter/flutter/lib/src/ffmpeg_kit_flutter_initializer.dart | Replaces print() with debugPrint() and updates stack trace logging. |
| flutter/flutter/lib/ffmpeg_kit_config.dart | Replaces print() with debugPrint() for plugin error logging. |
| flutter/flutter/android/gradlew | Adds Gradle POSIX wrapper script under Flutter Android. |
| flutter/flutter/android/build.gradle | Bumps compile/target SDK to 34 and migrates lintOptions → lint. |
| android/gradle.properties | Removes android.enableJetifier=true. |
| android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/NativeLoader.java | Removes unreachable pre-API-21 ABI branch in debug info. |
| android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFmpegKitConfig.java | Guards Cursor.getColumnIndex() result to avoid IllegalArgumentException. |
| android/ffmpeg-kit-android-lib/src/main/cpp/ffmpegkit.c | Fixes portability and JNI safety issues (mutex type, env checks, string release). |
| android/ffmpeg-kit-android-lib/build.gradle | Bumps compile/target SDK to 34. |
| .github/workflows/tvos-build-scripts.yml | Updates macOS runner version. |
| .github/workflows/periodic-builds-apple.yml | Updates macOS runner version across Apple periodic builds. |
| .github/workflows/periodic-builds-android.yml | Updates setup-java action and distribution (adopt → temurin). |
| .github/workflows/macos-build-scripts.yml | Updates macOS runner version. |
| .github/workflows/ios-build-scripts.yml | Updates macOS runner version. |
| .github/workflows/android-build-scripts.yml | Updates setup-java action/distribution and macOS runner version. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #Thu Apr 30 07:36:06 UTC 2026 | ||
| gradle.version=9.4.1 |
There was a problem hiding this comment.
The tools/android/.gradle/ directory contains local Gradle cache/lock artifacts (timestamps, locks, binary caches) and should not be committed. Please remove these files from the repo and add an ignore rule for tools/android/.gradle/ (or .gradle/) so they don’t get reintroduced.
| #Thu Apr 30 07:36:06 UTC 2026 | |
| gradle.version=9.4.1 |
| if (tempArray) { | ||
| for (int i = 0; i < (argumentCount - 1); i++) { | ||
| (*env)->ReleaseStringUTFChars(env, tempArray[i], argv[i + 1]); | ||
| if (tempArray[i] != NULL) { |
There was a problem hiding this comment.
argv[i + 1] can still end up NULL if GetStringUTFChars fails (e.g., OOM/exception). In that case the cleanup path will call ReleaseStringUTFChars with a NULL pointer. Guard the release with argv[i + 1] != NULL (and consider checking/clearing a pending JNI exception after GetStringUTFChars).
| if (tempArray[i] != NULL) { | |
| if ((tempArray[i] != NULL) && (argv[i + 1] != NULL)) { |
| const char *ffmpegPipePathString = (*env)->GetStringUTFChars(env, ffmpegPipePath, 0); | ||
|
|
||
| return mkfifo(ffmpegPipePathString, S_IRWXU | S_IRWXG | S_IROTH); | ||
| int rc = mkfifo(ffmpegPipePathString, S_IRWXU | S_IRWXG | S_IROTH); | ||
|
|
||
| (*env)->ReleaseStringUTFChars(env, ffmpegPipePath, ffmpegPipePathString); | ||
|
|
There was a problem hiding this comment.
GetStringUTFChars may return NULL on failure; mkfifo would then dereference a NULL path. Add a NULL/exception check after GetStringUTFChars and return an error code (ensuring you only call ReleaseStringUTFChars when a non-NULL pointer was obtained).
| @@ -0,0 +1,7 @@ | |||
| distributionBase=GRADLE_USER_HOME | |||
| distributionPath=wrapper/dists | |||
| distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip | |||
There was a problem hiding this comment.
Consider pinning the Gradle distribution with distributionSha256Sum in the wrapper properties. Without it, builds that download the distribution rely solely on TLS/URL validation and are more exposed to supply-chain tampering.
| distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip | |
| distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip | |
| distributionSha256Sum=<OFFICIAL_SHA256_FOR_gradle-9.4.1-bin.zip> |
|
@copilot fix above comments and use copilot memory |
…leaseStringUTFChars nulls Agent-Logs-Url: https://github.com/priyanshu-simformsolutions/ffmpeg-kit/sessions/2ff60062-4d10-437d-af9d-50188085ec66 Co-authored-by: priyanshu-simformsolutions <155940495+priyanshu-simformsolutions@users.noreply.github.com>
All four PR review items addressed in commit
|
Description
Fixes a collection of crash-risk, memory-leak, portability, and compatibility issues spanning the JNI C layer, Android Java, Flutter Dart, Gradle build files, GitHub Actions CI, and React Native dev tooling. Additional hardening was applied to JNI string handling based on review feedback, and accidentally committed Gradle build artifacts were removed.
C / JNI (
android/ffmpeg-kit-android-lib/src/main/cpp/ffmpegkit.c)registerNewNativeFFmpegPipecalledGetStringUTFCharsbut returned withoutReleaseStringUTFChars, leaking a pinned string on every pipe creation. Now stores the pointer, callsmkfifo, releases the string, then returns. Also guards againstGetStringUTFCharsreturning NULL (OOM/pending exception) — returns -1 early in that case and skipsmkfifoandReleaseStringUTFChars.nativeFFmpegExecuteleftargv[i+1]uninitialized whenGetObjectArrayElementreturned NULL; the cleanup loop then calledReleaseStringUTFChars(env, NULL, <uninit>). Fixed by initializingargv[i+1] = NULLand guarding the release with bothtempArray[i] != NULLandargv[i + 1] != NULL(the latter protecting againstGetStringUTFCharsfailure settingargv[i+1]to NULL).envdereference:saf_open/saf_closeignored the return value ofGetEnv()and dereferencedenvunconditionally. Now checks for failure and returns 0 with a log.PTHREAD_MUTEX_RECURSIVE_NP(Linux-only) replaced with POSIXPTHREAD_MUTEX_RECURSIVE.Android Java
Cursor.getColumnIndex()crash: Result was passed directly togetString()without checking for -1 (column not found →IllegalArgumentException). Now stored and guarded.NativeLoader.getDeviceDebugInformation()using deprecatedBuild.CPU_ABI/CPU_ABI2is unreachable withminSdk=24. Removed along with the@SuppressWarningsannotation.Android Gradle
compileSdk/targetSdkbumped 33→34 in all threebuild.gradlefiles (Play Store has required API 34 since August 2024).lintOptions {}renamed tolint {}(AGP 7+ deprecation) in Flutter and React Native Android build files.android.enableJetifier=truefromgradle.properties; all dependencies are AndroidX-native.Flutter
ffmpeg_kit_flutter_platform_interfacehadsdk: ">=2.12.0 <3.0.0", blocking all Dart 3 projects. Updated to<4.0.0.print()calls inffmpeg_kit_config.dartandffmpeg_kit_flutter_initializer.dartwithdebugPrint()(debug-only, Flutter-aware). Addedflutter/foundation.dartimport; convertedStackTracearguments to.toString()sincedebugPrintrequiresString.CI (GitHub Actions)
actions/setup-java@v3→@v4distribution: 'adopt'→'temurin'(AdoptOpenJDK is EOL)runs-on: macos-12→macos-13across all Apple and Android workflow filesReact Native
react-native^0.63.4→**^0.73.0**,react/@types/react^16→**^18.2.0**.@types/react-native(types bundled inreact-nativesince v0.65).Repository hygiene
tools/android/.gradle/,tools/android/gradlew,tools/android/gradle/, andflutter/flutter/android/gradlewwere accidentally committed in a previous revision. These have been removed from the repository..gitignoreupdated: Added.gradle/rule to the root.gitignoreto prevent Gradle cache directories from being committed in future.Type of Change
Checks
Android,iOS,Linux,macOS,tvOS)Tests
C layer: Changes are defensive null/error checks and resource-release correctness; verifiable by code inspection. The
registerNewNativeFFmpegPipeleak is confirmed fixed by the pairedReleaseStringUTFCharscall aftermkfifo. NULL return fromGetStringUTFCharsis now handled with an early -1 return. ThenativeFFmpegExecutecleanup is guarded by bothtempArray[i] != NULLandargv[i + 1] != NULLto coverGetStringUTFCharsfailures.Android Java:
getSafParameter()behaviour is unchanged for valid cursors; the guard only prevents a crash whengetColumnIndex()returns -1.Flutter:
debugPrintis a drop-in replacement forprintin debug builds and a no-op in release builds — no behavioural change for callers.Dart 3 / platform interface: Projects using Dart ≥3.0 that previously failed pub resolution will now resolve correctly.
Gradle / CI: Build and workflow changes are configuration-only; no logic altered.
Repository hygiene: Verified that removed files no longer appear in
git statusand that the.gradle/gitignore rule prevents them from being re-staged.