@@ -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