diff --git a/inc/parser.h b/inc/parser.h index e2f06af..f293dad 100644 --- a/inc/parser.h +++ b/inc/parser.h @@ -15,6 +15,7 @@ # include "minishell.h" +char *parser_sanitize_string(t_minishell *msh, char *str, char c); t_command *parser_alloc_command(t_minishell *msh, char *cmd); t_list *parser_get_commands(t_minishell *msh); t_list *parser_get_input_redirects(t_list *list); diff --git a/src/debug/print_commands.c b/src/debug/print_commands.c index 2092b8d..5c0ee86 100644 --- a/src/debug/print_commands.c +++ b/src/debug/print_commands.c @@ -51,5 +51,10 @@ void token_print(void *param) if (!DEBUG) return ; token = (t_token *)param; + if (token->type == T_ERROR) + { + printf("Error: %d\n", token->type); + return ; + } printf("token type %i, value %s\n", token->type, token->value); } diff --git a/src/executor/executor_absolute_path.c b/src/executor/executor_absolute_path.c index 86916b1..99c5ccc 100644 --- a/src/executor/executor_absolute_path.c +++ b/src/executor/executor_absolute_path.c @@ -16,14 +16,10 @@ static char *resolve_relative(t_minishell *msh, char *cmd) { char *executable; - if (access(cmd, F_OK) == 0) - { - executable = ft_strdup_safe(msh, cmd); - if (!executable) - return (NULL); - return (executable); - } - return (NULL); + executable = ft_strdup_safe(msh, cmd); + if (!executable) + return (NULL); + return (executable); } static char *resolve_path(t_minishell *msh, char *path, char *cmd) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index 923492c..e7948bd 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -24,6 +24,21 @@ static int is_dir(char *path) return (S_ISDIR(path_stats.st_mode)); } +static int validate_executable_path(char *path) +{ + if (access(path, X_OK) < 0) + { + error_msg(path, "Permission denied"); + return (0); + } + if (is_dir(path)) + { + error_msg(path, "Is a directory"); + return (0); + } + return (1); +} + void executor_child(t_minishell *msh, t_command *command) { char *path; @@ -34,18 +49,13 @@ void executor_child(t_minishell *msh, t_command *command) dup2(command->fd_out, 1); executor_close_fds(command->n_fds); path = executor_absolute_path(msh, command->args[0]); - if (path == NULL || access(path, F_OK | X_OK) != 0) + if (path == NULL) { errno = 0; error_msg("minishell", "command not found"); return ; } - if (is_dir(path)) - { - ft_putstr_fd(RED BOLD, 2); - ft_putstr_fd("minishell: ", 2); - ft_putstr_fd(command->args[0], 2); - ft_putstr_fd(": " RESET "Is a directory\n", 2); - } + else if (! validate_executable_path(path)) + return ; execve(path, command->args, environment_get_arr(msh)); } diff --git a/src/lexer/lexer_parse_input.c b/src/lexer/lexer_parse_input.c index 1fd02a1..375be79 100644 --- a/src/lexer/lexer_parse_input.c +++ b/src/lexer/lexer_parse_input.c @@ -35,10 +35,12 @@ t_list *ft_parse_input(t_minishell *msh) while (TRUE) { token = ft_token_next(msh, lexer); - if (token->type == T_EOF || token->type == T_ERROR) - break ; ft_lstadd_back(&list, ft_lstnew_safe(msh, token)); + if (token->type == T_EOF || token->type == T_ERROR) + { + break ; + } } - ft_token_free(msh, token); + // ft_token_free(msh, token); return (list); } diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 2ffb01c..801961b 100644 --- a/src/lexer/lexer_read_word.c +++ b/src/lexer/lexer_read_word.c @@ -14,35 +14,11 @@ static int is_word_char(char c) { - return (ft_isprint(c) - && c != '<' - && c != '>' - && c != '|' - && c != '\0' - && !ft_isspace(c)); -} - -static int match_quotes(t_minishell *msh, t_lexer *lexer) -{ - char c; - int i; - int d_qts; - int s_qts; - - i = lexer->pos; - c = lexer->input[i]; - d_qts = 0; - s_qts = 0; - while (is_word_char(c)) - { - if (lexer->input[i] == '\'') - s_qts++; - if (lexer->input[i] == '\'') - d_qts++; - i++; - c = lexer->input[i]; - } - return ((s_qts % 2) == 0 && (d_qts % 2) == 0); + if (c == '<' || c == '>' || c == '|' || c == '\0') + return (0); + else if (ft_isspace(c)) + return (0); + return (ft_isprint(c)); } static int calculate_word_len(t_minishell *msh, t_lexer *lexer) @@ -54,36 +30,46 @@ static int calculate_word_len(t_minishell *msh, t_lexer *lexer) i = lexer->pos; while (is_word_char(lexer->input[i])) { - if (lexer->input[i] != '\'' && lexer->input[i] != '"') - len++; + + len++; i++; } return (len); } -char *lexer_readword(t_minishell *msh, t_lexer *lexer) +char *read_word(t_minishell *msh, t_lexer *lexer, int len) { - int len; - char *word; char c; + char *dest; + int i; - if (lexer->current_char == '"' || lexer->current_char == '\'') - { - return (lexer_parse_quotes(msh, lexer)); - } - if (!match_quotes(msh, lexer)) - return (NULL); - len = calculate_word_len(msh, lexer); - word = malloc_safe(msh, sizeof(char) * len); + dest = malloc_safe(msh, sizeof(char) * len); c = lexer->current_char; - len = 0; + i = 0; while (is_word_char(c)) { - if (c != '\'' && c != '"') - word[len++] = lexer->current_char; + dest[i++] = lexer->current_char; lexer_readchar(lexer); c = lexer->current_char; } - word[len] = 0; + dest[i] = 0; + return (dest); +} + +char *lexer_readword(t_minishell *msh, t_lexer *lexer) +{ + int len; + int qts; + char *word; + char c; + + c = lexer->current_char; + qts = (c == '"' || c == '\''); + if (qts) + return (lexer_parse_quotes(msh, lexer)); + // if (!match_quotes(msh, lexer, qts)) + // return (NULL); + len = calculate_word_len(msh, lexer); + word = read_word(msh, lexer, len); return (word); } diff --git a/src/lexer/lexer_token_next.c b/src/lexer/lexer_token_next.c index 12d571c..e8d7e34 100644 --- a/src/lexer/lexer_token_next.c +++ b/src/lexer/lexer_token_next.c @@ -22,7 +22,7 @@ static t_token_type get_word_type(char c) return (T_WORD); } -static t_token *process_word(t_minishell *msh, t_lexer *lexer, int pos) +static t_token * process_word(t_minishell *msh, t_lexer *lexer, int pos) { t_token_type word_type; t_token *token; @@ -31,7 +31,9 @@ static t_token *process_word(t_minishell *msh, t_lexer *lexer, int pos) word_type = get_word_type(lexer->current_char); word = lexer_readword(msh, lexer); if (!word) + { return (token_new(msh, T_ERROR, &(lexer->current_char), pos)); + } token = token_new(msh, word_type, word, pos); free_safe(msh, (void **)&word); return (token); diff --git a/src/parser/parser_get_arguments.c b/src/parser/parser_get_arguments.c index 0375ba9..97120d2 100644 --- a/src/parser/parser_get_arguments.c +++ b/src/parser/parser_get_arguments.c @@ -10,7 +10,10 @@ /* */ /* ************************************************************************** */ +#include "libft.h" #include "minishell.h" +#include "parser.h" +#include "utils.h" static int count_cmds(t_list *list) { @@ -23,7 +26,7 @@ static int count_cmds(t_list *list) while (current) { token = ((t_token *)current->content); - if (token->type >= 3) + if (token->type > 2) break ; cmds++; current = current->next; @@ -40,41 +43,72 @@ static int parser_should_expand(t_list *value) if (!token) return (0); i = 0; - if (token->type == T_DQWORD) + if (token->type == T_DQWORD || token->type == T_WORD) { while (token->value[i]) { if (token->value[i] == '$' - && !expander_character_valid(token->value[i + 1])) - return (0); + && (expander_character_valid(token->value[i + 1]) || token->value[i + 1] == '?')) + return (1); i++; } - return (1); + return (0); } - return ((token->type == T_WORD && token->value[0] == '$' - && token->value[1])); + return (0); +} + +static char *parser_process_token(t_minishell *msh, char **args, t_list *prev, t_list *t_head) +{ + char *str; + t_token *token; + + if (!t_head) + return (NULL); + token = (t_token *)t_head->content; + str = NULL; + if (ft_strcmp(token->value, "") == 0) + return (NULL); + if (parser_should_expand(t_head)) + str = expander_parse_string(token->value, msh); + if (!str) + str = ft_strdup_safe(msh, token->value); + if (str && token->type == T_WORD && ft_strchr(str, '"')) + str = parser_sanitize_string(msh, str, '"'); + else if (str && token->type == T_WORD && ft_strchr(str, '\'')) + str = parser_sanitize_string(msh, str, '\''); + return (str); } char **parser_get_arguments(t_list *list, t_minishell *msh) { t_list *current; + t_list *prev; char **args; int cmds; int i; + char *str; + char *cat; cmds = count_cmds(list); args = malloc_safe(msh, (cmds + 1) * sizeof(char *)); current = list; - i = -1; - while ((++i) < cmds && current) + i = 0; + prev = NULL; + while (cmds > 0 && current) { - if (parser_should_expand(current)) - args[i] = expander_parse_string( - ((t_token *)current->content)->value, msh); - else if (((t_token *)current->content)->type < 3) - args[i] = ft_strdup_safe(msh, - ((t_token *)current->content)->value); + str = parser_process_token(msh, args, prev, current); + if (i > 0 && prev && ft_strcmp(((t_token *)prev->content)->value, "") == 0) + { + cat = malloc_safe(msh, ft_strlen(str) + ft_strlen(args[i - 1]) + 1); + ft_strlcpy(cat, args[i - 1], ft_strlen(args[i - 1]) + 1); + ft_strlcat(cat, str, ft_strlen(str) + ft_strlen(args[i - 1]) + 1); + args[i - 1] = cat; + } + else if (str) + args[i++] = str; + prev = current; current = current->next; + cmds--; } args[i] = 0; return (args); diff --git a/src/parser/parser_sanitize_string.c b/src/parser/parser_sanitize_string.c new file mode 100644 index 0000000..68cdb02 --- /dev/null +++ b/src/parser/parser_sanitize_string.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_sanitize_string.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/05 10:56:27 by qmennen #+# #+# */ +/* Updated: 2025/03/05 11:09:25 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *parser_sanitize_string(t_minishell *msh, char *str, char c) +{ + int i; + int j; + int qts; + char *dest; + + i = 0; + qts = 0; + while (str[i++]) + if (str[i] == c) + qts++; + dest = malloc_safe(msh, ft_strlen(str) - qts + 1); + i = 0; + j = 0; + while (str[i]) + { + if (str[i] != c) + dest[j++] = str[i]; + i++; + } + dest[j] = 0; + free_safe(msh, (void **)&str); + return (dest); +}