From c53c6ec39dffa8fcb78303179bd2891459f2250e Mon Sep 17 00:00:00 2001
From: Sven Robertz <sven@cs.lth.se>
Date: Mon, 15 Apr 2013 16:46:50 +0200
Subject: [PATCH] fixed(?) stack leak

---
 lib/c/experimental/labcomm_sig_parser.c | 24 ++++---
 lib/c/experimental/labcomm_sig_parser.h | 83 +++++++++++++------------
 2 files changed, 59 insertions(+), 48 deletions(-)

diff --git a/lib/c/experimental/labcomm_sig_parser.c b/lib/c/experimental/labcomm_sig_parser.c
index b381307..c2c10e6 100644
--- a/lib/c/experimental/labcomm_sig_parser.c
+++ b/lib/c/experimental/labcomm_sig_parser.c
@@ -95,7 +95,9 @@ void dumpPtrStack(buffer *b) {
 void push_val(buffer *b, unsigned int e) {
 	b->val_stack[b->val_top]=e;
 	b->val_top=b->val_top-1;
+#ifdef DEBUG
 	dumpValStack(b);
+#endif
 }
 unsigned int pop_val(buffer *b) {
 	b->val_top=b->val_top+1;
@@ -104,7 +106,9 @@ unsigned int pop_val(buffer *b) {
 void push_ptr(buffer *b, void* e) {
 	b->ptr_stack[b->ptr_top]=e;
 	b->ptr_top=b->ptr_top-1;
+#ifdef DEBUG
 	dumpPtrStack(b);
+#endif
 }
 void* pop_ptr(buffer *b) {
 	b->ptr_top=b->ptr_top+1;
@@ -304,6 +308,7 @@ int accept_packet(buffer *d) {
         unsigned int type = peek_varint(d, &nbytes) ;
 	if(type == TYPE_DECL ) {
 		advancen(d, nbytes);
+		int b = accept_user_id(d);
 		if(accept_user_id(d)) {
 			unsigned int uid = pop_val(d);
 			VERBOSE_PRINTF(", name = ");
@@ -419,6 +424,7 @@ static int accept_string(buffer *d){
 	push_val(d, len);
 	return TRUE;
 }
+/* pushes size and type id */
 static int accept_type(buffer *d){
 	unsigned char nbytes;
         unsigned int type = peek_varint(d, &nbytes) ;
@@ -466,21 +472,24 @@ static int accept_type(buffer *d){
 			break;
 		case ARRAY_DECL :
 			accept_array_decl(d);
-			//push(d, pop(d)) == NOP
+			pop_val(d); // ignore element type
+			// push(d, pop(d) is a NOP --> leave size on stack
 			break;
 		case STRUCT_DECL :
 			accept_struct_decl(d);
-			//push(d, pop(d)) == NOP
+			// push(d, pop(d) is a NOP --> leave size on stack
 			break;
 		default :
 			printf("accept_basic_type default (type==%x) should not happen\n", type);
 			push_val(d, 0);
+			push_val(d, type);
 			return FALSE;
 	}
 	push_val(d, type);
 	return TRUE;
 }
 
+/* pushes size and element type */
 static int accept_array_decl(buffer *d){
         unsigned char nbytes;
         unsigned int tid = peek_varint(d, &nbytes) ;
@@ -515,10 +524,10 @@ static int accept_array_decl(buffer *d){
 #endif
 			push_val(d,  (size*es));
 		} else {
-//HERE BE DRAGONS! shouldn't we push some (non-) size?
+//HERE BE DRAGONS! push a (non-) size for variable size arrays?
+			push_val(d, 0);
 		}
-		//pop(d);
-		push_val(d, tid);
+		push_val(d, et);
 		return TRUE;
 	} else {
 		printf("accept_array_decl: type=%x, should not happen\n",tid);
@@ -554,7 +563,7 @@ static int accept_struct_decl(buffer *d){
 	}
 }
 
-/* pushes name (if enabled) and field size */
+/* pushes field size */
 static int accept_field(buffer *d){
 	VERBOSE_PRINTF("field ");
 	accept_string(d);
@@ -566,7 +575,8 @@ static int accept_field(buffer *d){
 	VERBOSE_PRINTF(" : ");
 	accept_type(d);
 	pop_val(d); // ignore type, for now
-	//push(d, pop(d) == NOP , leave size on the stack
+	// push(pop() is really a NOP , leave size on the stack when debugging done
+	VERBOSE_PRINTF(" : ");
 	VERBOSE_PRINTF("\n");
 }
 static int accept_sample_data(buffer *d){
diff --git a/lib/c/experimental/labcomm_sig_parser.h b/lib/c/experimental/labcomm_sig_parser.h
index 6d4a250..69cb89c 100644
--- a/lib/c/experimental/labcomm_sig_parser.h
+++ b/lib/c/experimental/labcomm_sig_parser.h
@@ -11,11 +11,51 @@
 #include "../labcomm_private.h"
 
 #undef DEBUG 
-#undef DEBUG_STACK
+#define DEBUG_STACK
 
 #undef QUIET 		//just print type and size when skipping data
 #undef VERBOSE 		// print in great detail
 
+
+//XXX experimental settings, should probably be dynamic
+#define MAX_SIGNATURES 10
+#define MAX_NAME_LEN 32 
+#define MAX_SIG_LEN 128
+
+#define STACK_SIZE 16
+
+
+/* internal type: stack for the parser */
+typedef struct {
+	unsigned char* c;
+	size_t size;
+	size_t capacity;
+	unsigned int idx;
+	unsigned int val_top;
+	int * val_stack;
+	unsigned int ptr_top;
+	void** ptr_stack;
+	size_t stacksize;
+	int current_decl_is_varsize;
+} buffer;
+
+int init_buffer(buffer *b, size_t size, size_t stacksize) ;
+int read_file(FILE *f, buffer *b);
+
+int accept_packet(buffer *d);
+
+labcomm_signature_t *get_sig_t(unsigned int uid);
+
+unsigned int get_signature_len(unsigned int uid);
+unsigned char* get_signature_name(unsigned int uid);
+unsigned char* get_signature(unsigned int uid);
+void dump_signature(unsigned int uid);
+
+
+/* parse signature and skip the corresponding bytes in the buffer 
+ */
+int skip_packed_sample_data(buffer *d, labcomm_signature_t *sig);
+
 #ifdef QUIET
 #define INFO_PRINTF(format, args...)  
 #undef VERBOSE
@@ -33,7 +73,7 @@
 
 #undef EXIT_WHEN_RECEIVING_DATA 
 
-#define RETURN_STRINGS  //  not really tested
+#undef RETURN_STRINGS  //  not really tested
 
 #ifndef TRUE
 
@@ -58,43 +98,4 @@ typedef enum{
         TYPE_DOUBLE  = LABCOMM_DOUBLE,
         TYPE_STRING  = LABCOMM_STRING
 } labcomm_type ;
-
-/* internal type: stack for the parser */
-typedef struct {
-	unsigned char* c;
-	size_t size;
-	size_t capacity;
-	unsigned int idx;
-	unsigned int val_top;
-	int * val_stack;
-	unsigned int ptr_top;
-	void** ptr_stack;
-	size_t stacksize;
-	int current_decl_is_varsize;
-} buffer;
-
-int init_buffer(buffer *b, size_t size, size_t stacksize) ;
-int read_file(FILE *f, buffer *b);
-
-int accept_packet(buffer *d);
-
-//XXX experimental
-#define MAX_SIGNATURES 10
-#define MAX_NAME_LEN 32 
-#define MAX_SIG_LEN 128
-
-#define STACK_SIZE 16
-
-labcomm_signature_t *get_sig_t(unsigned int uid);
-
-unsigned int get_signature_len(unsigned int uid);
-unsigned char* get_signature_name(unsigned int uid);
-unsigned char* get_signature(unsigned int uid);
-void dump_signature(unsigned int uid);
-
-
-/* parse signature and skip the corresponding bytes in the buffer 
- */
-int skip_packed_sample_data(buffer *d, labcomm_signature_t *sig);
-
 #endif
-- 
GitLab