Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assert when outputting JSON using PrettyWriter #672

Closed
sjasonsmith opened this issue Jun 29, 2016 · 1 comment
Closed

Assert when outputting JSON using PrettyWriter #672

sjasonsmith opened this issue Jun 29, 2016 · 1 comment
Labels

Comments

@sjasonsmith
Copy link
Contributor

Using PrettyWriter to output JSON I encounter an assert when PutN is used to indent the output.

I hit the same assert with both Visual C++ 2008 and GCC 4.7.

Assertion failed: stackTop_ + sizeof(T) * count <= stackEnd_, file d:\p4\thirdpartyexports\rapidjson\export\1.0\1.0.3a2\includes\rapidjson\internal/stack.h, line 129

It appears to be an issue in PutN in stream.h. It instantiates templates differently for PutReserve and PutUnsafe. This causes it to use use PutReserve from stream.h (which does nothing), then uses PutUnsafe from stringbuffer.h (which assumes PutReserve allocated space).

Contents of stream.h PutN which causes assertion:

   //! Put N copies of a character to a stream.
   template<typename Stream, typename Ch>
   inline void PutN(Stream& stream, Ch c, size_t n) {
       PutReserve<Stream>(stream, n);
       for (size_t i = 0; i < n; i++)
           PutUnsafe(stream, c);
   }

Removing the template argument from PutReserve seems to resolve the issue, as it now uses PutReserve from stringbuffer.h.

Revised stream.h PutN which does not cause assertion:

   //! Put N copies of a character to a stream.
   template<typename Stream, typename Ch>
   inline void PutN(Stream& stream, Ch c, size_t n) {
       PutReserve(stream, n);
       for (size_t i = 0; i < n; i++)
           PutUnsafe(stream, c);
   }
@sjasonsmith
Copy link
Contributor Author

It looks like I triggered this by using GenericStringBuffer<UTF8<>, MemoryPoolAllocator<> >. When used with a non-default allocator, PutN doesn't match the template specialization in stringbuffer.h, and falls back to the generic implementation in stream.h.

I am verifying my own fix for this, and will put up a pull request to add a failing test and fix the issue.

@miloyip miloyip added the bug label Jun 30, 2016
sjasonsmith added a commit to sjasonsmith/rapidjson that referenced this issue Jun 30, 2016
Fix inconsistent calling of template functions in PutN in stream.h. When
used with a GenericStringBuffer<<UTF8>, MemoryPoolAllocator>, PutN would call
PurReserve from stream.h, and PutUnsafe from stringbuffer.h. This
resulted in bytes being added to the buffer without allocating space.

This was not an issue when used with the default memory allocator,
because in this case the specialized PutN is used from stringbuffer.h.
@miloyip miloyip closed this as completed in 252e812 Jul 1, 2016
miloyip added a commit that referenced this issue Jul 1, 2016
Fix buffer overrun using PutN (closes #672)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants