mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
Locale error checking is now more robust.
This commit is contained in:
parent
8feb5a8124
commit
cddc305a75
@ -18,6 +18,7 @@
|
|||||||
#include "jni-util.h"
|
#include "jni-util.h"
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "fcntl.h"
|
#include "fcntl.h"
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
|
||||||
@ -132,6 +133,59 @@ namespace {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Locale {
|
||||||
|
static const unsigned MINLEN = 2;
|
||||||
|
static const unsigned MAXLEN = 3;
|
||||||
|
static const unsigned FIELDSIZE = MAXLEN + 1;
|
||||||
|
|
||||||
|
static const char* DEFAULT_LANGUAGE;
|
||||||
|
static const char* DEFAULT_REGION;
|
||||||
|
|
||||||
|
char language[FIELDSIZE];
|
||||||
|
char region[FIELDSIZE];
|
||||||
|
|
||||||
|
bool isLanguage(const char* language) {
|
||||||
|
if (!language) return false;
|
||||||
|
unsigned len = strlen(language);
|
||||||
|
if (len < MINLEN || len > MAXLEN) return false;
|
||||||
|
const char* p = language - 1;
|
||||||
|
while (islower(*++p));
|
||||||
|
if (*p != '\0') return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isRegion(const char* region) {
|
||||||
|
if (!region) return false;
|
||||||
|
unsigned len = strlen(region);
|
||||||
|
if ((len != 0 && len < MINLEN) || len > MAXLEN) return false;
|
||||||
|
const char* p = region - 1;
|
||||||
|
while (isupper(*++p));
|
||||||
|
if (*p != '\0') return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Locale(const char* language = "", const char* region = "") {
|
||||||
|
if (!isLanguage(language) || !isRegion(region)) {
|
||||||
|
language = DEFAULT_LANGUAGE;
|
||||||
|
region = DEFAULT_REGION;
|
||||||
|
}
|
||||||
|
memcpy(this->language, language, strlen(language) + 1);
|
||||||
|
memcpy(this->region, region, strlen(region) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale& operator=(const Locale& l) {
|
||||||
|
memcpy(language, l.language, FIELDSIZE);
|
||||||
|
memcpy(region, l.region, FIELDSIZE);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* getLanguage() { return reinterpret_cast<const char*>(language); }
|
||||||
|
const char* getRegion() { return reinterpret_cast<const char*>(region); }
|
||||||
|
};
|
||||||
|
const char* Locale::DEFAULT_LANGUAGE = "en";
|
||||||
|
const char* Locale::DEFAULT_REGION = "";
|
||||||
|
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
|
Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
|
||||||
@ -230,14 +284,12 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid)
|
|||||||
return exitCode;
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getLocale(char* language, char* region) {
|
Locale getLocale() {
|
||||||
const char dummy = '\0';
|
const char* lang = "";
|
||||||
const char* lang = &dummy;
|
const char* reg = "";
|
||||||
const char* reg = &dummy;
|
unsigned langid = GetUserDefaultUILanguage();
|
||||||
|
unsigned prilang = langid & 0x3ff;
|
||||||
unsigned locale = GetUserDefaultUILanguage();
|
unsigned sublang = langid >> 10;
|
||||||
unsigned prilang = locale & 0x3ff;
|
|
||||||
unsigned sublang = locale >> 10;
|
|
||||||
|
|
||||||
switch (prilang) {
|
switch (prilang) {
|
||||||
case 0x004: {
|
case 0x004: {
|
||||||
@ -301,10 +353,11 @@ void getLocale(char* language, char* region) {
|
|||||||
case 0x018: lang = "ro"; reg = "RO"; break;
|
case 0x018: lang = "ro"; reg = "RO"; break;
|
||||||
case 0x019: lang = "ru"; reg = "RU"; break;
|
case 0x019: lang = "ru"; reg = "RU"; break;
|
||||||
case 0x01d: lang = "sv"; reg = "SE"; break;
|
case 0x01d: lang = "sv"; reg = "SE"; break;
|
||||||
|
default: lang = "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (language) memcpy(language, lang, (strlen(lang) + 1) * sizeof(char));
|
Locale locale(lang, reg);
|
||||||
if (region) memcpy(region, reg, (strlen(reg) + 1) * sizeof(char));
|
return locale;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
@ -430,25 +483,30 @@ Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid)
|
|||||||
return exitCode;
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getLocale(char* language, char* region) {
|
Locale getLocale() {
|
||||||
unsigned langlen = 0, reglen = 0;
|
Locale fallback;
|
||||||
|
|
||||||
const char* LANG = getenv("LANG");
|
const char* LANG = getenv("LANG");
|
||||||
|
if (!LANG || strcmp(LANG, "C") == 0) return fallback;
|
||||||
|
|
||||||
if (LANG) {
|
int len = strlen(LANG);
|
||||||
while (langlen < strlen(LANG) && *(LANG + langlen) != '_') ++langlen;
|
char buf[len];
|
||||||
unsigned regend = langlen + 1;
|
memcpy(buf, LANG, len);
|
||||||
while (regend < strlen(LANG) && *(LANG + regend) != '.') ++regend;
|
|
||||||
reglen = regend - langlen - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (language) {
|
char* tracer = buf;
|
||||||
memcpy(language, LANG, langlen * sizeof(char));
|
const char* reg;
|
||||||
language[langlen] = '\0';
|
|
||||||
}
|
while (*tracer && *tracer != '_') ++tracer;
|
||||||
if (region) {
|
if (!*tracer) return fallback;
|
||||||
memcpy(region, LANG + langlen + 1, reglen * sizeof(char));
|
*tracer = '\0';
|
||||||
region[reglen] = '\0';
|
reg = tracer++ + 1;
|
||||||
}
|
|
||||||
|
while (*tracer && *tracer != '.') ++tracer;
|
||||||
|
if (tracer == reg) return fallback;
|
||||||
|
*tracer = '\0';
|
||||||
|
|
||||||
|
Locale locale(buf, reg);
|
||||||
|
return locale;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -551,13 +609,11 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (strcmp(chars, "user.language") == 0) {
|
else if (strcmp(chars, "user.language") == 0) {
|
||||||
char lang[16];
|
Locale locale = getLocale();
|
||||||
getLocale(lang, 0);
|
if (strlen(locale.getLanguage())) r = e->NewStringUTF(locale.getLanguage());
|
||||||
if (strlen(lang)) r = e->NewStringUTF(lang);
|
|
||||||
} else if (strcmp(chars, "user.region") == 0) {
|
} else if (strcmp(chars, "user.region") == 0) {
|
||||||
char reg[16];
|
Locale locale = getLocale();
|
||||||
getLocale(0, reg);
|
if (strlen(locale.getRegion())) r = e->NewStringUTF(locale.getRegion());
|
||||||
if (strlen(reg)) r = e->NewStringUTF(reg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e->ReleaseStringUTFChars(name, chars);
|
e->ReleaseStringUTFChars(name, chars);
|
||||||
|
Loading…
Reference in New Issue
Block a user