diff --git a/src/m_misc.c b/src/m_misc.c index 5815d17c54619f46afe6fc29c1277a3621ecc77b..1b6a90c50acd6230cb9d8c56f99df7178926c777 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2259,6 +2259,44 @@ boolean M_IsStringEmpty(const char *s) return true; } +// Converts a string containing a whole number into an int. Returns false if the conversion failed. +boolean M_StringToNumber(const char *input, int *out) +{ + char *end_position = NULL; + + errno = 0; + + int result = strtol(input, &end_position, 10); + if (end_position == input || *end_position != '\0') + return false; + + if (errno == ERANGE) + return false; + + *out = result; + + return true; +} + +// Converts a string containing a number into a double. Returns false if the conversion failed. +boolean M_StringToDecimal(const char *input, double *out) +{ + char *end_position = NULL; + + errno = 0; + + double result = strtod(input, &end_position); + if (end_position == input || *end_position != '\0') + return false; + + if (errno == ERANGE) + return false; + + *out = result; + + return true; +} + // Rounds off floating numbers and checks for 0 - 255 bounds int M_RoundUp(double number) { diff --git a/src/m_misc.h b/src/m_misc.h index 753991e70465c075fa874ce7662d6aa6603e7b6a..04ac66ca65e1ff92d44172b12e1186cdaa04b648 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -109,6 +109,12 @@ const char * M_Ftrim (double); // Returns true if the string is empty. boolean M_IsStringEmpty(const char *s); +// Converts a string containing a whole number into an int. Returns false if the conversion failed. +boolean M_StringToNumber(const char *input, int *out); + +// Converts a string containing a number into a double. Returns false if the conversion failed. +boolean M_StringToDecimal(const char *input, double *out); + // counting bits, for weapon ammo code, usually FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); diff --git a/src/r_translation.c b/src/r_translation.c index a4df3cde0c9bdc04702f963e62b3703ca6f42c58..d86f3ad9598f258c782a0d050c89dbead64213b6 100644 --- a/src/r_translation.c +++ b/src/r_translation.c @@ -17,6 +17,7 @@ #include "z_zone.h" #include "w_wad.h" #include "m_tokenizer.h" +#include "m_misc.h" #include <errno.h> @@ -528,50 +529,26 @@ void R_LoadParsedTranslations(void) static boolean ExpectToken(tokenizer_t *sc, const char *expect) { - return strcmp(sc->get(sc, 0), expect) == 0; -} - -static boolean StringToNumber(const char *tkn, int *out) -{ - char *endPos = NULL; - - errno = 0; - - int result = strtol(tkn, &endPos, 10); - if (endPos == tkn || *endPos != '\0') - return false; - - if (errno == ERANGE) + const char *tkn = sc->get(sc, 0); + if (!tkn) return false; - - *out = result; - - return true; + return strcmp(tkn, expect) == 0; } static boolean ParseNumber(tokenizer_t *sc, int *out) { - return StringToNumber(sc->get(sc, 0), out); + const char *tkn = sc->get(sc, 0); + if (!tkn) + return false; + return M_StringToNumber(tkn, out); } static boolean ParseDecimal(tokenizer_t *sc, double *out) { const char *tkn = sc->get(sc, 0); - - char *endPos = NULL; - - errno = 0; - - double result = strtod(tkn, &endPos); - if (endPos == tkn || *endPos != '\0') - return false; - - if (errno == ERANGE) + if (!tkn) return false; - - *out = result; - - return true; + return M_StringToDecimal(tkn, out); } static struct PaletteRemapParseResult *ThrowError(const char *format, ...) @@ -615,6 +592,9 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc) return ThrowError("expected '='"); const char *tkn = sc->get(sc, 0); + if (tkn == NULL) + return ThrowError("unexpected EOF"); + if (strcmp(tkn, "[") == 0) { // translation using RGB values @@ -785,7 +765,7 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc) { int pal1, pal2; - if (!StringToNumber(tkn, &pal1)) + if (!M_StringToNumber(tkn, &pal1)) return ThrowError("expected a number for starting index"); if (!ExpectToken(sc, ":")) return ThrowError("expected ':'"); @@ -809,6 +789,13 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseTranslation(const char return result; } +#define CHECK_EOF() \ + if (!tkn) \ + { \ + CONS_Alert(CONS_ERROR, "Error parsing translation '%s': Unexpected EOF\n", name); \ + goto fail; \ + } + void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) { char *lumpData = (char *)W_CacheLumpNumPwad(wadNum, lumpnum, PU_STATIC); @@ -827,9 +814,11 @@ void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) char *name = Z_StrDup(tkn); tkn = sc->get(sc, 0); + CHECK_EOF(); if (strcmp(tkn, ":") == 0) { tkn = sc->get(sc, 0); + CHECK_EOF(); base_translation = R_FindCustomTranslation(tkn); if (base_translation == -1) @@ -847,6 +836,15 @@ void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) goto fail; } tkn = sc->get(sc, 0); + CHECK_EOF(); + + if (strcmp(tkn, "\"") != 0) + { + CONS_Alert(CONS_ERROR, "Error parsing translation '%s': Expected '=', got '%s'\n", name, tkn); + goto fail; + } + tkn = sc->get(sc, 0); + CHECK_EOF(); struct PaletteRemapParseResult *result = NULL; do { @@ -862,10 +860,15 @@ void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) if (!tkn) break; - if (strcmp(tkn, ",") != 0) - break; + if (strcmp(tkn, "\"") != 0) + { + CONS_Alert(CONS_ERROR, "Error parsing translation '%s': Expected '=', got '%s'\n", name, tkn); + goto fail; + } tkn = sc->get(sc, 0); + if (!tkn || strcmp(tkn, ",") != 0) + break; } while (true); // Allocate it and register it @@ -886,6 +889,8 @@ fail: Z_Free(text); } +#undef CHECK_EOF + typedef struct CustomTranslation { char *name;