pipeline parse: reject hanging pipe at end

This rejects commands such as

echo hello | cat -e |

I also updated the doc this time
This commit is contained in:
Khaïs COLIN 2025-02-24 17:27:14 +01:00
parent 8606774781
commit 4b403c4bf3
Signed by: logistic-bot
SSH key fingerprint: SHA256:RlpiqKeXpcPFZZ4y9Ou4xi2M8OhRJovIwDlbCaMsuAo
2 changed files with 28 additions and 9 deletions

View file

@ -6,14 +6,17 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/24 14:36:43 by khais #+# #+# */ /* Created: 2025/02/24 14:36:43 by khais #+# #+# */
/* Updated: 2025/02/24 15:53:04 by khais ### ########.fr */ /* Updated: 2025/02/28 13:13:38 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "pipeline_parse.h" #include "pipeline_parse.h"
#include "pipeline.h"
#include "pipeline_parse_baseops.h" #include "pipeline_parse_baseops.h"
#include "../../ft_errno.h" #include "../../ft_errno.h"
#include "../matchers/pipe.h" #include "../matchers/pipe.h"
#include "unistd.h"
#include "libft.h"
#include <stdlib.h> #include <stdlib.h>
/* /*
@ -82,8 +85,11 @@ static void pipeline_delimit(t_pipeline_builder *builder)
** - While there are still words remaining in the input stream ** - While there are still words remaining in the input stream
** - If we have a pipe character ** - If we have a pipe character
** - Delimit the current command ** - Delimit the current command
** - If there was an error ** - If there was an error
** - Return NULL ** - Return NULL
** - If we reached the end of input stream
** - This means that there is a hanging pipe at the end of the pipeline.
** Destroy the pipeline, set ft_errno, and return NULL.
** - Push the current word to the accumulator for the next command ** - Push the current word to the accumulator for the next command
** - Advance the state to the next word ** - Advance the state to the next word
** - Since there is no pipe token at the end to delimit the last command, ** - Since there is no pipe token at the end to delimit the last command,
@ -92,9 +98,6 @@ static void pipeline_delimit(t_pipeline_builder *builder)
** additional memory freeing is required. ** additional memory freeing is required.
** in case of error in pipeline_delimit, it will call destroy, which will set ** in case of error in pipeline_delimit, it will call destroy, which will set
** builder->pipeline to NULL ** builder->pipeline to NULL
**
** Note: if there is a | token at the end of the input stream, the results are
** undefined.
*/ */
t_pipeline *pipeline_parse_wordlist(t_pipeline_builder *builder) t_pipeline *pipeline_parse_wordlist(t_pipeline_builder *builder)
{ {
@ -104,9 +107,17 @@ t_pipeline *pipeline_parse_wordlist(t_pipeline_builder *builder)
while (!eof(builder)) while (!eof(builder))
{ {
if (current_is_pipe(builder)) if (current_is_pipe(builder))
{
pipeline_delimit(builder); pipeline_delimit(builder);
if (builder->error) if (builder->error)
return (NULL); return (NULL);
if (eof(builder))
{
builder_destroy(builder);
ft_errno(FT_EUNEXPECTED_PIPE);
return (NULL);
}
}
push_word(builder); push_word(builder);
next_word(builder); next_word(builder);
} }

View file

@ -6,7 +6,7 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */ /* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/21 13:13:58 by khais #+# #+# */ /* Created: 2025/02/21 13:13:58 by khais #+# #+# */
/* Updated: 2025/02/24 15:19:39 by khais ### ########.fr */ /* Updated: 2025/02/24 17:22:54 by khais ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -117,6 +117,13 @@ static void test_parse_pipeline_pipe_at_start_rejected(void)
assert(ft_errno_get() == FT_EUNEXPECTED_PIPE); assert(ft_errno_get() == FT_EUNEXPECTED_PIPE);
} }
static void test_parse_pipeline_pipe_at_end_rejected(void)
{
ft_errno(FT_ESUCCESS);
assert(parse_pipeline("echo hello | tee output.txt |") == NULL);
assert(ft_errno_get() == FT_EUNEXPECTED_PIPE);
}
int main(void) int main(void)
{ {
test_parse_empty_pipeline(); test_parse_empty_pipeline();
@ -127,5 +134,6 @@ int main(void)
test_parse_pipeline_double_pipe_rejected(); test_parse_pipeline_double_pipe_rejected();
test_parse_pipeline_triple_pipe_rejected(); test_parse_pipeline_triple_pipe_rejected();
test_parse_pipeline_pipe_at_start_rejected(); test_parse_pipeline_pipe_at_start_rejected();
test_parse_pipeline_pipe_at_end_rejected();
return (0); return (0);
} }