From 8a7a76b7dcc94e8e71725e26a146330c73377ebd Mon Sep 17 00:00:00 2001 From: Alexandre Rostovtsev Date: Mon, 26 Sep 2011 04:46:44 -0400 Subject: [PATCH 2/2] Switch LC_NUMERIC locale to "C" for decimal point separator safety Make sure to switch the LC_NUMERIC locale to "C" when using strtod() and fpritnf("%g",...) to ensure that '.' is used as the decimal point separator when reading and writing .ply files. --- rply.c | 31 +++++++++++++++++++++++++++---- 1 files changed, 27 insertions(+), 4 deletions(-) diff --git a/rply.c b/rply.c index 9eaa77f..789c002 100644 --- a/rply.c +++ b/rply.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -1229,13 +1230,27 @@ static int oascii_uint32(p_ply ply, double value) { } static int oascii_float32(p_ply ply, double value) { + char *curr_locale; + int ret; if (value < -FLT_MAX || value > FLT_MAX) return 0; - return fprintf(ply->fp, "%g ", (float) value) > 0; + /* Switch locale to C to use '.' as the decimal point separator */ + curr_locale = setlocale(LC_NUMERIC, NULL); + setlocale(LC_NUMERIC, "C"); + ret = fprintf(ply->fp, "%g ", (float) value); + setlocale(LC_NUMERIC, curr_locale); + return ret > 0; } static int oascii_float64(p_ply ply, double value) { + char *curr_locale; + int ret; if (value < -DBL_MAX || value > DBL_MAX) return 0; - return fprintf(ply->fp, "%g ", value) > 0; + /* Switch locale to C to use '.' as the decimal point separator */ + curr_locale = setlocale(LC_NUMERIC, NULL); + setlocale(LC_NUMERIC, "C"); + ret = fprintf(ply->fp, "%g ", value); + setlocale(LC_NUMERIC, curr_locale); + return ret > 0; } static int obinary_int8(p_ply ply, double value) { @@ -1336,17 +1351,25 @@ static int iascii_uint32(p_ply ply, double *value) { } static int iascii_float32(p_ply ply, double *value) { - char *end; + char *end, *curr_locale; if (!ply_read_word(ply)) return 0; + /* Switch locale to C to use '.' as the decimal point separator */ + curr_locale = setlocale(LC_NUMERIC, NULL); + setlocale(LC_NUMERIC, "C"); *value = strtod(BWORD(ply), &end); + setlocale(LC_NUMERIC, curr_locale); if (*end || *value < -FLT_MAX || *value > FLT_MAX) return 0; return 1; } static int iascii_float64(p_ply ply, double *value) { - char *end; + char *end, *curr_locale; if (!ply_read_word(ply)) return 0; + /* Switch locale to C to use '.' as the decimal point separator */ + curr_locale = setlocale(LC_NUMERIC, NULL); + setlocale(LC_NUMERIC, "C"); *value = strtod(BWORD(ply), &end); + setlocale(LC_NUMERIC, curr_locale); if (*end || *value < -DBL_MAX || *value > DBL_MAX) return 0; return 1; } -- 1.7.6.1