Commit f5bb3117 f5bb311708a1457865ad396601db11b9e9367cb5 by Sergey Poznyakoff

Fixed handling of escape sequences in

strings. Thanks Fabrice Bauzac <fabrice.bauzac@wanadoo.fr>
for reporting.
1 parent f74c4d96
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
26 #include <sys/file.h> 26 #include <sys/file.h>
27 #include <sys/stat.h> 27 #include <sys/stat.h>
28 #include <errno.h> 28 #include <errno.h>
29 #include <string.h> 29 #include <string.h>
30 #include <mailutils/argcv.h>
30 #include <sieve.h> 31 #include <sieve.h>
31 #include <sieve-gram.h> 32 #include <sieve-gram.h>
32 33
...@@ -40,6 +41,9 @@ static int strip_tabs; ...@@ -40,6 +41,9 @@ static int strip_tabs;
40 41
41 static int number __P ((void)); 42 static int number __P ((void));
42 static int string __P ((void)); 43 static int string __P ((void));
44 static void line_begin __P ((void));
45 static void line_add __P((char *text, size_t len));
46 static void line_finish __P ((void));
43 static void multiline_begin __P ((void)); 47 static void multiline_begin __P ((void));
44 static void multiline_add __P ((char *)); 48 static void multiline_add __P ((char *));
45 static void multiline_finish __P ((void)); 49 static void multiline_finish __P ((void));
...@@ -47,7 +51,7 @@ static char *multiline_strip_tabs __P((char *text)); ...@@ -47,7 +51,7 @@ static char *multiline_strip_tabs __P((char *text));
47 static void ident __P((const char *text)); 51 static void ident __P((const char *text));
48 static void sieve_include __P((void)); 52 static void sieve_include __P((void));
49 static void sieve_searchpath __P((void)); 53 static void sieve_searchpath __P((void));
50 static char *str_escape __P((void)); 54 static char *str_unescape __P((char *text, size_t len));
51 static int isemptystr __P((char *text)); 55 static int isemptystr __P((char *text));
52 56
53 #ifdef FLEX_SCANNER 57 #ifdef FLEX_SCANNER
...@@ -352,12 +356,13 @@ not return NOT; ...@@ -352,12 +356,13 @@ not return NOT;
352 /* Quoted strings */ 356 /* Quoted strings */
353 \"[^\\"\n]*\" { return string (); } 357 \"[^\\"\n]*\" { return string (); }
354 \"[^\\"\n]*\\. { BEGIN(STR); 358 \"[^\\"\n]*\\. { BEGIN(STR);
355 multiline_begin (); 359 line_begin ();
356 multiline_add (str_escape ()); } 360 line_add (str_unescape (yytext + 1, yyleng - 1), 0); }
357 <STR>[^\\"\n]*\\. { multiline_add (str_escape ()); } 361 <STR>[^\\"\n]*\\. { line_add (str_unescape (yytext, yyleng), 0); }
358 <STR>[^\\"\n]*\" { BEGIN(INITIAL); 362 <STR>[^\\"\n]*\" { BEGIN(INITIAL);
359 multiline_add (NULL); 363 if (yyleng > 1)
360 multiline_finish (); 364 line_add (yytext, yyleng - 1);
365 line_finish ();
361 return STRING; } 366 return STRING; }
362 /* Multiline strings */ 367 /* Multiline strings */
363 text:-?[ \t]*#.*\n { BEGIN(ML); multiline_begin (); sieve_line_num++; } 368 text:-?[ \t]*#.*\n { BEGIN(ML); multiline_begin (); sieve_line_num++; }
...@@ -576,24 +581,50 @@ multiline_strip_tabs (char *text) ...@@ -576,24 +581,50 @@ multiline_strip_tabs (char *text)
576 } 581 }
577 582
578 void 583 void
579 multiline_add (char *s) 584 line_add (char *text, size_t len)
580 { 585 {
586 char *s;
587
588 if (len == 0)
589 len = strlen (text);
590 s = malloc (len + 1);
581 if (!s) 591 if (!s)
582 { 592 {
583 s = strdup (multiline_strip_tabs (yytext)); 593 yyerror (_("not enough memory"));
584 if (!s) 594 exit (1);
585 {
586 yyerror (_("not enough memory"));
587 exit (1);
588 }
589 } 595 }
596 memcpy (s, text, len);
597 s[len] = 0;
590 list_append (string_list, s); 598 list_append (string_list, s);
591 } 599 }
592 600
593 void 601 void
594 multiline_begin () 602 multiline_add (char *s)
603 {
604 if (!s)
605 s = multiline_strip_tabs (yytext);
606 line_add (s, 0);
607 }
608
609 void
610 line_begin ()
595 { 611 {
596 int status; 612 int status;
613
614 if (string_list)
615 sieve_slist_destroy (&string_list);
616 status = list_create (&string_list);
617 if (status)
618 {
619 sieve_compile_error (sieve_filename, sieve_line_num,
620 "list_create: %s", mu_strerror (status));
621 exit (1);
622 }
623 }
624
625 void
626 multiline_begin ()
627 {
597 char *p = yytext + 5; /* past the text: keyword */ 628 char *p = yytext + 5; /* past the text: keyword */
598 629
599 if (*p == '-') 630 if (*p == '-')
...@@ -627,21 +658,12 @@ multiline_begin () ...@@ -627,21 +658,12 @@ multiline_begin ()
627 exit (1); 658 exit (1);
628 } 659 }
629 } 660 }
630
631 if (string_list)
632 sieve_slist_destroy (&string_list);
633 status = list_create (&string_list);
634 if (status)
635 {
636 sieve_compile_error (sieve_filename, sieve_line_num,
637 "list_create: %s", mu_strerror (status));
638 exit (1);
639 }
640 661
662 line_begin ();
641 } 663 }
642 664
643 void 665 void
644 multiline_finish () 666 line_finish ()
645 { 667 {
646 iterator_t itr; 668 iterator_t itr;
647 int length = 0; 669 int length = 0;
...@@ -675,6 +697,12 @@ multiline_finish () ...@@ -675,6 +697,12 @@ multiline_finish ()
675 } 697 }
676 698
677 void 699 void
700 multiline_finish ()
701 {
702 line_finish ();
703 }
704
705 void
678 ident (const char *text) 706 ident (const char *text)
679 { 707 {
680 yylval.string = strdup (text); 708 yylval.string = strdup (text);
...@@ -687,11 +715,11 @@ ident (const char *text) ...@@ -687,11 +715,11 @@ ident (const char *text)
687 715
688 /* Escapes the last character from yytext */ 716 /* Escapes the last character from yytext */
689 char * 717 char *
690 str_escape () 718 str_unescape (char *text, size_t len)
691 { 719 {
692 char *str = sieve_alloc (yyleng - 1); 720 char *str = sieve_alloc (len);
693 memcpy (str, yytext, yyleng - 2); 721 memcpy (str, text, len - 2);
694 str[yyleng - 2] = yytext[yyleng - 1]; 722 str[len - 2] = argcv_unescape_char (text[len - 1]);
695 str[yyleng - 1] = 0; 723 str[len - 1] = 0;
696 return str; 724 return str;
697 } 725 }
......