Browse Source

[fix] segfault for coted block and openned coted block:
- loop to check every cotes types.
- detect opening and closing cotes for a block.
- else: non-coted block.
- [norm] use an init f() to init variables.
- update corresponding comments and add unit test.

Moul 4 years ago
parent
commit
2e4187f229
4 changed files with 33 additions and 15 deletions
  1. 28 12
      src/detect_cotes.c
  2. 2 2
      src/main.c
  3. 2 1
      src/sh.h
  4. 1 0
      tests.sh

+ 28 - 12
src/detect_cotes.c

@@ -1,30 +1,46 @@
 #include "sh.h"
 
+void	init_detect_blocks(t_e *e, char *line)
+{
+	int		pos;
+	int		b_pos;
+
+	pos = 0;
+	b_pos = 0;
+	e->b = (t_block**)malloc(sizeof(t_block*) * 50);
+	detect_blocks(e, line, pos, b_pos);
+}
+
 /*
 ** arbitrary value to 50 blocks max
 ** While not scanned all string
-** If found cote (prevent segfault if only one cote) and non-coted block before:
-** Else: no cote found: non coted block
+** If found opening and close cotes and non-coted block before:
+** - retrieve coted block
+** Else: no cote found: retrieve non coted block
 ** Increment block position
 */
 
-void	detect_blocks(t_e *e, char *line)
+void	detect_blocks(t_e *e, char *line, int pos, int b_pos)
 {
-	int		pos;
-	int		b_pos;
+	int		i;
+	int		coted;
 
-	pos = 0;
-	b_pos = 0;
-	e->b = (t_block**)malloc(sizeof(t_block*) * 50);
 	while (line[pos] != '\0')
 	{
 		while (line[pos] != '\0' && (line[pos] == ' ' || line[pos] == '\t'))
 			pos++;
 		e->b[b_pos] = (t_block*)malloc(sizeof(t_block));
-		if ((line[pos] == '\'' || line[pos] == '\"' || line[pos] == '`') &&\
-		line[pos + 1] != '\0' && (b_pos != 0 ? e->b[b_pos - 1]->type == 0 : 1))
-			pos = coted_block(e, line, pos, e->b[b_pos++]);
-		else
+		i = -1;
+		coted = 0;
+		while (++i < 3)
+			if (line[pos] == e->par_open[i] && \
+				ft_strchr(&line[pos + 1], e->par_open[i]) != NULL && \
+				(b_pos > 0 ? e->b[b_pos - 1]->type == 0 : 1))
+			{
+				pos = coted_block(e, line, pos, e->b[b_pos++]);
+				coted = 1;
+			}
+		if (coted == 0)
 			pos = non_coted_block(e, line, pos, e->b[b_pos++]);
 	}
 	e->b[b_pos] = NULL;

+ 2 - 2
src/main.c

@@ -17,7 +17,7 @@ int		main(int ac, char **av, char **env)
 	{
 		if (ft_strcmp(av[1], "-c") == 0 && ac == 3)
 		{
-			detect_blocks(e, av[2]);
+			init_detect_blocks(e, av[2]);
 			comma_split(e, av[2]);
 		}
 		else if (ac == 2 && ft_strcmp(av[1], "-c") != 0)
@@ -45,7 +45,7 @@ void	shell_script(t_e *e, char *script_name)
 	fd = open(script_name, O_RDONLY);
 	while (get_next_line(fd, &line) != 0)
 	{
-		detect_blocks(e, line);
+		init_detect_blocks(e, line);
 		comma_split(e, line);
 	}
 }

+ 2 - 1
src/sh.h

@@ -27,7 +27,8 @@ void	comma_split(t_e *e, char *cmd);
 /*
 ** detect_cotes.c
 */
-void	detect_blocks(t_e *e, char *line);
+void	init_detect_blocks(t_e *e, char *line);
+void	detect_blocks(t_e *e, char *line, int pos, int b_pos);
 int		coted_block(t_e *e, char *line, int pos, t_block *blk);
 int		non_coted_block(t_e *e, char *line, int pos, t_block *blk);
 /*

+ 1 - 0
tests.sh

@@ -150,6 +150,7 @@ tests=(
 "\'"
 "\""
 "\`"
+"\"anrusit\" \"bnrst" # one coted block, one opening coted block
 
 ## Mix
 "rm $tmpf ; ls ; pwd; ls -a | cat -e | wc > $tmpf ; cat $tmpf ; rm $tmpf" # point-virgules, pipes et redirection