Skip to content

Commit 36ade7c

Browse files
committed
Set only LC_CTYPE according to env, keep the "C" locale for other locale categories
* Fixes #3512
1 parent cf76578 commit 36ade7c

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Bug fixes:
88
* Fix repeated calling of methods `Dir#{each,each_child,children}` (#3464, @andrykonchin).
99
* Fix `IO#{wait,wait_readable,wait_writable}` methods and switch the current thread into a sleep state (@andrykonchin).
1010
* Fix `rb_global_variable()` for `Float` and bignum values during the `Init_` function (#3478, @eregon).
11+
* Fix parsing literal floats when the locale does not use `.` for the decimal separator (e.g. `LANG=fr_FR.UTF-8`) (#3512, @eregon).
1112

1213
Compatibility:
1314
* Move `IO#wait_readable`, `IO#wait_writable`, `IO#wait_priority` and `IO#wait` into core library (@andrykonchin).

src/main/c/rubysignal/src/rubysignal.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,19 @@
88
* GNU Lesser General Public License version 2.1.
99
*/
1010
#include "org_truffleruby_signal_LibRubySignal.h"
11+
#include <locale.h>
1112
#include <pthread.h>
1213
#include <signal.h>
1314
#include <unistd.h>
1415
#include <sys/syscall.h>
1516

1617
_Static_assert(sizeof(pthread_t) == sizeof(jlong), "Expected sizeof(pthread_t) == sizeof(jlong)");
1718

19+
JNIEXPORT void JNICALL Java_org_truffleruby_signal_LibRubySignal_setupLocale(JNIEnv *env, jclass clazz) {
20+
setlocale(LC_ALL, "C");
21+
setlocale(LC_CTYPE, "");
22+
}
23+
1824
static void empty_handler(int sig) {
1925
}
2026

src/main/java/org/truffleruby/core/encoding/EncodingManager.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
import com.oracle.truffle.api.CompilerDirectives;
2323
import com.oracle.truffle.api.interop.InteropException;
2424
import com.oracle.truffle.api.interop.InteropLibrary;
25-
import org.graalvm.nativeimage.ImageInfo;
26-
import org.graalvm.nativeimage.ProcessProperties;
2725
import org.graalvm.shadowed.org.jcodings.Encoding;
2826
import org.graalvm.shadowed.org.jcodings.EncodingDB;
2927
import org.truffleruby.RubyContext;
@@ -39,6 +37,8 @@
3937

4038
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
4139
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
40+
import org.truffleruby.shared.Platform;
41+
import org.truffleruby.signal.LibRubySignal;
4242

4343
import static org.truffleruby.core.encoding.Encodings.INITIAL_NUMBER_OF_ENCODINGS;
4444

@@ -129,11 +129,16 @@ public void initializeDefaultEncodings(TruffleNFIPlatform nfi, NativeConfigurati
129129
}
130130

131131
private void initializeLocaleEncoding(TruffleNFIPlatform nfi, NativeConfiguration nativeConfiguration) {
132-
if (ImageInfo.inImageRuntimeCode()) {
133-
// Call setlocale(LC_ALL, "") to ensure the locale is set to the environment's locale
134-
// rather than the default "C" locale.
135-
ProcessProperties.setLocale("LC_ALL", "");
136-
}
132+
// CRuby does setlocale(LC_CTYPE, "") because this is needed to get the locale encoding with nl_langinfo(CODESET).
133+
// This means every locale category except LC_CTYPE remains the initial "C".
134+
// LC_CTYPE is set according to environment variables (LC_ALL, LC_CTYPE, LANG).
135+
// HotSpot does setlocale(LC_ALL, "") and Native Image does nothing.
136+
// We match CRuby by doing setlocale(LC_ALL, "C") and setlocale(LC_CTYPE, "").
137+
// This is notably important for Prism to be able to parse floating-point numbers:
138+
// https://github.com/ruby/prism/issues/2638
139+
// It also affects C functions that depend on the locale in C extensions, so best to follow CRuby here.
140+
LibRubySignal.loadLibrary(language.getRubyHome(), Platform.LIB_SUFFIX);
141+
LibRubySignal.setupLocale();
137142

138143
final String localeEncodingName;
139144
final String detector;

src/signal/java/org/truffleruby/signal/LibRubySignal.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public static void loadLibrary(String rubyHome, String libSuffix) {
1616
System.load(path);
1717
}
1818

19+
public static native void setupLocale();
20+
1921
public static native int setupSIGVTALRMEmptySignalHandler();
2022

2123
public static native long threadID();

0 commit comments

Comments
 (0)