Changeset 897 for cpp/frams/util


Ignore:
Timestamp:
11/30/19 01:46:51 (5 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

Location:
cpp/frams/util
Files:
2 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                {
  • cpp/frams/util/sstring.cpp

    r889 r897  
    415415                va_end(ap);
    416416                /* If that worked, return the string. */
     417
     418#ifdef __ANDROID__
     419                //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.
     420                //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).
     421                if (n < 0 && size >= (1 << 24)) //wants more than 16M
     422                {
     423                        buf[size - 1] = 0; //just to ensure there is at least some ending \0 in memory... who knows what buggy vsnprintf() did.
     424                        __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);
     425                        //in my tests, it always used 0 bytes, so it produced a 0-length string: ""
     426                        va_copy(ap_copy, ap);
     427                        n = vsprintf(buf, format, ap_copy); //hoping 16M is enough
     428                        va_end(ap_copy);
     429                        __android_log_print(ANDROID_LOG_INFO, LOG_APP_NAME, "Fallback to vsprintf() produced string: '%s'", buf);
     430                        if (n < 0) //vsprintf was also buggy. If we were strict, we should abort the app now.
     431                        {
     432                                strcpy(buf, "[STR_ERR] "); //a special prefix just to indicate the returned string is incorrect
     433                                strcat(buf, format); //append and return the original formatting string
     434                                __android_log_print(ANDROID_LOG_ERROR, LOG_APP_NAME, "vsprintf() also failed, using the incorrect resulting string: '%s'", buf);
     435                        }
     436                        n = strlen(buf); //pretend vsnprintf() or vsprintf() was OK to exit the endless loop
     437                }
     438#endif
     439
    417440                if (n > -1 && n < size)
    418441                {
Note: See TracChangeset for help on using the changeset viewer.