Skip to content

Commit b036074

Browse files
committed
check for input size larger than allowed size of sequence
1 parent 85f9e92 commit b036074

File tree

2 files changed

+75
-74
lines changed

2 files changed

+75
-74
lines changed

include/boost/json/detail/parse_into.hpp

Lines changed: 73 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,10 @@ class composite_handler
158158
# pragma GCC diagnostic pop
159159
#endif
160160

161-
bool signal_end(system::error_code&)
161+
bool signal_end(system::error_code& ec)
162162
{
163163
inner_active_ = false;
164-
parent_->signal_value();
165-
return true;
164+
return parent_->signal_value(ec);
166165
}
167166

168167
#define BOOST_JSON_INVOKE_INNER(f) \
@@ -285,7 +284,7 @@ class converting_handler<integral_conversion_tag, V, P>
285284
return true;
286285
}
287286

288-
bool on_int64( system::error_code& ec, std::int64_t v )
287+
bool on_int64(system::error_code& ec, std::int64_t v)
289288
{
290289
if( !integral_in_range<V>( v ) )
291290
{
@@ -294,23 +293,19 @@ class converting_handler<integral_conversion_tag, V, P>
294293
}
295294

296295
*value_ = static_cast<V>( v );
297-
298-
this->parent_->signal_value();
299-
return true;
296+
return this->parent_->signal_value(ec);
300297
}
301298

302-
bool on_uint64( system::error_code& ec, std::uint64_t v )
299+
bool on_uint64(system::error_code& ec, std::uint64_t v)
303300
{
304-
if( !integral_in_range<V>( v ) )
301+
if( !integral_in_range<V>(v) )
305302
{
306303
BOOST_JSON_FAIL( ec, error::not_exact );
307304
return false;
308305
}
309306

310-
*value_ = static_cast<V>( v );
311-
312-
this->parent_->signal_value();
313-
return true;
307+
*value_ = static_cast<V>(v);
308+
return this->parent_->signal_value(ec);
314309
}
315310
};
316311

@@ -333,28 +328,22 @@ class converting_handler<floating_point_conversion_tag, V, P>
333328
return true;
334329
}
335330

336-
bool on_int64( system::error_code&, std::int64_t v )
331+
bool on_int64(system::error_code& ec, std::int64_t v)
337332
{
338-
*value_ = static_cast<V>( v );
339-
340-
this->parent_->signal_value();
341-
return true;
333+
*value_ = static_cast<V>(v);
334+
return this->parent_->signal_value(ec);
342335
}
343336

344-
bool on_uint64( system::error_code&, std::uint64_t v )
337+
bool on_uint64(system::error_code& ec, std::uint64_t v)
345338
{
346-
*value_ = static_cast<V>( v );
347-
348-
this->parent_->signal_value();
349-
return true;
339+
*value_ = static_cast<V>(v);
340+
return this->parent_->signal_value(ec);
350341
}
351342

352-
bool on_double( system::error_code&, double v )
343+
bool on_double(system::error_code& ec, double v)
353344
{
354-
*value_ = static_cast<V>( v );
355-
356-
this->parent_->signal_value();
357-
return true;
345+
*value_ = static_cast<V>(v);
346+
return this->parent_->signal_value(ec);
358347
}
359348
};
360349

@@ -385,17 +374,15 @@ class converting_handler<string_like_conversion_tag, V, P>
385374
return true;
386375
}
387376

388-
bool on_string( system::error_code&, string_view sv )
377+
bool on_string(system::error_code& ec, string_view sv)
389378
{
390379
if( !cleared_ )
391380
value_->clear();
392381
else
393382
cleared_ = false;
394383

395384
value_->append( sv.begin(), sv.end() );
396-
397-
this->parent_->signal_value();
398-
return true;
385+
return this->parent_->signal_value(ec);
399386
}
400387
};
401388

@@ -413,12 +400,10 @@ class converting_handler<bool_conversion_tag, V, P>
413400
, value_(v)
414401
{}
415402

416-
bool on_bool( system::error_code&, bool v )
403+
bool on_bool(system::error_code& ec, bool v)
417404
{
418405
*value_ = v;
419-
420-
this->parent_->signal_value();
421-
return true;
406+
return this->parent_->signal_value(ec);
422407
}
423408
};
424409

@@ -436,12 +421,10 @@ class converting_handler<null_like_conversion_tag, V, P>
436421
, value_(v)
437422
{}
438423

439-
bool on_null( system::error_code& )
424+
bool on_null(system::error_code& ec)
440425
{
441426
*value_ = {};
442-
443-
this->parent_->signal_value();
444-
return true;
427+
return this->parent_->signal_value(ec);
445428
}
446429
};
447430

@@ -473,7 +456,7 @@ class converting_handler<described_enum_conversion_tag, V, P>
473456
return true;
474457
}
475458

476-
bool on_string( system::error_code& ec, string_view sv )
459+
bool on_string(system::error_code& ec, string_view sv)
477460
{
478461
string_view name = sv;
479462
if( !name_.empty() )
@@ -488,8 +471,7 @@ class converting_handler<described_enum_conversion_tag, V, P>
488471
return false;
489472
}
490473

491-
this->parent_->signal_value();
492-
return true;
474+
return this->parent_->signal_value(ec);
493475
}
494476

495477
#endif // BOOST_DESCRIBE_CXX14
@@ -503,13 +485,25 @@ class converting_handler<no_conversion_tag, V, P>
503485

504486
// sequence handler
505487
template< class It >
506-
bool check_inserter( It l, It r )
488+
bool cannot_insert(It i, It e)
489+
{
490+
return i == e;
491+
}
492+
493+
template< class It1, class It2 >
494+
std::false_type cannot_insert(It1, It2)
495+
{
496+
return {};
497+
}
498+
499+
template< class It >
500+
bool needs_more_elements(It i, It e)
507501
{
508-
return l == r;
502+
return i != e;
509503
}
510504

511505
template< class It1, class It2 >
512-
std::true_type check_inserter( It1, It2 )
506+
std::false_type needs_more_elements(It1, It2)
513507
{
514508
return {};
515509
}
@@ -562,8 +556,14 @@ class converting_handler<sequence_conversion_tag, V, P>
562556
, inserter( detail::inserter(*value_, inserter_implementation<V>()) )
563557
{}
564558

565-
void signal_value()
559+
bool signal_value(system::error_code& ec)
566560
{
561+
if(cannot_insert( inserter, value_->end() ))
562+
{
563+
BOOST_JSON_FAIL( ec, error::size_mismatch );
564+
return false;
565+
}
566+
567567
*inserter++ = std::move(this->next_value_);
568568
#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
569569
# pragma GCC diagnostic push
@@ -573,11 +573,12 @@ class converting_handler<sequence_conversion_tag, V, P>
573573
#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
574574
# pragma GCC diagnostic pop
575575
#endif
576+
return true;
576577
}
577578

578579
bool signal_end(system::error_code& ec)
579580
{
580-
if( !check_inserter( inserter, value_->end() ) )
581+
if(needs_more_elements( inserter, value_->end() ))
581582
{
582583
BOOST_JSON_FAIL( ec, error::size_mismatch );
583584
return false;
@@ -625,14 +626,16 @@ class converting_handler<map_like_conversion_tag, V, P>
625626
: converting_handler::composite_handler(p), value_(v)
626627
{}
627628

628-
void signal_value()
629+
bool signal_value(system::error_code&)
629630
{
630631
value_->emplace( std::move(key_), std::move(this->next_value_) );
631632

632633
key_ = {};
633634
this->next_value_ = {};
634635

635636
this->inner_active_ = false;
637+
638+
return true;
636639
}
637640

638641
bool on_object_begin( system::error_code& ec )
@@ -644,13 +647,12 @@ class converting_handler<map_like_conversion_tag, V, P>
644647
return true;
645648
}
646649

647-
bool on_object_end( system::error_code& ec )
650+
bool on_object_end(system::error_code& ec)
648651
{
649652
if( this->inner_active_ )
650653
return this->inner_.on_object_end(ec);
651654

652-
this->parent_->signal_value();
653-
return true;
655+
return this->parent_->signal_value(ec);
654656
}
655657

656658
bool on_array_end( system::error_code& ec )
@@ -815,9 +817,10 @@ class converting_handler<tuple_conversion_tag, T, P>
815817
: value_(v) , parent_(p) , handlers_(tuple_accessor(), v, this)
816818
{}
817819

818-
void signal_value()
820+
bool signal_value(system::error_code&)
819821
{
820822
++inner_active_;
823+
return true;
821824
}
822825

823826
bool signal_end(system::error_code& ec)
@@ -830,8 +833,7 @@ class converting_handler<tuple_conversion_tag, T, P>
830833
}
831834

832835
inner_active_ = -1;
833-
parent_->signal_value();
834-
return true;
836+
return parent_->signal_value(ec);
835837
}
836838

837839
#define BOOST_JSON_HANDLE_EVENT(fn) \
@@ -1027,7 +1029,8 @@ class converting_handler<described_class_conversion_tag, V, P>
10271029
return !is_optional_like<T>::value;
10281030
}
10291031
};
1030-
void signal_value()
1032+
1033+
bool signal_value(system::error_code&)
10311034
{
10321035
BOOST_ASSERT( inner_active_ >= 0 );
10331036
bool required_member = mp11::mp_with_index< mp11::mp_size<Dm> >(
@@ -1038,14 +1041,14 @@ class converting_handler<described_class_conversion_tag, V, P>
10381041

10391042
key_ = {};
10401043
inner_active_ = -1;
1044+
return true;
10411045
}
10421046

1043-
bool signal_end(system::error_code&)
1047+
bool signal_end(system::error_code& ec)
10441048
{
10451049
key_ = {};
10461050
inner_active_ = -1;
1047-
parent_->signal_value();
1048-
return true;
1051+
return parent_->signal_value(ec);
10491052
}
10501053

10511054
#define BOOST_JSON_INVOKE_INNER(fn) \
@@ -1082,8 +1085,7 @@ class converting_handler<described_class_conversion_tag, V, P>
10821085
return false;
10831086
}
10841087

1085-
parent_->signal_value();
1086-
return true;
1088+
return parent_->signal_value(ec);
10871089
}
10881090

10891091
BOOST_JSON_INVOKE_INNER( on_object_end(ec) );
@@ -1356,12 +1358,12 @@ class converting_handler<variant_conversion_tag, T, P>
13561358
, parent_( p )
13571359
{}
13581360

1359-
void signal_value()
1361+
bool signal_value(system::error_code& ec)
13601362
{
13611363
inner_.template emplace<0>();
13621364
inner_active_ = -1;
13631365
events_.clear();
1364-
parent_->signal_value();
1366+
return parent_->signal_value(ec);
13651367
}
13661368

13671369
bool signal_end(system::error_code& ec)
@@ -1552,12 +1554,12 @@ class converting_handler<optional_conversion_tag, V, P>
15521554
: value_(v), parent_(p), inner_(&inner_value_, this)
15531555
{}
15541556

1555-
void signal_value()
1557+
bool signal_value(system::error_code& ec)
15561558
{
15571559
*value_ = std::move(inner_value_);
15581560

15591561
inner_active_ = false;
1560-
parent_->signal_value();
1562+
return parent_->signal_value(ec);
15611563
}
15621564

15631565
bool signal_end(system::error_code& ec)
@@ -1638,14 +1640,12 @@ class converting_handler<optional_conversion_tag, V, P>
16381640
BOOST_JSON_INVOKE_INNER( on_bool(ec, v) );
16391641
}
16401642

1641-
bool on_null( system::error_code& ec )
1643+
bool on_null(system::error_code& ec)
16421644
{
16431645
if( !inner_active_ )
16441646
{
16451647
*value_ = {};
1646-
1647-
this->parent_->signal_value();
1648-
return true;
1648+
return this->parent_->signal_value(ec);
16491649
}
16501650
else
16511651
{
@@ -1683,7 +1683,7 @@ class converting_handler<path_conversion_tag, V, P>
16831683
return true;
16841684
}
16851685

1686-
bool on_string( system::error_code&, string_view sv )
1686+
bool on_string(system::error_code& ec, string_view sv)
16871687
{
16881688
if( !cleared_ )
16891689
value_->clear();
@@ -1692,8 +1692,7 @@ class converting_handler<path_conversion_tag, V, P>
16921692

16931693
value_->concat( sv.begin(), sv.end() );
16941694

1695-
this->parent_->signal_value();
1696-
return true;
1695+
return this->parent_->signal_value(ec);
16971696
}
16981697
};
16991698

@@ -1726,8 +1725,9 @@ class into_handler
17261725
{
17271726
}
17281727

1729-
void signal_value()
1728+
bool signal_value(system::error_code&)
17301729
{
1730+
return true;
17311731
}
17321732

17331733
bool signal_end(system::error_code&)

0 commit comments

Comments
 (0)