Browse code

core: expr string length fixup fix

- moved the string length fixup before the rve/rval optimisations:
the string length fixup was executed after the rve/rval
optimisations and would try to re-calculate the length of the
string (which was already filled in by the optimizer). However
the rval optimizer did not 0-terminate strings => this second
re-calculation was wrong.

- the rve/rval optimiser 0 terminates strings (although not
strictly needed it's better for debugging and would avoid
problems similar to the above one).

- don't try to fix a string in the left side of an expression,
there can be no strings there (and by chance
METHOD_O==STRING_ST).

Reported-by: Juha Heinanen jh at tutpro com

Andrei Pelinescu-Onciul authored on 18/07/2009 08:05:16
Showing 1 changed files
... ...
@@ -435,6 +435,7 @@ static int exp_optimize_right(struct expr* exp)
435 435
 					if (exp->r.str.s){
436 436
 						exp->r.str.len=rval->v.s.len;
437 437
 						memcpy(exp->r.str.s, rval->v.s.s, rval->v.s.len);
438
+						exp->r.str.s[exp->r.str.len]=0;
438 439
 						exp->r_type=STRING_ST;
439 440
 						rval_destroy(rval);
440 441
 						pkg_free(rve);
... ...
@@ -503,6 +504,7 @@ int fix_expr(struct expr* exp)
503 503
 {
504 504
 	regex_t* re;
505 505
 	int ret;
506
+	int len;
506 507
 
507 508
 	ret=E_BUG;
508 509
 	if (exp==0){
... ...
@@ -525,8 +527,17 @@ int fix_expr(struct expr* exp)
525 525
 								exp->op);
526 526
 		}
527 527
 	}else if (exp->type==ELEM_T){
528
-			/* first fix & optimize rve/rvals (they might be optimized
529
-			   to non-rvals, e.g. string, avp a.s.o) */
528
+			/* first calculate lengths of strings  (only right side, since 
529
+			  left side can never be a string) */
530
+			if (exp->r_type==STRING_ST) {
531
+				if (exp->r.string) len = strlen(exp->r.string);
532
+				else len = 0;
533
+				exp->r.str.s = exp->r.string;
534
+				exp->r.str.len = len;
535
+			}
536
+			/* then fix & optimize rve/rvals (they might be optimized
537
+			   to non-rvals, e.g. string, avp a.s.o and needs to be done
538
+			   before MATCH_OP and other fixups) */
530 539
 			if (exp->l_type==RVEXP_O){
531 540
 				if ((ret=fix_rval_expr(&exp->l.param))<0){
532 541
 					ERR("Unable to fix left rval expression\n");
... ...
@@ -544,21 +555,6 @@ int fix_expr(struct expr* exp)
544 544
 					exp_optimize_right(exp);
545 545
 			}
546 546
 			
547
-			/* Calculate lengths of strings */
548
-			if (exp->l_type==STRING_ST) {
549
-				int len;
550
-				if (exp->l.string) len = strlen(exp->l.string);
551
-				else len = 0;
552
-				exp->l.str.s = exp->l.string;
553
-				exp->l.str.len = len;
554
-			}
555
-			if (exp->r_type==STRING_ST) {
556
-				int len;
557
-				if (exp->r.string) len = strlen(exp->r.string);
558
-				else len = 0;
559
-				exp->r.str.s = exp->r.string;
560
-				exp->r.str.len = len;
561
-			}
562 547
 			
563 548
 			if (exp->op==MATCH_OP){
564 549
 				     /* right side either has to be string, in which case