Skip to content

Commit 7686f1b

Browse files
authored
Allow infinity and NaN to be parsed. (#26)
* Allow infinity and NaN to be parsed. * Use libc++ (instead of libstdc++) when using clang * Exclude an ASAN option due to a bug.
1 parent 66be1fb commit 7686f1b

File tree

4 files changed

+60
-26
lines changed

4 files changed

+60
-26
lines changed

.circleci/config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ jobs:
4242
resource_class: xlarge
4343
environment:
4444
MAKE_JOB_COUNT: 8
45+
# See <https://github.com/llvm/llvm-project/issues/59432>.
46+
ASAN_OPTIONS: alloc_dealloc_mismatch=0
4547
steps:
4648
- checkout
4749
- run: mkdir .build

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ set(CMAKE_CXX_STANDARD 17)
1717
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1818
set(CMAKE_CXX_EXTENSIONS OFF)
1919

20+
# If we're building with clang, then use the libc++ version of the standard
21+
# library instead of libstdc++. Better coverage of build configurations.
22+
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
23+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
24+
endif()
25+
2026
include(ProcessorCount)
2127
ProcessorCount(NUM_PROCESSORS)
2228
set(MAKE_JOB_COUNT ${NUM_PROCESSORS} CACHE STRING "Number of jobs to use when building libcurl")

Dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ env DEBIAN_FRONTEND=noninteractive
1010
# - Make available more recent versions of git.
1111
# - Update the package lists and upgrade already-installed software.
1212
# - Install build tooling:
13-
# - GCC, clang, make, git, debugger, formatter, and miscellanea
13+
# - GCC, clang, libc++, make, git, debugger, formatter, and miscellanea
1414
run apt-get update && apt-get install --yes software-properties-common && \
1515
add-apt-repository ppa:git-core/ppa --yes && \
1616
apt-get update && apt-get upgrade --yes && \
17-
apt-get install --yes wget build-essential clang sed gdb clang-format git ssh shellcheck
17+
apt-get install --yes \
18+
wget build-essential clang sed gdb clang-format git ssh shellcheck \
19+
libc++-dev libc++abi-dev
1820

1921
# bazelisk, a launcher for bazel. `bazelisk --help` will cause the latest
2022
# version to be downloaded.

test/test_tracer_config.cpp

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -585,28 +585,35 @@ TEST_CASE("TracerConfig::trace_sampler") {
585585
struct TestCase {
586586
std::string name;
587587
std::string env_value;
588-
Error::Code expected_error;
588+
std::vector<Error::Code> allowed_errors;
589589
};
590590

591591
auto test_case = GENERATE(values<TestCase>({
592-
{"empty", "", Error::INVALID_DOUBLE},
593-
{"nonsense", "nonsense", Error::INVALID_DOUBLE},
594-
{"trailing space", "0.23 ", Error::INVALID_DOUBLE},
595-
{"out of range of double", "123e9999999999", Error::INVALID_DOUBLE},
596-
{"NaN", "NaN", Error::INVALID_DOUBLE},
597-
{"nan", "nan", Error::INVALID_DOUBLE},
598-
{"inf", "inf", Error::INVALID_DOUBLE},
599-
{"Inf", "Inf", Error::INVALID_DOUBLE},
600-
{"below range", "-0.1", Error::RATE_OUT_OF_RANGE},
601-
{"above range", "1.1", Error::RATE_OUT_OF_RANGE},
592+
{"empty", "", {Error::INVALID_DOUBLE}},
593+
{"nonsense", "nonsense", {Error::INVALID_DOUBLE}},
594+
{"trailing space", "0.23 ", {Error::INVALID_DOUBLE}},
595+
{"out of range of double", "123e9999999999", {Error::INVALID_DOUBLE}},
596+
// Some C++ standard libraries parse "nan" and "inf" as the
597+
// corresponding special floating point values. Other standard
598+
// libraries consider "nan" and "inf" invalid.
599+
// So, either the double will fail to parse, or parsing will succeed
600+
// but the resulting value will be outside of the inclusive range
601+
// [0.0, 1.0] of the `Rate` type.
602+
{"NaN", "NaN", {Error::INVALID_DOUBLE, Error::RATE_OUT_OF_RANGE}},
603+
{"nan", "nan", {Error::INVALID_DOUBLE, Error::RATE_OUT_OF_RANGE}},
604+
{"inf", "inf", {Error::INVALID_DOUBLE, Error::RATE_OUT_OF_RANGE}},
605+
{"Inf", "Inf", {Error::INVALID_DOUBLE, Error::RATE_OUT_OF_RANGE}},
606+
{"below range", "-0.1", {Error::RATE_OUT_OF_RANGE}},
607+
{"above range", "1.1", {Error::RATE_OUT_OF_RANGE}},
602608
}));
603609

604610
CAPTURE(test_case.name);
605611

606612
const EnvGuard guard{"DD_TRACE_SAMPLE_RATE", test_case.env_value};
607613
auto finalized = finalize_config(config);
608614
REQUIRE(!finalized);
609-
REQUIRE(finalized.error().code == test_case.expected_error);
615+
REQUIRE_THAT(test_case.allowed_errors,
616+
Catch::Matchers::VectorContains(finalized.error().code));
610617
}
611618
}
612619

@@ -644,28 +651,45 @@ TEST_CASE("TracerConfig::trace_sampler") {
644651
struct TestCase {
645652
std::string name;
646653
std::string env_value;
647-
Error::Code expected_error;
654+
std::vector<Error::Code> allowed_errors;
648655
};
649656

650657
auto test_case = GENERATE(values<TestCase>({
651-
{"empty", "", Error::INVALID_DOUBLE},
652-
{"nonsense", "nonsense", Error::INVALID_DOUBLE},
653-
{"trailing space", "23 ", Error::INVALID_DOUBLE},
654-
{"out of range of double", "123e9999999999", Error::INVALID_DOUBLE},
655-
{"NaN", "NaN", Error::INVALID_DOUBLE},
656-
{"nan", "nan", Error::INVALID_DOUBLE},
657-
{"inf", "inf", Error::INVALID_DOUBLE},
658-
{"Inf", "Inf", Error::INVALID_DOUBLE},
659-
{"below range", "-0.1", Error::MAX_PER_SECOND_OUT_OF_RANGE},
660-
{"zero (also below range)", "0", Error::MAX_PER_SECOND_OUT_OF_RANGE},
658+
{"empty", "", {Error::INVALID_DOUBLE}},
659+
{"nonsense", "nonsense", {Error::INVALID_DOUBLE}},
660+
{"trailing space", "23 ", {Error::INVALID_DOUBLE}},
661+
{"out of range of double", "123e9999999999", {Error::INVALID_DOUBLE}},
662+
// Some C++ standard libraries parse "nan" and "inf" as the
663+
// corresponding special floating point values. Other standard
664+
// libraries consider "nan" and "inf" invalid.
665+
// So, either the double will fail to parse, or parsing will succeed
666+
// but the resulting value will be outside of the exclusive range
667+
// (0.0, Inf) allowed.
668+
{"NaN",
669+
"NaN",
670+
{Error::INVALID_DOUBLE, Error::MAX_PER_SECOND_OUT_OF_RANGE}},
671+
{"nan",
672+
"nan",
673+
{Error::INVALID_DOUBLE, Error::MAX_PER_SECOND_OUT_OF_RANGE}},
674+
{"inf",
675+
"inf",
676+
{Error::INVALID_DOUBLE, Error::MAX_PER_SECOND_OUT_OF_RANGE}},
677+
{"Inf",
678+
"Inf",
679+
{Error::INVALID_DOUBLE, Error::MAX_PER_SECOND_OUT_OF_RANGE}},
680+
{"below range", "-0.1", {Error::MAX_PER_SECOND_OUT_OF_RANGE}},
681+
{"zero (also below range)",
682+
"0",
683+
{Error::MAX_PER_SECOND_OUT_OF_RANGE}},
661684
}));
662685

663686
CAPTURE(test_case.name);
664687

665688
const EnvGuard guard{"DD_TRACE_RATE_LIMIT", test_case.env_value};
666689
auto finalized = finalize_config(config);
667690
REQUIRE(!finalized);
668-
REQUIRE(finalized.error().code == test_case.expected_error);
691+
REQUIRE_THAT(test_case.allowed_errors,
692+
Catch::Matchers::VectorContains(finalized.error().code));
669693
}
670694
}
671695

0 commit comments

Comments
 (0)