Description
I noticed that Jp2kDecoder thoroughly validates JS evaluation results by parsing them as JSON and checking for error codes. However, the evaluateJavaScriptAsync result is fed directly into JSONObject(...) without first checking for empty or blank strings. The Jetpack JavaScriptEngine silently coerces non-string JS expression results to "". While JSONObject("") will throw a JSONException that is caught by the existing error handling, the resulting error message can be confusing and does not indicate the root cause.
Evidence
1. WASM init result compared against sentinel without empty guard
In Jp2kDecoder.kt L144-L148, the WASM instantiation result is checked:
val result = resultFuture.await()
if (result != INTERNAL_RESULT_SUCCESS) {
throw IllegalStateException("WASM instantiation failed.")
}
If result is "" (due to the JS promise resolving to a non-string value), this correctly fails but the error message "WASM instantiation failed" does not indicate that the issue was an empty-string coercion.
2. Decode/getSize results parsed as JSON directly
In multiple decode paths (e.g., L238-L241, L517-L520, L616-L617), the JSON result is consumed:
val jsonResult = resultFuture.await()
?: throw IllegalStateException("Result Future is null")
val root = JSONObject(jsonResult)
If jsonResult is "", JSONObject("") throws a JSONException. This is caught, but the error message is opaque.
Why this may matter
- The existing error handling does catch the failure eventually, but the error messages do not point to the root cause (JavaScriptEngine type-coercion returning
"").
- This makes debugging harder when the WASM/JS layer has a type mismatch.
Suggested hardening
- Add an explicit empty-string check before JSON parsing:
val jsonResult = resultFuture.await()
if (jsonResult.isNullOrBlank()) {
throw IllegalStateException("JavaScriptEngine returned empty result - expected JSON")
}
val root = JSONObject(jsonResult)
- This provides a clear error message and avoids relying on
JSONException for a known JavaScriptEngine behavior.
Description
I noticed that
Jp2kDecoderthoroughly validates JS evaluation results by parsing them as JSON and checking for error codes. However, theevaluateJavaScriptAsyncresult is fed directly intoJSONObject(...)without first checking for empty or blank strings. The JetpackJavaScriptEnginesilently coerces non-string JS expression results to"". WhileJSONObject("")will throw aJSONExceptionthat is caught by the existing error handling, the resulting error message can be confusing and does not indicate the root cause.Evidence
1. WASM init result compared against sentinel without empty guard
In
Jp2kDecoder.ktL144-L148, the WASM instantiation result is checked:If
resultis""(due to the JS promise resolving to a non-string value), this correctly fails but the error message "WASM instantiation failed" does not indicate that the issue was an empty-string coercion.2. Decode/getSize results parsed as JSON directly
In multiple decode paths (e.g., L238-L241, L517-L520, L616-L617), the JSON result is consumed:
If
jsonResultis"",JSONObject("")throws aJSONException. This is caught, but the error message is opaque.Why this may matter
"").Suggested hardening
JSONExceptionfor a knownJavaScriptEnginebehavior.