Skip to content

Commit c4369ae

Browse files
authored
fix stack overflow by limiting the maximum depth of dotted keys (#242)
1 parent 380c49f commit c4369ae

File tree

6 files changed

+26
-4
lines changed

6 files changed

+26
-4
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ UTF-8 decoding is performed using a state machine based on Bjoern Hoehrmann's '[
306306
- **[@whiterabbit963](https://github.com/whiterabbit963)** - Fixed a bug with value_or conversions
307307
- **[@ximion](https://github.com/ximion)** - Added support for installation with meson
308308
- **[@a-is](https://github.com/a-is)** - Fixed a bug
309-
-**[@capuanob](https://github.com/capuanob)** - Integrated this project into OSSFuzz
309+
- **[@capuanob](https://github.com/capuanob)** - Integrated this project into OSSFuzz
310+
- **[@tyler92]** - Fixed stack overflow that occurred during fuzzing tests
310311
<br>
311312

312313
## Contact

fuzzing/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ cmake -S . -B build -DBUILD_FUZZER=ON && cmake --build build --target install
55
# Build the corpus using the existing toml files in the source
66
mkdir -p corpus
77
find $SRC/tomlplusplus -name "*.toml" -exec cp {} corpus \;
8-
zip -q $OUT/toml_fuzzer_seed_corpus.zip corpus/*
8+
zip -q -j $OUT/toml_fuzzer_seed_corpus.zip corpus/*

include/toml++/impl/parser.inl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,8 @@ TOML_IMPL_NAMESPACE_START
10631063
class parser
10641064
{
10651065
private:
1066-
static constexpr size_t max_nested_values = TOML_MAX_NESTED_VALUES;
1066+
static constexpr size_t max_nested_values = TOML_MAX_NESTED_VALUES;
1067+
static constexpr size_t max_dotted_keys_depth = TOML_MAX_DOTTED_KEYS_DEPTH;
10671068

10681069
utf8_buffered_reader reader;
10691070
table root;
@@ -3085,6 +3086,11 @@ TOML_IMPL_NAMESPACE_START
30853086
// store segment
30863087
key_buffer.push_back(key_segment, key_begin, key_end);
30873088

3089+
if TOML_UNLIKELY(key_buffer.size() > max_dotted_keys_depth)
3090+
set_error_and_return_default("exceeded maximum dotted keys depth of "sv,
3091+
max_dotted_keys_depth,
3092+
" (TOML_MAX_DOTTED_KEYS_DEPTH)"sv);
3093+
30883094
// eof or no more key to come
30893095
if (is_eof() || *cp != U'.')
30903096
break;

include/toml++/impl/preprocessor.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,10 @@
11821182
// 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job...
11831183
#endif
11841184

1185+
#ifndef TOML_MAX_DOTTED_KEYS_DEPTH
1186+
#define TOML_MAX_DOTTED_KEYS_DEPTH 1024
1187+
#endif
1188+
11851189
#ifdef TOML_CHAR_8_STRINGS
11861190
#if TOML_CHAR_8_STRINGS
11871191
#error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly.

toml.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,10 @@
10911091
// 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job...
10921092
#endif
10931093

1094+
#ifndef TOML_MAX_DOTTED_KEYS_DEPTH
1095+
#define TOML_MAX_DOTTED_KEYS_DEPTH 1024
1096+
#endif
1097+
10941098
#ifdef TOML_CHAR_8_STRINGS
10951099
#if TOML_CHAR_8_STRINGS
10961100
#error TOML_CHAR_8_STRINGS was removed in toml++ 2.0.0; all value setters and getters now work with char8_t strings implicitly.
@@ -13554,7 +13558,8 @@ TOML_IMPL_NAMESPACE_START
1355413558
class parser
1355513559
{
1355613560
private:
13557-
static constexpr size_t max_nested_values = TOML_MAX_NESTED_VALUES;
13561+
static constexpr size_t max_nested_values = TOML_MAX_NESTED_VALUES;
13562+
static constexpr size_t max_dotted_keys_depth = TOML_MAX_DOTTED_KEYS_DEPTH;
1355813563

1355913564
utf8_buffered_reader reader;
1356013565
table root;
@@ -15575,6 +15580,11 @@ TOML_IMPL_NAMESPACE_START
1557515580
// store segment
1557615581
key_buffer.push_back(key_segment, key_begin, key_end);
1557715582

15583+
if TOML_UNLIKELY(key_buffer.size() > max_dotted_keys_depth)
15584+
set_error_and_return_default("exceeded maximum dotted keys depth of "sv,
15585+
max_dotted_keys_depth,
15586+
" (TOML_MAX_DOTTED_KEYS_DEPTH)"sv);
15587+
1557815588
// eof or no more key to come
1557915589
if (is_eof() || *cp != U'.')
1558015590
break;

tools/generate_single_header.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ def main():
231231
r'TOML_LIB_PATCH',
232232
r'TOML_LIB_SINGLE_HEADER',
233233
r'TOML_MAX_NESTED_VALUES',
234+
r'TOML_MAX_DOTTED_KEYS_DEPTH',
234235
r'TOML_NAMESPACE_END',
235236
r'TOML_NAMESPACE_START',
236237
r'TOML_OPTIONAL_TYPE',

0 commit comments

Comments
 (0)