From 94677f4af8ad0f91e1aab1c4582288c2b62aa12b Mon Sep 17 00:00:00 2001 From: BenTalagan Date: Tue, 19 Nov 2019 09:54:11 +0100 Subject: [PATCH] Rule alignment fixes for non compliant platforms / Fix for emscripten demo --- emscripten/Makefile | 2 +- emscripten/post.js | 2 ++ src/libespeak-ng/dictionary.c | 8 ++++++-- src/libespeak-ng/readclause.c | 8 ++++++++ src/libespeak-ng/readclause.h | 6 +++++- src/libespeak-ng/translate.c | 2 +- 6 files changed, 23 insertions(+), 5 deletions(-) diff --git a/emscripten/Makefile b/emscripten/Makefile index e69095679a..e9850b4c49 100644 --- a/emscripten/Makefile +++ b/emscripten/Makefile @@ -100,7 +100,7 @@ CXXFLAGS+=-I ./ -I ../ -I ../src/include/espeak-ng #CXXFLAGS+=-s USE_PTHREADS=1 # NOTE: extra flags for emscripten -EM_CXXFLAGS=-s RESERVED_FUNCTION_POINTERS=2 --memory-init-file 0 -s FORCE_FILESYSTEM=1 -s WASM=0 +EM_CXXFLAGS=-s RESERVED_FUNCTION_POINTERS=2 --memory-init-file 0 -s FORCE_FILESYSTEM=1 -s WASM=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 diff --git a/emscripten/post.js b/emscripten/post.js index 045f38c50b..7105ed67ae 100644 --- a/emscripten/post.js +++ b/emscripten/post.js @@ -119,6 +119,8 @@ eSpeakNGWorker.prototype.synthesize_ipa = function (aText, aCallback) { if (typeof WorkerGlobalScope !== 'undefined') { var worker; + + Module.postRun = Module.postRun || []; Module.postRun.push(function () { worker = new eSpeakNGWorker(); diff --git a/src/libespeak-ng/dictionary.c b/src/libespeak-ng/dictionary.c index 3019678d16..b106428585 100644 --- a/src/libespeak-ng/dictionary.c +++ b/src/libespeak-ng/dictionary.c @@ -142,7 +142,7 @@ static void InitGroups(Translator *tr) // a RULE_GROUP_END. if (*p != RULE_GROUP_END) while (*p != 0) { if (*p != RULE_GROUP_START) { - fprintf(stderr, "Bad rules data in '%s_dict' at 0x%x (%c)\n", dictionary_name, (unsigned int)(p - tr->data_dictrules), p); + fprintf(stderr, "Bad rules data in '%s_dict' at 0x%x (%c)\n", dictionary_name, (unsigned int)(p - tr->data_dictrules), *p); break; } p++; @@ -150,8 +150,12 @@ static void InitGroups(Translator *tr) if (p[0] == RULE_REPLACEMENTS) { p = (char *)(((intptr_t)p+4) & ~3); // advance to next word boundary tr->langopts.replace_chars = (unsigned char *)p; - while (*(unsigned int *)p != 0) + + // Don't cast to (unsigned int), result may not be garanted depending on compiler + while ( !is_str_fully_empty(p, 4) ) { p++; + } + while (*p != RULE_GROUP_END) p++; p++; continue; diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c index a9cafb5864..823934ada7 100644 --- a/src/libespeak-ng/readclause.c +++ b/src/libespeak-ng/readclause.c @@ -132,6 +132,14 @@ int clause_type_from_codepoint(uint32_t c) return CLAUSE_NONE; } +int is_str_fully_empty(const char* str, int size) { + // Tests if all bytes of str are null uf to size + // This should never be reimplemented with integers, because + // this function has to work with unaligned char* + // (casting to int when unaligned may result in ungaranteed behaviors) + return *str || memcmp(str, str+1, size-1); +} + int towlower2(unsigned int c, Translator *translator) { // check for non-standard upper to lower case conversions diff --git a/src/libespeak-ng/readclause.h b/src/libespeak-ng/readclause.h index a49da28f9a..9a80991cc0 100644 --- a/src/libespeak-ng/readclause.h +++ b/src/libespeak-ng/readclause.h @@ -34,7 +34,10 @@ typedef struct { extern PARAM_STACK param_stack[]; - int clause_type_from_codepoint(uint32_t c); +// Tests if all bytes of str up to size are null +int is_str_fully_empty(const char* str, int size); + +int clause_type_from_codepoint(uint32_t c); int towlower2(unsigned int c, Translator *translator); // Supports Turkish I int Eof(void); const char *WordToString2(unsigned int word); @@ -52,6 +55,7 @@ int ReadClause(Translator *tr, + #ifdef __cplusplus } #endif diff --git a/src/libespeak-ng/translate.c b/src/libespeak-ng/translate.c index eeaa19ea6e..e34bf91944 100644 --- a/src/libespeak-ng/translate.c +++ b/src/libespeak-ng/translate.c @@ -1793,7 +1793,7 @@ static int EmbeddedCommand(unsigned int *source_index_out) static const char *FindReplacementChars(Translator *tr, const char **pfrom, unsigned int c, const char *next, int *ignore_next_n) { const char *from = *pfrom; - while (*(unsigned int *)from != 0) { + while ( !is_str_fully_empty(from, 4) ) { unsigned int fc = 0; // from character unsigned int nc = c; // next character const char *match_next = next;