From 38b2c8f012eb29929531c5ad65c2cb4520a00679 Mon Sep 17 00:00:00 2001
From: Yorhel <git@yorhel.nl>
Date: Wed, 5 Sep 2012 17:46:44 +0200
Subject: [PATCH] dir_import.c: Various fixes

- errors in item() didn't propagate properly
- empty [] and {} values weren't allowed
- fractional numbers weren't allowed
- parsing of escaped characters didn't ensure that enough data was in
  the buffer
- E() didn't propagate errors properly in all cases

I'll do some more testing later on, but the current code seems to be
working quite well already.
---
 src/dir_import.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/dir_import.c b/src/dir_import.c
index 7712ce2..334ec28 100644
--- a/src/dir_import.c
+++ b/src/dir_import.c
@@ -125,8 +125,9 @@ static int fill(int n) {
 
 /* Two macros that break function calling behaviour, but are damn convenient */
 #define E(_x, _m) do {\
-    if((_x) && !dir_fatalerr) {\
-      dir_seterr("Line %d byte %d: %s", ctx->line, ctx->byte, _m);\
+    if(_x) {\
+      if(!dir_fatalerr)\
+        dir_seterr("Line %d byte %d: %s", ctx->line, ctx->byte, _m);\
       return 1;\
     }\
   } while(0)
@@ -186,6 +187,8 @@ static int cons() {
 static int rstring_esc(char **dest, int *destlen) {
   unsigned int n;
 
+  C(rfill1);
+
 #define ap(c) if(*destlen > 1) { *((*dest)++) = c; (*destlen)--; }
   switch(*ctx->buf) {
   case '"':  ap('"');  con(1); break;
@@ -290,7 +293,7 @@ static int rnum() {
   C(rfill1);
   while(1) {
     C(!*ctx->buf && fill(1));
-    if(*ctx->buf == 'e' || *ctx->buf == 'E' || *ctx->buf == '-' || *ctx->buf == '+' || (*ctx->buf >= '0' && *ctx->buf <= '9')) {
+    if(*ctx->buf == 'e' || *ctx->buf == 'E' || *ctx->buf == '-' || *ctx->buf == '+' || *ctx->buf == '.' || (*ctx->buf >= '0' && *ctx->buf <= '9')) {
       haschar = 1;
       con(1);
     } else {
@@ -341,6 +344,9 @@ static int rval() {
   case '{': /* object */
     con(1);
     while(1) {
+      C(cons());
+      if(*ctx->buf == '}')
+        break;
       C(rkey(NULL, 0) || rval() || cons());
       if(*ctx->buf == '}')
         break;
@@ -352,6 +358,9 @@ static int rval() {
   case '[': /* array */
     con(1);
     while(1) {
+      C(cons());
+      if(*ctx->buf == ']')
+        break;
       C(cons() || rval() || cons());
       if(*ctx->buf == ']')
         break;
@@ -409,8 +418,7 @@ static int itemdir(uint64_t dev) {
       break;
     E(*ctx->buf != ',', "Expected ',' or ']'");
     con(1);
-    C(cons());
-    item(dev);
+    C(cons() || item(dev));
   }
   con(1);
   C(cons());
-- 
GitLab