Changeset 892 for cpp/common


Ignore:
Timestamp:
07/27/19 12:53:36 (5 years ago)
Author:
Maciej Komosinski
Message:

A workaround for Android bug in vsnprintf() and vsprintf(), https://github.com/android-ndk/ndk/issues/879

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/common/util-string.cpp

    r867 r892  
    1111#ifdef USE_VIRTFILE
    1212#include <common/virtfile/virtfile.h>
     13#endif
     14#ifdef __ANDROID__
     15#include <android/log.h> //only needed to print error messages related to a workaround for Android bug
    1316#endif
    1417
     
    3538                int n = vsnprintf(buf, size, format, ap_copy);
    3639                va_end(ap_copy);
     40
     41#ifdef __ANDROID__
     42                //Workaround for Android bug. /system/lib64/libc.so? maybe only arm 64-bit? "If an encoding error occurs, a negative number is returned". On some devices keeps returning -1 forever.
     43                //https://github.com/android-ndk/ndk/issues/879 but unfortunately during google play tests (Firebase Test Lab) this problem turned out to be not limited to Chinese devices and occurred in Mate 9, Galaxy S9, Pixel, Pixel 2, Moto Z (even with the en_GB locale; the locale is not important but the problem seem to be utf8 non-ascii chars in the format string).
     44                if (n < 0 && size >= (1 << 24)) //wants more than 16M
     45                {
     46                        buf[size - 1] = 0; //just to ensure there is at least some ending \0 in memory... who knows what buggy vsnprintf() did.
     47                        __android_log_print(ANDROID_LOG_ERROR, LOG_APP_NAME, "Giving up due to Android bug: vsnprintf() wants more than %d bytes, it used %zu bytes, for format='%s'", size, strlen(buf), format);
     48                        //in my tests, it always used 0 bytes, so it produced a 0-length string: ""
     49                        va_copy(ap_copy, ap);
     50                        n = vsprintf(buf, format, ap_copy); //hoping 16M is enough
     51                        va_end(ap_copy);
     52                        __android_log_print(ANDROID_LOG_INFO, LOG_APP_NAME, "Fallback to vsprintf() produced string: '%s'", buf);
     53                        if (n < 0) //vsprintf was also buggy. If we were strict, we should abort the app now.
     54                        {
     55                                strcpy(buf, "[STR_ERR] "); //just to indicate the returned string is invalid
     56                                strcat(buf, format); //return just the original formatting string
     57                                __android_log_print(ANDROID_LOG_ERROR, LOG_APP_NAME, "vsprintf() also failed, returning incorrect string '%s'", buf);
     58                        }
     59                        n = 0; //pretend vsnprintf() or vsprintf() was OK to exit the endless loop
     60                }
     61#endif
     62
    3763                if (n > -1 && n < size)
    3864                {
Note: See TracChangeset for help on using the changeset viewer.