Browse Source

Fix locale handling (again)

C locale handling is completely broken. It globally affects all of the
process, and changes semantics of float parsing/formatting. It should
not be used. Unfortunately, C++ code tends to set locales to user
settings anyway for incomprehensible reasons (Qt and Chromium within
QtWebengine). This breaks at least mpv's video renderer, which formats
floats to strings when generating OpenGL shaders. It also could subtly
break other code, including ffmpeg.

The setlocale() calls in our main function were supposed to force locale
string handling to C. But this seems to have regressed with newer Qt
releases, and locale is reset at a later point again.

Do a brutal but effective workaround and set the local environment to C.
These environment variables are used by setlocale(). Glibc at least will
typically check LC_ALL first and then LC_NUMERIC, so we have to set them
both.

This is a hack, but nothing compared to the immeasurable brokenness of
the library code that sets the locale unconditionally.
Vincent Lang 8 năm trước cách đây
mục cha
commit
e89ecfd742
1 tập tin đã thay đổi với 7 bổ sung10 xóa
  1. 7 10
      src/main.cpp

+ 7 - 10
src/main.cpp

@@ -101,6 +101,13 @@ int main(int argc, char *argv[])
     qputenv("QT_LOGGING_RULES", "qt.network.ssl.warning=false");
 #endif
 
+    // Qt calls setlocale(LC_ALL, "") in a bunch of places, which breaks
+    // float/string processing in mpv and ffmpeg.
+#ifdef Q_OS_UNIX
+    qputenv("LC_ALL", "C");
+    qputenv("LC_NUMERIC", "C");
+#endif
+
     detectOpenGLEarly();
 
     preinitQt();
@@ -146,10 +153,6 @@ int main(int argc, char *argv[])
       return 0;
     }
 
-#ifdef Q_OS_UNIX
-    setlocale(LC_NUMERIC, "C");
-#endif
-
     detectOpenGLLate();
 
 #ifdef Q_OS_WIN32
@@ -169,12 +172,6 @@ int main(int argc, char *argv[])
 
     QtWebEngine::initialize();
 
-    // Qt and QWebEngineProfile set the locale, which breaks parsing and
-    // formatting float numbers in a few countries.
-#ifdef Q_OS_UNIX
-    setlocale(LC_NUMERIC, "C");
-#endif
-
     // start our helper
     HelperLauncher::Get().connectToHelper();