@@ -36,6 +36,12 @@ typedef unsigned char _Bool;
3636# define MAYBE_UNUSED (x ) x
3737#endif
3838
39+ #ifdef RUBY_DEBUG
40+ #ifndef JSON_DEBUG
41+ #define JSON_DEBUG RUBY_DEBUG
42+ #endif
43+ #endif
44+
3945enum fbuffer_type {
4046 FBUFFER_HEAP_ALLOCATED = 0 ,
4147 FBUFFER_STACK_ALLOCATED = 1 ,
@@ -46,6 +52,9 @@ typedef struct FBufferStruct {
4652 unsigned long initial_length;
4753 unsigned long len;
4854 unsigned long capa;
55+ #ifdef JSON_DEBUG
56+ unsigned long requested;
57+ #endif
4958 char *ptr;
5059 VALUE io;
5160} FBuffer;
@@ -74,6 +83,20 @@ static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *
7483 fb->ptr = stack_buffer;
7584 fb->capa = stack_buffer_size;
7685 }
86+ #ifdef JSON_DEBUG
87+ fb->requested = 0 ;
88+ #endif
89+ }
90+
91+ static inline void fbuffer_consumed (FBuffer *fb, unsigned long consumed)
92+ {
93+ #ifdef JSON_DEBUG
94+ if (consumed > fb->requested ) {
95+ rb_bug (" fbuffer: Out of bound write" );
96+ }
97+ fb->requested = 0 ;
98+ #endif
99+ fb->len += consumed;
77100}
78101
79102static void fbuffer_free (FBuffer *fb)
@@ -137,6 +160,10 @@ static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
137160
138161static inline void fbuffer_inc_capa (FBuffer *fb, unsigned long requested)
139162{
163+ #ifdef JSON_DEBUG
164+ fb->requested = requested;
165+ #endif
166+
140167 if (RB_UNLIKELY (requested > fb->capa - fb->len )) {
141168 fbuffer_do_inc_capa (fb, requested);
142169 }
@@ -147,15 +174,22 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
147174 if (len > 0 ) {
148175 fbuffer_inc_capa (fb, len);
149176 MEMCPY (fb->ptr + fb->len , newstr, char , len);
150- fb-> len += len;
177+ fbuffer_consumed (fb, len) ;
151178 }
152179}
153180
154181/* Appends a character into a buffer. The buffer needs to have sufficient capacity, via fbuffer_inc_capa(...). */
155182static inline void fbuffer_append_reserved_char (FBuffer *fb, char chr)
156183{
184+ #ifdef JSON_DEBUG
185+ if (fb->requested < 1 ) {
186+ rb_bug (" fbuffer: unreserved write" );
187+ }
188+ fb->requested --;
189+ #endif
190+
157191 fb->ptr [fb->len ] = chr;
158- fb->len += 1 ;
192+ fb->len ++ ;
159193}
160194
161195static void fbuffer_append_str (FBuffer *fb, VALUE str)
@@ -172,7 +206,7 @@ static inline void fbuffer_append_char(FBuffer *fb, char newchr)
172206{
173207 fbuffer_inc_capa (fb, 1 );
174208 *(fb->ptr + fb->len ) = newchr;
175- fb-> len ++ ;
209+ fbuffer_consumed (fb, 1 ) ;
176210}
177211
178212static inline char *fbuffer_cursor (FBuffer *fb)
@@ -182,7 +216,7 @@ static inline char *fbuffer_cursor(FBuffer *fb)
182216
183217static inline void fbuffer_advance_to (FBuffer *fb, char *end)
184218{
185- fb-> len = end - fb->ptr ;
219+ fbuffer_consumed (fb, ( end - fb->ptr ) - fb-> len ) ;
186220}
187221
188222/*
0 commit comments