Skip to content

Commit a1d6c9e

Browse files
committed
Fixed iteration bug over null values.
1 parent 2814f6e commit a1d6c9e

3 files changed

Lines changed: 46 additions & 29 deletions

File tree

include/json/value.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,8 @@ class DefaultValueArrayAllocator : public ValueArrayAllocator
917917
private:
918918
#ifndef JSON_VALUE_USE_INTERNAL_MAP
919919
Value::ObjectValues::iterator current_;
920+
// Indicates that iterator is for a null value.
921+
bool isNull_;
920922
#else
921923
union
922924
{

src/lib_json/json_valueiterator.inl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
ValueIteratorBase::ValueIteratorBase()
1414
#ifndef JSON_VALUE_USE_INTERNAL_MAP
1515
: current_()
16+
, isNull_( true )
1617
#else
1718
# error fix me // Need to handle uninitialized iterator comparison for experimental maps
1819
#endif
@@ -23,6 +24,7 @@ ValueIteratorBase::ValueIteratorBase()
2324
#ifndef JSON_VALUE_USE_INTERNAL_MAP
2425
ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator &current )
2526
: current_( current )
27+
, isNull_( false )
2628
{
2729
}
2830
#else
@@ -86,6 +88,15 @@ ValueIteratorBase::computeDistance( const SelfType &other ) const
8688
# ifdef JSON_USE_CPPTL_SMALLMAP
8789
return current_ - other.current_;
8890
# else
91+
// Iterator for null value are initialized using the default
92+
// constructor, which initialize current_ to the default
93+
// std::map::iterator. As begin() and end() are two instance
94+
// of the default std::map::iterator, they can not be compared.
95+
// To allow this, we handle this comparison specifically.
96+
if ( isNull_ && other.isNull_ )
97+
{
98+
return 0;
99+
}
89100
return difference_type( std::distance( current_, other.current_ ) );
90101
# endif
91102
#else
@@ -100,6 +111,10 @@ bool
100111
ValueIteratorBase::isEqual( const SelfType &other ) const
101112
{
102113
#ifndef JSON_VALUE_USE_INTERNAL_MAP
114+
if ( isNull_ )
115+
{
116+
return other.isNull_;
117+
}
103118
return current_ == other.current_;
104119
#else
105120
if ( isArray_ )

src/test_lib_json/jsontest.cpp

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -505,35 +505,35 @@ Runner::runCommandLine( int argc, const char *argv[] ) const
505505

506506
#if defined(_MSC_VER)
507507
// Hook MSVCRT assertions to prevent dialog from appearing
508-
static int
509-
msvcrtSilentReportHook( int reportType, char *message, int *returnValue )
510-
{
511-
// The default CRT handling of error and assertion is to display
512-
// an error dialog to the user.
513-
// Instead, when an error or an assertion occurs, we force the
514-
// application to terminate using abort() after display
515-
// the message on stderr.
516-
if ( reportType == _CRT_ERROR ||
517-
reportType == _CRT_ASSERT )
518-
{
519-
// calling abort() cause the ReportHook to be called
520-
// The following is used to detect this case and let's the
521-
// error handler fallback on its default behaviour (
522-
// display a warning message)
523-
static volatile bool isAborting = false;
524-
if ( isAborting )
525-
{
526-
return TRUE;
527-
}
528-
isAborting = true;
529-
530-
fprintf( stderr, "CRT Error/Assert:\n%s\n", message );
531-
fflush( stderr );
532-
abort();
533-
}
534-
// Let's other reportType (_CRT_WARNING) be handled as they would by default
535-
return FALSE;
536-
}
508+
static int
509+
msvcrtSilentReportHook( int reportType, char *message, int *returnValue )
510+
{
511+
// The default CRT handling of error and assertion is to display
512+
// an error dialog to the user.
513+
// Instead, when an error or an assertion occurs, we force the
514+
// application to terminate using abort() after display
515+
// the message on stderr.
516+
if ( reportType == _CRT_ERROR ||
517+
reportType == _CRT_ASSERT )
518+
{
519+
// calling abort() cause the ReportHook to be called
520+
// The following is used to detect this case and let's the
521+
// error handler fallback on its default behaviour (
522+
// display a warning message)
523+
static volatile bool isAborting = false;
524+
if ( isAborting )
525+
{
526+
return TRUE;
527+
}
528+
isAborting = true;
529+
530+
fprintf( stderr, "CRT Error/Assert:\n%s\n", message );
531+
fflush( stderr );
532+
abort();
533+
}
534+
// Let's other reportType (_CRT_WARNING) be handled as they would by default
535+
return FALSE;
536+
}
537537
#endif // if defined(_MSC_VER)
538538

539539

0 commit comments

Comments
 (0)