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