blob: 5aae0af832052b9b1dc62bd7f539a30254abf8dc [file] [log] [blame]
From 16872af88915176f49e389defb167f899e2c230a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= <mail@kkaefer.com>
Date: Thu, 1 Sep 2016 12:10:03 +0200
Subject: [PATCH] Avoid pointer arithmetic on null pointer to remove undefined
behavior
The existing checks triggered undefined behavior when the stack was empty (null pointer). This change avoid this:
* If `stackTop_` and `stackEnd_` are null, it results in a `ptrdiff_t` of `0`
* If `stackTop_` and `stackEnd_` are valid pointers, they produce a `ptrdiff_t` with the remaining size on the stack
---
include/rapidjson/internal/stack.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/rapidjson/internal/stack.h b/include/rapidjson/internal/stack.h
index 89558d0da..45dca6a8b 100644
--- a/include/rapidjson/internal/stack.h
+++ b/include/rapidjson/internal/stack.h
@@ -17,6 +17,7 @@
#include "../allocators.h"
#include "swap.h"
+#include <cstddef>
#if defined(__clang__)
RAPIDJSON_DIAG_PUSH
@@ -114,7 +115,7 @@ class Stack {
template<typename T>
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
// Expand the stack if needed
- if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
+ if (RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) > (stackEnd_ - stackTop_)))
Expand<T>(count);
}
@@ -127,7 +128,7 @@ class Stack {
template<typename T>
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
RAPIDJSON_ASSERT(stackTop_);
- RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
+ RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(sizeof(T) * count) <= (stackEnd_ - stackTop_));
T* ret = reinterpret_cast<T*>(stackTop_);
stackTop_ += sizeof(T) * count;
return ret;