diff --git a/.circleci/config.yml b/.circleci/config.yml index e3d2a887a..1c0ab9ea7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,6 +25,10 @@ jobs: type: string steps: - checkout + - run: apt-get update -y + - run: apt-get install -y --no-install-recommends locales + - run: sed -i '/^# de_DE /s/^# //' /etc/locale.gen + - run: locale-gen - run: git submodule update --init --recursive - run: cmake -D XLNT_CXX_LANG=<< parameters.cxx-ver >> -D STATIC=<< parameters.static >> -D BENCHMARKS=<< parameters.benchmarks >> -D TESTS=ON -D SAMPLES=<< parameters.samples >> -D COVERAGE=<< parameters.coverage >> -D CMAKE_BUILD_TYPE=<< parameters.build-type >> . - run: cmake --build . -- -j2 diff --git a/include/xlnt/utils/numeric.hpp b/include/xlnt/utils/numeric.hpp index 901291338..52df17357 100644 --- a/include/xlnt/utils/numeric.hpp +++ b/include/xlnt/utils/numeric.hpp @@ -175,8 +175,9 @@ class number_serialiser return d; } char buf[30]; - assert(s.size() < sizeof(buf)); - auto copy_end = std::copy(s.begin(), s.end(), buf); + assert(s.size() + 1 < sizeof(buf)); + const char *cstr = s.c_str(); + auto copy_end = std::copy(cstr, cstr + s.size() + 1, buf); convert_pt_to_comma(buf, static_cast(copy_end - buf)); double d = strtod(buf, &end_of_convert); *len_converted = end_of_convert - buf; diff --git a/tests/data/Issue714_local_comma.xlsx b/tests/data/Issue714_local_comma.xlsx new file mode 100644 index 000000000..8d2d81f76 Binary files /dev/null and b/tests/data/Issue714_local_comma.xlsx differ diff --git a/tests/detail/numeric_util_test_suite.cpp b/tests/detail/numeric_util_test_suite.cpp index cf420a4a1..7c33817d1 100644 --- a/tests/detail/numeric_util_test_suite.cpp +++ b/tests/detail/numeric_util_test_suite.cpp @@ -23,6 +23,7 @@ #include #include +#include class numeric_test_suite : public test_suite { @@ -36,6 +37,7 @@ class numeric_test_suite : public test_suite register_test(test_min); register_test(test_max); register_test(test_abs); + register_test(test_locale_comma); } void test_serialise_number() @@ -219,5 +221,18 @@ class numeric_test_suite : public test_suite static_assert(xlnt::detail::abs(-1.23) == 1.23, "constexpr"); } + + void test_locale_comma () + { + struct SetLocale + { + SetLocale() {xlnt_assert(setlocale(LC_ALL, "de_DE") != nullptr);} // If failed, please install de_DE locale to correctly run this test. + ~SetLocale() {setlocale(LC_ALL, "C");} + } setLocale; + + xlnt::detail::number_serialiser serialiser; + xlnt_assert(serialiser.deserialise("1.99999999") == 1.99999999); + xlnt_assert(serialiser.deserialise("1.1") == 1.1); + } }; static numeric_test_suite x; diff --git a/tests/workbook/serialization_test_suite.cpp b/tests/workbook/serialization_test_suite.cpp index ca6383a18..d82689eee 100644 --- a/tests/workbook/serialization_test_suite.cpp +++ b/tests/workbook/serialization_test_suite.cpp @@ -73,6 +73,7 @@ class serialization_test_suite : public test_suite register_test(test_Issue503_external_link_load); register_test(test_formatting); register_test(test_active_sheet); + register_test(test_locale_comma); } bool workbook_matches_file(xlnt::workbook &wb, const xlnt::path &file) @@ -808,6 +809,21 @@ class serialization_test_suite : public test_suite wb.load(path_helper::test_file("20_active_sheet.xlsx")); xlnt_assert_equals(wb.active_sheet(), wb[2]); } + + void test_locale_comma () + { + struct SetLocale + { + SetLocale() {xlnt_assert(setlocale(LC_ALL, "de_DE") != nullptr);} // If failed, please install de_DE locale to correctly run this test. + ~SetLocale() {setlocale(LC_ALL, "C");} + } setLocale; + + xlnt::workbook wb; + wb.load(path_helper::test_file("Issue714_local_comma.xlsx")); + auto ws = wb.active_sheet(); + xlnt_assert_equals(ws.cell("A1").value(), 1.9999999999); + xlnt_assert_equals(ws.cell("A2").value(), 1.1); + } }; static serialization_test_suite x;