android js呼叫java 4.2之下漏洞的解決方案
阿新 • • 發佈:2019-01-03
在反射呼叫的時候把當前物件傳入,就可以呼叫成員方法了,這樣的話整個架構就比較靈活,感謝safe-java-js-webview-bridge的作者提供了這麼好的解決方案!
<span style="font-size:14px;">public String call(WebView webView, String jsonStr) { if (!TextUtils.isEmpty(jsonStr)) { try { JSONObject callJson = new JSONObject(jsonStr); String methodName = callJson.getString("method"); JSONArray argsTypes = callJson.getJSONArray("types"); JSONArray argsVals = callJson.getJSONArray("args"); //Log.e("print",methodName+"="+argsTypes+"="+argsVals); String sign = methodName; int len = argsTypes.length(); Object[] values = new Object[len]; int numIndex = 0; String currType; for (int k = 0; k < len; k++) { currType = argsTypes.optString(k); if ("string".equals(currType)) { sign += "_S"; values[k] = argsVals.isNull(k) ? null : argsVals.getString(k); } else if ("number".equals(currType)) { sign += "_N"; //為了標記for迴圈的判斷 如果第一位就是number型別排除0 numIndex = numIndex * 10 + k + 1; Log.e("print", "numIndex:" + numIndex); } else if ("boolean".equals(currType)) { sign += "_B"; values[k] = argsVals.getBoolean(k); } else if ("object".equals(currType)) { sign += "_O"; values[k] = argsVals.isNull(k) ? null : argsVals.getJSONObject(k); } else if ("function".equals(currType)) { sign += "_F"; values[k] = new JsCallback(webView, mInjectedName, argsVals.getInt(k)); } else { sign += "_P"; } } Method currMethod = mMethodsMap.get(sign); // 方法匹配失敗 if (currMethod == null) { return getReturn(jsonStr, 500, "not found method(" + sign + ") with valid parameters"); } // 數字型別細分匹配 if (numIndex > 0) { Class[] methodTypes = currMethod.getParameterTypes(); int currIndex; Class currCls; while (numIndex > 0) { currIndex = (numIndex - numIndex / 10 * 10) - 1; currCls = methodTypes[currIndex]; if (currCls == int.class) { values[currIndex] = argsVals.getInt(currIndex); } else if (currCls == long.class) { //WARN: argsJson.getLong(k + defValue) will return a bigger incorrect number values[currIndex] = Long.parseLong(argsVals.getString(currIndex)); } else { values[currIndex] = argsVals.getDouble(currIndex); } // Log.e("print",currIndex+"=numIndex="+numIndex+" value:"+ values[currIndex]); numIndex /= 10; } } </span><span style="font-size:24px;color:#ff0000;">return getReturn(jsonStr, 200, currMethod.invoke(mInstance, values));</span><span style="font-size:14px;"> } catch (Exception e) { //優先返回詳細的錯誤資訊 if (e.getCause() != null) { return getReturn(jsonStr, 500, "method execute error:" + e.getCause().getMessage()); } return getReturn(jsonStr, 500, "method execute error:" + e.getMessage()); } } else { return getReturn(jsonStr, 500, "call data empty"); } }</span>