直接将/trunk/frameworks/base/wifi/java/android/net/wifi/WifiSsid.java 中的convertToBytes 拷贝出来调试:
目的:了解这个函数的作用,输入输出分别是什么。
结果:输入参数为\xnn格式的ascii码,当输入参数非法时,由于原生代码写的健壮性不够,很容易发生字串索引越界,导致系统异常。
下面将测试代码贴出来,以作备份。
package com.rockey.test1;
import java.io.ByteArrayOutputStream;
import android.os.Bundle;
import android.R.integer;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
public ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
private static final int HEX_RADIX = 16;
private static final String TAG = "ROCKEY";
public String asciiEncoded;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG, "octets1:"+octets.toString());
asciiEncoded = "\\x45\\x45\\x45\\x45\\x45\\x45\\x45\\07";
convertToBytes(asciiEncoded);
Log.e(TAG, "octets2:"+octets.toString());
int var = Character.digit('B', HEX_RADIX);
Log.e(TAG, "Character.digit:"+var);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/* This function is equivalent to printf_decode() at src/utils/common.c in
* the supplicant */
private void convertToBytes(String asciiEncoded) {
int i = 0;
int val = 0;
while (i< asciiEncoded.length()) {
char c = asciiEncoded.charAt(i);
switch (c) {
case '\\':
Log.e(TAG, "dash1,length:"+asciiEncoded.length());
i++;
//added for StringIndexOutOfBoundsException by ctv zhangjiqiang
if (i >= asciiEncoded.length()) {
octets.write('\\');
break;
}
switch(asciiEncoded.charAt(i)) {
case '\\':
Log.e(TAG, "dash2");
octets.write('\\');
i++;
break;
case '"':
octets.write('"');
i++;
break;
case 'n':
octets.write('\n');
i++;
break;
case 'r':
octets.write('\r');
i++;
break;
case 't':
octets.write('\t');
i++;
break;
case 'e':
octets.write(27); //escape char
i++;
break;
case 'x':
Log.e(TAG, "dashx");
i++;
try {
//added for StringIndexOutOfBoundsException by ctv zhangjiqiang delete by liuxiang
//if((i+2)>asciiEncoded.length()){
// val = -1;
//}else{
//add try...catch for StringIndexOutOfBoundsException by ctv liuxiang
try{
val = Integer.parseInt(asciiEncoded.substring(i, i + 2), HEX_RADIX);
}catch(StringIndexOutOfBoundsException e){
e.printStackTrace();
break;
}
//}
} catch (NumberFormatException e) {
val = -1;
}
if (val < 0) {
//add try catch for StringIndexOutOfBoundsException by ctv liuxiang
try{
val = Character.digit(asciiEncoded.charAt(i), HEX_RADIX);
}catch(StringIndexOutOfBoundsException e){
val = -1;
Log.e(TAG, "StringIndexOutOfBoundsException2");
}
if (val < 0) break;
octets.write(val);
i++;
} else {
octets.write(val);
i += 2;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
Log.e(TAG, "0~7,i="+i);
val = asciiEncoded.charAt(i) - '0';
Log.e(TAG, "val1:"+val);
i++;
try {
if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
val = val * 8 + asciiEncoded.charAt(i) - '0';
Log.e(TAG, "val2:"+val);
i++;
}
if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
val = val * 8 + asciiEncoded.charAt(i) - '0';
Log.e(TAG, "val3:"+val);
i++;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
Log.e(TAG, "StringIndexOutOfBoundsException3");
break;
}
octets.write(val);
break;
default:
break;
}
break;
default:
Log.e(TAG, "default");
octets.write(c);
i++;
break;
}
}
}
}
输入为:asciiEncoded = "\\x45\\x45\\x45\\x45\\x45\\x45\\x45\\07";
运行结果:
07-15 15:15:44.216: E/ROCKEY(2757): octets1:
07-15 15:15:44.216: E/ROCKEY(2757): dash1,length:31
07-15 15:15:44.216: E/ROCKEY(2757): dashx
07-15 15:15:44.216: E/ROCKEY(2757): dash1,length:31
07-15 15:15:44.216: E/ROCKEY(2757): dashx
07-15 15:15:44.216: E/ROCKEY(2757): dash1,length:31
07-15 15:15:44.216: E/ROCKEY(2757): dashx
07-15 15:15:44.216: E/ROCKEY(2757): dash1,length:31
07-15 15:15:44.216: E/ROCKEY(2757): dashx
07-15 15:15:44.216: E/ROCKEY(2757): dash1,length:31
07-15 15:15:44.216: E/ROCKEY(2757): dashx
07-15 15:15:44.216: E/ROCKEY(2757): dash1,length:31
07-15 15:15:44.216: E/ROCKEY(2757): dashx
07-15 15:15:44.216: E/ROCKEY(2757): dash1,length:31
07-15 15:15:44.216: E/ROCKEY(2757): dashx
07-15 15:15:44.216: E/ROCKEY(2757): dash1,length:31
07-15 15:15:44.216: E/ROCKEY(2757): 0~7,i=29
07-15 15:15:44.216: E/ROCKEY(2757): val1:0
07-15 15:15:44.216: E/ROCKEY(2757): val2:7
07-15 15:15:44.216: W/System.err(2757): java.lang.StringIndexOutOfBoundsException: length=31; index=31
07-15 15:15:44.216: W/System.err(2757): at com.rockey.test1.MainActivity.convertToBytes(MainActivity.java:133)
07-15 15:15:44.216: W/System.err(2757): at com.rockey.test1.MainActivity.onCreate(MainActivity.java:22)
07-15 15:15:44.216: W/System.err(2757): at android.app.Activity.performCreate(Activity.java:5104)
07-15 15:15:44.216: W/System.err(2757): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
07-15 15:15:44.216: W/System.err(2757): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
07-15 15:15:44.216: W/System.err(2757): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
07-15 15:15:44.216: W/System.err(2757): at android.app.ActivityThread.access$600(ActivityThread.java:141)
07-15 15:15:44.216: W/System.err(2757): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
07-15 15:15:44.216: W/System.err(2757): at android.os.Handler.dispatchMessage(Handler.java:99)
07-15 15:15:44.216: W/System.err(2757): at android.os.Looper.loop(Looper.java:137)
07-15 15:15:44.216: W/System.err(2757): at android.app.ActivityThread.main(ActivityThread.java:5041)
07-15 15:15:44.220: W/System.err(2757): at java.lang.reflect.Method.invokeNative(Native Method)
07-15 15:15:44.220: W/System.err(2757): at java.lang.reflect.Method.invoke(Method.java:511)
07-15 15:15:44.220: W/System.err(2757): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
07-15 15:15:44.220: W/System.err(2757): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
07-15 15:15:44.220: W/System.err(2757): at dalvik.system.NativeStart.main(Native Method)
07-15 15:15:44.220: E/ROCKEY(2757): StringIndexOutOfBoundsException3
07-15 15:15:44.220: E/ROCKEY(2757): octets2:EEEEEEE
07-15 15:15:44.220: E/ROCKEY(2757): Character.digit:11