comparison toys/posix/sed.c @ 1646:8e506e89bb8c draft

Fix sed backslash parsing in square bracket pattern sections.
author Rob Landley <rob@landley.net>
date Sun, 04 Jan 2015 03:50:52 -0600
parents 53bfe8ac762b
children 58cb2d7bd461
comparison
equal deleted inserted replaced
1645:2ffee259f519 1646:8e506e89bb8c
673 673
674 if (i) { 674 if (i) {
675 struct step *primal; 675 struct step *primal;
676 676
677 if (!fd && *name=='-') { 677 if (!fd && *name=='-') {
678 error_msg("no -i on stdin"); 678 error_msg("-i on stdin");
679 return; 679 return;
680 } 680 }
681 TT.fdout = copy_tempfile(fd, name, &tmp); 681 TT.fdout = copy_tempfile(fd, name, &tmp);
682 TT.count = 0; 682 TT.count = 0;
683 for (primal = (void *)TT.pattern; primal; primal = primal->next) 683 for (primal = (void *)TT.pattern; primal; primal = primal->next)
697 // returns processed copy of string (0 if error), *pstr advances to next 697 // returns processed copy of string (0 if error), *pstr advances to next
698 // unused char. if delim (or *delim) is 0 uses/saves starting char as delimiter 698 // unused char. if delim (or *delim) is 0 uses/saves starting char as delimiter
699 // if regxex, ignore delimiter in [ranges] 699 // if regxex, ignore delimiter in [ranges]
700 static char *unescape_delimited_string(char **pstr, char *delim, int regex) 700 static char *unescape_delimited_string(char **pstr, char *delim, int regex)
701 { 701 {
702 char *to, *from, d; 702 char *to, *from, mode = 0, d;
703 703
704 to = from = *pstr; 704 to = from = *pstr;
705 if (!delim || !*delim) { 705 if (!delim || !*delim) {
706 if (!(d = *(from++))) return 0; 706 if (!(d = *(from++))) return 0;
707 if (d == '\\') d = *(from++); 707 if (d == '\\') d = *(from++);
708 if (!d || d == '\\') return 0; 708 if (!d || d == '\\') return 0;
709 if (delim) *delim = d; 709 if (delim) *delim = d;
710 } else d = *delim; 710 } else d = *delim;
711 to = delim = xmalloc(strlen(*pstr)+1); 711 to = delim = xmalloc(strlen(*pstr)+1);
712 712
713 while (*from != d) { 713 while (mode || *from != d) {
714 if (!*from) return 0; 714 if (!*from) return 0;
715 715
716 // delimiter in regex character range doesn't count 716 // delimiter in regex character range doesn't count
717 if (*from == '[') { 717 if (*from == '[') {
718 int len = 1; 718 mode = '[';
719 719 if (from[1] == ']') *(to++) = *(from++);
720 if (from[len] == ']') len++; 720 } else if (mode && *from == ']') mode = 0;
721 while (from[len] != ']') if (!from[len++]) return 0; 721 else if (*from == '\\') {
722 memmove(to, from, ++len);
723 to += len;
724 from += len;
725 continue;
726 }
727 if (*from == '\\') {
728 if (!from[1]) return 0; 722 if (!from[1]) return 0;
729 723
730 // Check escaped end delimiter before printf style escapes. 724 // Check escaped end delimiter before printf style escapes.
731 if (from[1] == d) from++; 725 if (from[1] == d) from++;
732 else if (from[1]=='\\') *(to++) = *(from++); 726 else if (from[1]=='\\') *(to++) = *(from++);
735 729
736 if (c) { 730 if (c) {
737 *(to++) = c; 731 *(to++) = c;
738 from+=2; 732 from+=2;
739 continue; 733 continue;
740 } 734 } else if (from[1]) *(to++) = *(from++);
741 } 735 }
742 } 736 }
743 *(to++) = *(from++); 737 *(to++) = *(from++);
744 } 738 }
745 *to = 0; 739 *to = 0;