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) {