您的位置:首页 > 其它

关于:JNI WARNING: illegal start byte 处理

2011-06-17 01:11 148 查看



W/dalvikvm(
1473): in Landroid/media/MediaScanner;.processFile
(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V
(NewStringUTF)

I/dalvikvm( 1473): "MediaScannerService" prio=5 tid=10 NATIVE

I/dalvikvm( 1473): | group="main" sCount=0 dsCount=0 s=N obj=0x45f1ea18 self=0x22f0d0

I/dalvikvm( 1473): | sysTid=1647 nice=11 sched=3/0 cgrp=unknown handle=2229456

I/dalvikvm( 1473): at android.media.MediaScanner.processFile(Native Method)

I/dalvikvm( 1473): at android.media.MediaScanner.access$500(MediaScanner.java:103)

这个就是蛋疼的地方,

造成该问题的原因是没有通过虚拟机的checkjni检查。代码在dalvik/vm/CheckJni.c

/*

* Verify that "bytes" points to valid "modified UTF-8" data.

*/

static void checkUtfString(JNIEnv* env, const char* bytes, bool nullOk,

const char* func)

{

const char* origBytes = bytes;

if (bytes == NULL) {

if (!nullOk) {

LOGW("JNI WARNING: unexpectedly null UTF string/n");

goto fail;

}

return;

}

while (*bytes != '/0') {

u1 utf8 = *(bytes++);

// Switch on the high four bits.

switch (utf8 >> 4) {

case 0x00:

case 0x01:

case 0x02:

case 0x03:

case 0x04:

case 0x05:

case 0x06:

case 0x07: {

// Bit pattern 0xxx. No need for any extra bytes.

break;

}

case 0x08:

case 0x09:

case 0x0a:

case 0x0b:

case 0x0f: {

/*

* Bit pattern 10xx or 1111, which are illegal start bytes.

* Note: 1111 is valid for normal UTF-8, but not the

* modified UTF-8 used here.

*/

LOGW("JNI WARNING: illegal start byte 0x%x/n", utf8);

goto fail;

}

case 0x0e: {

// Bit pattern 1110, so there are two additional bytes.

utf8 = *(bytes++);

if ((utf8 & 0xc0) != 0x80) {

LOGW("JNI WARNING: illegal continuation byte 0x%x/n", utf8);

goto fail;

}

// Fall through to take care of the final byte.

}

case 0x0c:

case 0x0d: {

// Bit pattern 110x, so there is one additional byte.

utf8 = *(bytes++);

if ((utf8 & 0xc0) != 0x80) {

LOGW("JNI WARNING: illegal continuation byte 0x%x/n", utf8);

goto fail;

}

break;

}

}

}

return;

fail:

LOGW(" string: '%s'/n", origBytes);

showLocation(dvmGetCurrentJNIMethod(), func);

abortMaybe();

}

解决方法:

是否进行checkjni检查是由ro.kernel.android.checkjni决定。

在eng版本中ro.kernel.android.checkjni=1.而在user版本不做检查。

网上提出的解决方案是将非法头字符修正为“?”,将其他非法字符修正为“0x80”,patch后的函数如下:

// Send a command to the supplicant, and return the reply as a String

static jstring doStringCommand(JNIEnv *env, const char *cmd)

{

char reply[4096];

char* bytes;

if (doCommand(cmd, reply, sizeof(reply)) != 0) {

return env->NewStringUTF(NULL);

} else {

// Make sure reply only contains valid UTF-8 Characters

// This is borrowed from CheckJni.c

bytes = reply;

while (*bytes != '/0')

{

char utf8 = *bytes;

switch (utf8 >> 4) {

case 0x00:

case 0x01:

case 0x02:

case 0x03:

case 0x04:

case 0x05:

case 0x06:

case 0x07:

{

// Bit pattern 0xxx. No need for any extra bytes.

break;

}

case 0x08:

case 0x09:

case 0x0a:

case 0x0b:

case 0x0f:

{

/*

* Bit pattern 10xx or 1111, which are illegal start bytes.

* Note: 1111 is valid for normal UTF-8, but not the

* modified UTF-8 used here. + */

LOGW("JNI WARNING: illegal start byte 0x%x, changing to '?'/n", utf8);

//return env->NewStringUTF("AP"); //modify by rockie

*bytes = '?';

}

case 0x0e: {

// Bit pattern 1110, so there are two additional bytes.

utf8 = *(++bytes);

if ((utf8 & 0xc0) != 0x80) {

LOGW("JNI WARNING: illegal continuation byte 0x%x, changing to 0x80./n", utf8);

*bytes = 0x80;

}

// Fall through to take care of the final byte.

}

case 0x0c:

case 0x0d: {

// Bit pattern 110x, so there is one additional byte.

utf8 = *(++bytes);

if ((utf8 & 0xc0) != 0x80) {

LOGW("JNI WARNING: illegal continuation byte 0x%x, changing to 0x80./n", utf8);

*bytes = 0x80;

}

break;

}

}

bytes++;

}

return env->NewStringUTF(reply);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: