关于:JNI WARNING: illegal start byte 处理

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);
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值