Ignore:
Timestamp:
11/30/19 01:46:51 (4 years ago)
Author:
Maciej Komosinski
Message:

A workaround for Android bug in vsnprintf() and vsprintf() needed in more classes (introduced earlier in r892), ​https://github.com/android-ndk/ndk/issues/879

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/util/sstring-simple.cpp

    r826 r897  
    268268                va_end(ap);
    269269                /* If that worked, return the string. */
     270
     271#ifdef __ANDROID__
     272                //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.
     273                //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).
     274                if (n < 0 && size >= (1 << 24)) //wants more than 16M
     275                {
     276                        buf[size - 1] = 0; //just to ensure there is at least some ending \0 in memory... who knows what buggy vsnprintf() did.
     277                        __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);
     278                        //in my tests, it always used 0 bytes, so it produced a 0-length string: ""
     279                        va_copy(ap_copy, ap);
     280                        n = vsprintf(buf, format, ap_copy); //hoping 16M is enough
     281                        va_end(ap_copy);
     282                        __android_log_print(ANDROID_LOG_INFO, LOG_APP_NAME, "Fallback to vsprintf() produced string: '%s'", buf);
     283                        if (n < 0) //vsprintf was also buggy. If we were strict, we should abort the app now.
     284                        {
     285                                strcpy(buf, "[STR_ERR] "); //a special prefix just to indicate the returned string is incorrect
     286                                strcat(buf, format); //append and return the original formatting string
     287                                __android_log_print(ANDROID_LOG_ERROR, LOG_APP_NAME, "vsprintf() also failed, using the incorrect resulting string: '%s'", buf);
     288                        }
     289                        n = strlen(buf); //pretend vsnprintf() or vsprintf() was OK to exit the endless loop
     290                }
     291#endif
     292
    270293                if (n > -1 && n < size)
    271294                {
Note: See TracChangeset for help on using the changeset viewer.