NeoMutt
2025-12-11-1009-ga75d9e
Teaching an old dog new tricks
DOXYGEN
Toggle main menu visibility
Loading...
Searching...
No Matches
cli.c
Go to the documentation of this file.
1
22
23
#include "config.h"
24
#include <ctype.h>
25
#include <stdbool.h>
26
#include <stdint.h>
27
#include <string.h>
28
#include <unistd.h>
29
#include "
mutt/lib.h
"
30
#include "
cli/lib.h
"
31
32
bool
StartupComplete
=
true
;
33
46
static
bool
parse_args
(
const
uint8_t *data,
size_t
size,
int
*argc,
char
***argv)
47
{
48
// Limit input size to prevent excessive memory usage
49
if
(size > 4096)
50
return
false
;
51
52
// Create a null-terminated copy of the input
53
char
*input =
MUTT_MEM_MALLOC
(size + 1,
char
);
54
memcpy(input, data, size);
55
input[size] =
'\0'
;
56
57
// Count arguments (words separated by spaces/control chars)
58
int
count = 1;
// Start with 1 for argv[0] = "neomutt"
59
bool
in_word =
false
;
60
61
for
(
size_t
i = 0; i < size; i++)
62
{
63
unsigned
char
c = (
unsigned
char) input[i];
64
// Treat control characters and space as separators
65
if
(iscntrl(c) || (c ==
' '
))
66
{
67
input[i] =
'\0'
;
68
in_word =
false
;
69
}
70
else
if
(!in_word)
71
{
72
count++;
73
in_word =
true
;
74
}
75
}
76
77
// Allocate argv array
78
char
**args =
MUTT_MEM_MALLOC
(count + 1,
char
*);
79
args[0] =
mutt_str_dup
(
"neomutt"
);
80
81
// Fill in arguments
82
int
idx = 1;
83
in_word =
false
;
84
char
*word_start = NULL;
85
86
for
(
size_t
i = 0; i < size; i++)
87
{
88
if
(input[i] ==
'\0'
)
89
{
90
if
(in_word && word_start)
91
{
92
args[idx++] =
mutt_str_dup
(word_start);
93
word_start = NULL;
94
}
95
in_word =
false
;
96
}
97
else
if
(!in_word)
98
{
99
word_start = &input[i];
100
in_word =
true
;
101
}
102
}
103
104
// Handle last word if input doesn't end with separator
105
if
(in_word && word_start)
106
{
107
args[idx++] =
mutt_str_dup
(word_start);
108
}
109
110
args[idx] = NULL;
111
FREE
(&input);
112
113
*argc = idx;
114
*argv = args;
115
return
true
;
116
}
117
123
static
void
free_args
(
int
argc,
char
**argv)
124
{
125
for
(
int
i = 0; i < argc; i++)
126
{
127
FREE
(&argv[i]);
128
}
129
FREE
(&argv);
130
}
131
132
int
LLVMFuzzerTestOneInput
(
const
uint8_t *data,
size_t
size)
133
{
134
MuttLogger
=
log_disp_null
;
135
136
int
argc = 0;
137
char
**argv = NULL;
138
139
if
(!
parse_args
(data, size, &argc, &argv))
140
return
-1;
141
142
// Disable getopt error output to stderr
143
opterr = 0;
144
145
struct
CommandLine
*cli =
command_line_new
();
146
cli_parse
(argc, (
char
*
const
*) argv, cli);
147
command_line_free
(&cli);
148
149
free_args
(argc, argv);
150
151
return
0;
152
}
lib.h
Parse the Command Line.
cli_parse
bool cli_parse(int argc, char *const *argv, struct CommandLine *cli)
Parse the Command Line.
Definition
parse.c:148
free_args
static void free_args(int argc, char **argv)
Free the allocated argc/argv.
Definition
cli.c:123
parse_args
static bool parse_args(const uint8_t *data, size_t size, int *argc, char ***argv)
Parse fuzz input into argc/argv format.
Definition
cli.c:46
LLVMFuzzerTestOneInput
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
Definition
cli.c:132
StartupComplete
bool StartupComplete
Definition
address.c:11
log_disp_null
int log_disp_null(time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...)
Discard log lines - Implements log_dispatcher_t -.
Definition
logging.c:515
MuttLogger
int log_dispatcher_t MuttLogger
FREE
#define FREE(x)
Free memory and set the pointer to NULL.
Definition
memory.h:68
MUTT_MEM_MALLOC
#define MUTT_MEM_MALLOC(n, type)
Definition
memory.h:53
lib.h
Convenience wrapper for the library headers.
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition
string.c:257
command_line_new
struct CommandLine * command_line_new(void)
Create a new CommandLine.
Definition
objects.c:105
command_line_free
void command_line_free(struct CommandLine **ptr)
Free a CommandLine.
Definition
objects.c:114
CommandLine
Command Line options.
Definition
objects.h:128