PR143: don't hang with invalid locale
authorStefan Ring <stefan@complang.tuwien.ac.at>
Wed, 29 Dec 2010 18:36:32 +0000 (19:36 +0100)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Wed, 29 Dec 2010 18:36:32 +0000 (19:36 +0100)
* THIRDPARTY: Documented lc-messages.m4.
* configure.ac: Added various locale checks.
* m4/lc-messages.m4: New file for detecting LC_MESSAGES.
* src/vm/properties.cpp: Validate locale names before passing them on to
classpath.

THIRDPARTY
configure.ac
m4/lc-messages.m4 [new file with mode: 0644]
src/vm/properties.cpp

index 24002d4bbc24ec4430e40614fed4f8428dc113c4..62d6e5b1fdd1d94488f635248604420759a67a46 100644 (file)
@@ -169,6 +169,16 @@ are permitted in any medium without royalty provided the copyright
 notice and this notice are preserved.
 
 
+* m4/lc-messages.m4
+
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+# This file can be copied and used freely without restrictions.  It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+
 * contrib/vmlog
 
 Copyright (C) 2006 Edwin Steiner <edwin.steiner@gmx.net>
index 14f2095f2e8392038fd5d6adc23f507740db54ea..566df603883de22acb9a3974c3c4216420197d40 100644 (file)
@@ -1,6 +1,6 @@
 dnl configure.ac
 dnl
-dnl Copyright (C) 1996-2005, 2006, 2007, 2008
+dnl Copyright (C) 1996-2010
 dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 dnl 
 dnl This file is part of CACAO.
@@ -278,6 +278,7 @@ AC_CHECK_HEADERS([errno.h])
 AC_CHECK_HEADERS([execinfo.h])
 AC_CHECK_HEADERS([fcntl.h])
 AC_CHECK_HEADERS([libgen.h])
+AC_CHECK_HEADERS([locale.h])
 AC_CHECK_HEADERS([netdb.h])
 AC_CHECK_HEADERS([signal.h])
 AC_CHECK_HEADERS([stdarg.h])
@@ -377,6 +378,7 @@ AC_CHECK_FUNCS([recv])
 AC_CHECK_FUNCS([scandir])
 AC_CHECK_FUNCS([select])
 AC_CHECK_FUNCS([send])
+AC_CHECK_FUNCS([setlocale])
 AC_CHECK_FUNCS([setsockopt])
 AC_CHECK_FUNCS([shutdown])
 AC_CHECK_FUNCS([socket])
@@ -394,6 +396,7 @@ AC_CHECK_FUNCS([strstr])
 AC_CHECK_FUNCS([time])
 AC_CHECK_FUNCS([write])
 
+AM_LC_MESSAGES
 
 dnl Checks for libraries.
 
diff --git a/m4/lc-messages.m4 b/m4/lc-messages.m4
new file mode 100644 (file)
index 0000000..7d0bfeb
--- /dev/null
@@ -0,0 +1,21 @@
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions.  It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 2
+
+AC_DEFUN([AM_LC_MESSAGES],
+  [if test $ac_cv_header_locale_h = yes; then
+    AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+      [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+       am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+    if test $am_cv_val_LC_MESSAGES = yes; then
+      AC_DEFINE(HAVE_LC_MESSAGES, 1,
+        [Define if your <locale.h> file defines LC_MESSAGES.])
+    fi
+  fi])
+
index 985791cbe39236cd50026104d495c10d14a4562a..c1029c660d602f7c5c399b0c9bbbbeb4177f5949 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/properties.cpp - handling commandline properties
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2010
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -48,6 +48,9 @@
 
 #include "vm/jit/asmpart.h"
 
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
 
 /**
  * Constructor fills the properties list with default values.
@@ -433,28 +436,33 @@ Properties::Properties()
 
        /* get locale */
 
+       bool use_en_US = true;
        if (env_lang != NULL) {
-               /* get the local stuff from the environment */
-
-               if (strlen(env_lang) <= 2) {
-                       put("user.language", env_lang);
-               }
-               else {
-                       if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
+#if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
+               /* get the locale stuff from the environment */
+               char *locale;
+
+               if ((locale = setlocale(LC_MESSAGES, ""))) {
+                       int len = strlen(locale);
+                       if (((len >= 5) && (locale[2] == '_')) || len == 2)  {
+                               use_en_US = false;
                                char* lang = MNEW(char, 3);
-                               strncpy(lang, (char*) &env_lang[0], 2);
+                               strncpy(lang, (char*) &locale[0], 2);
                                lang[2] = '\0';
+                               put("user.language", lang);
 
-                               char* country = MNEW(char, 3);
-                               strncpy(country, (char*) &env_lang[3], 2);
-                               country[2] = '\0';
+                               if (len >= 5) {
+                                       char* country = MNEW(char, 3);
+                                       strncpy(country, (char*) &locale[3], 2);
+                                       country[2] = '\0';
 
-                               put("user.language", lang);
-                               put("user.country", country);
+                                       put("user.country", country);
+                               }
                        }
                }
+#endif
        }
-       else {
+       if (use_en_US) {
                /* if no default locale was specified, use `en_US' */
 
                put("user.language", "en");