ext/oj/load.c in oj-1.4.0 vs ext/oj/load.c in oj-1.4.1

- old
+ new

@@ -26,14 +26,16 @@ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * 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 +#if SAFE_CACHE #include <pthread.h> #endif -#include <sys/resource.h> +#if !IS_WINDOWS +#include <sys/resource.h> // for getrlimit() on linux +#endif #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> @@ -160,11 +162,11 @@ classname2class(const char *name, ParseInfo pi) { VALUE clas; VALUE *slot; int auto_define = (Yes == pi->options->auto_define); -#ifdef SAFE_CACHE +#if SAFE_CACHE pthread_mutex_lock(&oj_cache_mutex); #endif if (Qundef == (clas = oj_cache_get(oj_class_cache, name, &slot))) { char class_name[1024]; char *s; @@ -189,11 +191,11 @@ *s = '\0'; if (Qundef != (clas = resolve_classname(clas, class_name, auto_define))) { *slot = clas; } } -#ifdef SAFE_CACHE +#if SAFE_CACHE pthread_mutex_unlock(&oj_cache_mutex); #endif return clas; } @@ -319,11 +321,15 @@ static VALUE read_next(ParseInfo pi, int hint) { VALUE obj; +#if IS_WINDOWS + if ((uint64_t)(uint32_t)&obj < pi->stack_min) { +#else if ((uint64_t)&obj < pi->stack_min) { +#endif rb_raise(rb_eSysStackError, "JSON is too deeply nested"); } next_non_white(pi); // skip white space switch (*pi->s) { case '{': @@ -496,11 +502,11 @@ } } else if (T_OBJECT == obj_type) { VALUE *slot; ID var_id; -#ifdef SAFE_CACHE +#if SAFE_CACHE pthread_mutex_lock(&oj_cache_mutex); #endif if (Qundef == (var_id = oj_cache_get(oj_attr_cache, ks, &slot))) { char attr[1024]; @@ -512,11 +518,11 @@ } attr[sizeof(attr) - 1] = '\0'; var_id = rb_intern(attr); *slot = var_id; } -#ifdef SAFE_CACHE +#if SAFE_CACHE pthread_mutex_unlock(&oj_cache_mutex); #endif #if HAS_EXCEPTION_MAGIC if ('~' == *ks && Qtrue == rb_obj_is_kind_of(obj, rb_eException)) { if (0 == strcmp("~mesg", ks)) { @@ -1001,11 +1007,10 @@ 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 */ @@ -1014,14 +1019,22 @@ 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 +#if IS_WINDOWS + pi.stack_min = (uint64_t)(uint32_t)&obj - (512 * 1024); // assume a 1M stack and give half to ruby +#else + { + struct rlimit lim; + + if (0 == getrlimit(RLIMIT_STACK, &lim)) { + pi.stack_min = (uint64_t)&obj - (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 + } } +#endif obj = read_next(&pi, 0); if (Yes == options->circular) { circ_array_free(pi.circ_array); } if (Qundef == obj) {