ext/oj/load.c in oj-1.3.5 vs ext/oj/load.c in oj-1.3.6

- old
+ new

@@ -27,12 +27,13 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef SAFE_CACHE -#include <pthread.h> // TBD LOCK +#include <pthread.h> #endif +#include <sys/resource.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> @@ -57,10 +58,11 @@ typedef struct _ParseInfo { char *str; /* buffer being read from */ char *s; /* current position in buffer */ CircArray circ_array; Options options; + uint64_t stack_min; } *ParseInfo; static CircArray circ_array_new(void); static void circ_array_free(CircArray ca); static void circ_array_set(CircArray ca, VALUE obj, unsigned long id); @@ -317,10 +319,13 @@ static VALUE read_next(ParseInfo pi, int hint) { VALUE obj; + if ((uint64_t)&obj < pi->stack_min) { + rb_raise(rb_eSysStackError, "JSON is too deeply nested"); + } next_non_white(pi); // skip white space switch (*pi->s) { case '{': obj = read_obj(pi); break; @@ -996,10 +1001,11 @@ VALUE oj_parse(char *json, Options options) { VALUE obj; struct _ParseInfo pi; + struct rlimit lim; if (0 == json) { raise_error("Invalid arg, xml string can not be null", json, 0); } /* initialize parse info */ @@ -1008,9 +1014,14 @@ pi.circ_array = 0; if (Yes == options->circular) { pi.circ_array = circ_array_new(); } pi.options = options; + if (0 == getrlimit(RLIMIT_STACK, &lim)) { + pi.stack_min = (uint64_t)&lim - (lim.rlim_cur / 4 * 3); // let 3/4ths of the stack be used only + } else { + pi.stack_min = 0; // indicates not to check stack limit + } obj = read_next(&pi, 0); if (Yes == options->circular) { circ_array_free(pi.circ_array); } if (Qundef == obj) {