src/server/config/serverconfig.c

changeset 417
90805bb9fbd6
parent 415
d938228c382e
child 418
b7dcc9c4f270
--- a/src/server/config/serverconfig.c	Sun Nov 06 16:59:39 2022 +0100
+++ b/src/server/config/serverconfig.c	Sun Nov 06 17:41:39 2022 +0100
@@ -44,8 +44,18 @@
         return NULL;
     }
     
+    CxMempool *mp = cxBasicMempoolCreate(512);
+    if(!mp) {
+        fclose(in);
+        return NULL;
+    }
+    
     CxBuffer buf;
-    cxBufferInit(&buf, NULL, 16384, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS);
+    if(cxBufferInit(&buf, NULL, 16384, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS)) {
+        fclose(in);
+        cxMempoolDestroy(mp);
+        return NULL;
+    }
     
     //ucx_stream_copy(in, buf, (read_func)fread, (write_func)ucx_buffer_write);
     char readbuf[2048];
@@ -55,7 +65,11 @@
     }
     fclose(in);
     
-    ServerConfig *scfg = serverconfig_parse(cx_strn(buf.space, buf.size));
+    ConfigParser2 parser;
+    ZERO(&parser, sizeof(ConfigParser2));
+    parser.mp = mp;
+    parser.allow_hierarchy = true;
+    ServerConfig *scfg = serverconfig_parse(&parser, cx_strn(buf.space, buf.size));
     
     cxBufferDestroy(&buf);
     return scfg;
@@ -190,9 +204,8 @@
     return 0;
 }
 
-ServerConfig* serverconfig_parse(cxstring content) {
-    CxMempool *mp = cxBasicMempoolCreate(512);
-    if(!mp) return NULL;
+ServerConfig* serverconfig_parse(ConfigParser2 *parser, cxstring content) {
+    CxMempool *mp = parser->mp;
     CxAllocator *a = (CxAllocator*)mp->allocator;
     
     ServerConfig *config = cxMalloc(a, sizeof(ServerConfig));
@@ -248,6 +261,12 @@
                     // this is a newline after a object is closed with '}'
                     // the line containing "}\n" should be added to the object
                     parent->text_end = line_cp;
+                    // validate
+                    if(parser->validateObjEnd && parser->validateObjEnd(parser, parent)) {
+                        // validation failed
+                        err = 1;
+                        break;
+                    }
                     // done with this object, remove it from the stack
                     ConfigNodeStack *remove_item = node_stack;
                     node_stack = node_stack->next;
@@ -261,6 +280,10 @@
                     obj->text_begin = new_textbegin;
                 } else {
                     // normal line containing a directive, space or comment
+                    if(parser->validateDirective && parser->validateDirective(parser, current)) {
+                        err = 1;
+                        break;
+                    }
                     // add it to parent node
                     current->text_begin = line_cp;
                     CFG_NODE_ADD(&parent->children_begin, &parent->children_end, current);
@@ -270,7 +293,14 @@
                 // the type is set to CONFIG_NODE_OBECT if it was followed by
                 // a '{' character
                 if(obj && obj->type == CONFIG_NODE_OBJECT) {
-                    // new object started, add it to the stack
+                    // new object started
+                    if(parser->validateObjBegin && parser->validateObjBegin(parser, obj)) {
+                        // validation callback failed
+                        err = 1;
+                        break;
+                    }
+                    
+                    // add it to the stack
                     nodestack_prepend(a, &node_stack, obj);
                     obj = NULL;
                 }
@@ -286,6 +316,13 @@
                 // either a directive/obj name, parameter or { }
                 
                 if(!cx_strcmp(token.content, cx_str("{"))) {
+                    // check if the parser allows an object hierarchy
+                    if(!parser->allow_hierarchy) {
+                        parser->error = CONFIG_PARSER_SYNTAX_ERROR;
+                        err = 1;
+                        break;
+                    }
+                    
                     // obj is pointing to the previous node that started
                     // a directive
                     if(!obj) {
@@ -297,6 +334,13 @@
                         current->type = CONFIG_NODE_OPEN_OBJECT;
                     }
                 } else if(!cx_strcmp(token.content, cx_str("}"))) {
+                    // check if the parser allows an object hierarchy
+                    if(!parser->allow_hierarchy) {
+                        parser->error = CONFIG_PARSER_SYNTAX_ERROR;
+                        err = 1;
+                        break;
+                    }
+                    
                     obj_closed = 1; // force newline before next directive
                     obj = NULL;
                     current->type = CONFIG_NODE_CLOSE_OBJECT;

mercurial