Skip to content

Commit 56765d9

Browse files
committed
Merge branch 'try-atoi'
* try-atoi: LIB: sm_try_atoi: always initialize output integer, just in case TOOLS: use sm_try_atoi for midi note command line arguments SRC: smtool: check results of str->int conversions SRC: smplay: check results of str->int conversions SRC: smplay: do not fail with error if libao support is available SRC: smenc: check results of str->int conversions See #31: Providing an (invalid?) MIDI note (e.g., -m e) causes smenc to hang indefinitely without error messages. LIB: provide sm_try_atoi function for str->int conversion with validation Signed-off-by: Stefan Westerfeld <[email protected]>
2 parents b780664 + 1a4778f commit 56765d9

File tree

8 files changed

+104
-19
lines changed

8 files changed

+104
-19
lines changed

lib/smutils.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <string>
77
#include <locale>
88
#include <codecvt>
9+
#include <charconv>
910

1011
#include <assert.h>
1112
#include <stdarg.h>
@@ -574,6 +575,21 @@ dir_exists (const string& dirname)
574575
return false;
575576
}
576577

578+
bool
579+
sm_try_atoi (const char *str, int& i)
580+
{
581+
i = 0;
582+
583+
if (!str || *str == '\0')
584+
return false;
585+
586+
auto [ptr, ec] = std::from_chars (str, str + strlen (str), i);
587+
if (ec != std::errc() || *ptr != '\0')
588+
return false;
589+
590+
return true;
591+
}
592+
577593
double
578594
sm_atof (const char *str) // always use . as decimal seperator
579595
{

lib/smutils.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ Error read_dir (const std::string& dirname, std::vector<std::string>& files);
200200
bool file_exists (const std::string& filename);
201201
bool dir_exists (const std::string& dirname);
202202

203+
bool sm_try_atoi (const char *str, int& i);
203204
double sm_atof (const char *str); // always use . as decimal seperator
204205
double sm_atof_any (const char *str); // allow . or locale as decimal separator
205206

src/smenc.cc

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,13 @@ Options::parse (int *argc_p,
149149
}
150150
else if (check_arg (argc, argv, &i, "-m", &opt_arg))
151151
{
152-
fundamental_freq = freqFromNote (atoi (opt_arg));
152+
int note;
153+
if (!sm_try_atoi (opt_arg, note) || note < 0 || note > 127)
154+
{
155+
fprintf (stderr, "%s: invalid midi note '%s', should be integer between 0 and 127\n", options.program_name.c_str(), opt_arg);
156+
exit (1);
157+
}
158+
fundamental_freq = freqFromNote (note);
153159
fundamental_args++;
154160
}
155161
else if (check_arg (argc, argv, &i, "-M"))
@@ -176,7 +182,11 @@ Options::parse (int *argc_p,
176182
}
177183
else if (check_arg (argc, argv, &i, "-O", &opt_arg))
178184
{
179-
optimization_level = atoi (opt_arg);
185+
if (!sm_try_atoi (opt_arg, optimization_level) || optimization_level < 0 || optimization_level > 2)
186+
{
187+
fprintf (stderr, "%s: invalid optimization level '%s', should be integer between 0 and 2\n", options.program_name.c_str(), opt_arg);
188+
exit (1);
189+
}
180190
}
181191
else if (check_arg (argc, argv, &i, "-s"))
182192
{
@@ -226,7 +236,11 @@ Options::parse (int *argc_p,
226236
else if (check_arg (argc, argv, &i, "--text-input-file", &opt_arg))
227237
{
228238
text_input_file = true;
229-
text_input_rate = atoi (opt_arg);
239+
if (!sm_try_atoi (opt_arg, text_input_rate) || text_input_rate < 8000)
240+
{
241+
fprintf (stderr, "%s: invalid rate '%s', should be integer >= 8000\n", options.program_name.c_str(), opt_arg);
242+
exit (1);
243+
}
230244
}
231245
else if (check_arg (argc, argv, &i, "--config", &opt_arg))
232246
{

src/smplay.cc

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,31 @@ Options::parse (int *argc_p,
8282
}
8383
else if (check_arg (argc, argv, &i, "--rate", &opt_arg) || check_arg (argc, argv, &i, "-r", &opt_arg))
8484
{
85-
rate = atoi (opt_arg);
85+
if (!sm_try_atoi (opt_arg, rate) || rate < 8000)
86+
{
87+
fprintf (stderr, "%s: invalid rate '%s', should be integer >= 8000\n", options.program_name.c_str(), opt_arg);
88+
exit (1);
89+
}
8690
}
8791
else if (check_arg (argc, argv, &i, "--bits", &opt_arg))
8892
{
89-
bits = atoi (opt_arg);
93+
if (!sm_try_atoi (opt_arg, bits) || bits < 8)
94+
{
95+
fprintf (stderr, "%s: invalid bit depth '%s', should be integer >= 8\n", options.program_name.c_str(), opt_arg);
96+
exit (1);
97+
}
9098
}
9199
else if (check_arg (argc, argv, &i, "--export", &opt_arg) || check_arg (argc, argv, &i, "-x", &opt_arg))
92100
{
93101
export_wav = opt_arg;
94102
}
95103
else if (check_arg (argc, argv, &i, "--midi-note", &opt_arg) || check_arg (argc, argv, &i, "-m", &opt_arg))
96104
{
97-
midi_note = atoi (opt_arg);
105+
if (!sm_try_atoi (opt_arg, midi_note) || midi_note < 0 || midi_note > 127)
106+
{
107+
fprintf (stderr, "%s: invalid midi note '%s', should be integer between 0 and 127\n", options.program_name.c_str(), opt_arg);
108+
exit (1);
109+
}
98110
}
99111
else if (check_arg (argc, argv, &i, "--gain", &opt_arg) || check_arg (argc, argv, &i, "-g", &opt_arg))
100112
{
@@ -422,9 +434,10 @@ main (int argc, char **argv)
422434
pos += todo;
423435
}
424436
ao_close (play_device);
425-
#endif
437+
#else
426438
fprintf (stderr, "error: %s was compiled without libao support (use --export <filename>)\n", options.program_name.c_str());
427439
exit (1);
440+
#endif
428441
}
429442
else /* export wav */
430443
{

src/smtool.cc

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,11 @@ class NoiseParamsCommand : public Command
474474
{
475475
if (args.size() == 1)
476476
{
477-
frame = atoi (args[0].c_str());
477+
if (!sm_try_atoi (args[0].c_str(), frame) || frame < 0)
478+
{
479+
fprintf (stderr, "invalid frame number '%s'\n", args[0].c_str());
480+
return false;
481+
}
478482
return true;
479483
}
480484
return false;
@@ -505,7 +509,11 @@ class FrameCommand : public Command
505509
{
506510
if (args.size() == 1)
507511
{
508-
frame = atoi (args[0].c_str());
512+
if (!sm_try_atoi (args[0].c_str(), frame) || frame < 0)
513+
{
514+
fprintf (stderr, "invalid frame number '%s'\n", args[0].c_str());
515+
return false;
516+
}
509517
return true;
510518
}
511519
return false;
@@ -543,7 +551,11 @@ class FrameParamsCommand : public Command
543551
{
544552
if (args.size() == 1)
545553
{
546-
frame = atoi (args[0].c_str());
554+
if (!sm_try_atoi (args[0].c_str(), frame) || frame < 0)
555+
{
556+
fprintf (stderr, "invalid frame number '%s'\n", args[0].c_str());
557+
return false;
558+
}
547559
return true;
548560
}
549561
return false;
@@ -711,7 +723,11 @@ class SpectrumCommand : public Command
711723
{
712724
if (args.size() == 1)
713725
{
714-
frame = atoi (args[0].c_str());
726+
if (!sm_try_atoi (args[0].c_str(), frame) || frame < 0)
727+
{
728+
fprintf (stderr, "invalid frame number '%s'\n", args[0].c_str());
729+
return false;
730+
}
715731
return true;
716732
}
717733
return false;
@@ -902,8 +918,11 @@ class TuneAllFramesCommand : public Command
902918
{
903919
if (args.size() == 1)
904920
{
905-
fundamental_est_n = atoi (args[0].c_str());
906-
assert (fundamental_est_n >= 1 && fundamental_est_n <= 3);
921+
if (!sm_try_atoi (args[0].c_str(), fundamental_est_n) || fundamental_est_n < 1 || fundamental_est_n > 3)
922+
{
923+
fprintf (stderr, "invalid number of partials '%s', should be integer between 1 and 3\n", args[0].c_str());
924+
return false;
925+
}
907926
return true;
908927
}
909928
return false;
@@ -994,8 +1013,11 @@ class SmoothTuneCommand : public Command
9941013
{
9951014
if (args.size() == 3)
9961015
{
997-
fundamental_est_n = atoi (args[0].c_str());
998-
assert (fundamental_est_n >= 1 && fundamental_est_n <= 3);
1016+
if (!sm_try_atoi (args[0].c_str(), fundamental_est_n) || fundamental_est_n < 1 || fundamental_est_n > 3)
1017+
{
1018+
fprintf (stderr, "invalid number of partials '%s', should be integer between 1 and 3\n", args[0].c_str());
1019+
return false;
1020+
}
9991021
smooth_ms = sm_atof (args[1].c_str());
10001022
assert (smooth_ms > 10 && smooth_ms < 5000);
10011023
smooth_percent = sm_atof (args[2].c_str());
@@ -1194,7 +1216,11 @@ class ExtractSMCommand : public Command
11941216
{
11951217
if (args.size() == 2)
11961218
{
1197-
note = atoi (args[0].c_str());
1219+
if (!sm_try_atoi (args[0].c_str(), note) || note < 0 || note > 127)
1220+
{
1221+
fprintf (stderr, "invalid note '%s', should be integer between 0 and 127\n", args[0].c_str());
1222+
return false;
1223+
}
11981224
filename = args[1];
11991225
return true;
12001226
}

tools/smlive.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,13 @@ Options::parse (int *argc_p,
121121
}
122122
else if (check_arg (argc, argv, &i, "--midi-note", &opt_arg) || check_arg (argc, argv, &i, "-m", &opt_arg))
123123
{
124-
freq = freq_from_note (atoi (opt_arg));
124+
int note;
125+
if (!sm_try_atoi (opt_arg, note) || note < 0 || note > 127)
126+
{
127+
fprintf (stderr, "%s: invalid midi note '%s', should be integer between 0 and 127\n", options.program_name.c_str(), opt_arg);
128+
exit (1);
129+
}
130+
freq = freq_from_note (note);
125131
}
126132
else if (check_arg (argc, argv, &i, "--gain", &opt_arg) || check_arg (argc, argv, &i, "-g", &opt_arg))
127133
{

tools/smrunplan.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ Options::parse (int *argc_p,
8989
}
9090
else if (check_arg (argc, argv, &i, "--midi-note", &opt_arg) || check_arg (argc, argv, &i, "-m", &opt_arg))
9191
{
92-
midi_note = atoi (opt_arg);
92+
if (!sm_try_atoi (opt_arg, midi_note) || midi_note < 0 || midi_note > 127)
93+
{
94+
fprintf (stderr, "%s: invalid midi note '%s', should be integer between 0 and 127\n", options.program_name.c_str(), opt_arg);
95+
exit (1);
96+
}
9397
}
9498
else if (check_arg (argc, argv, &i, "--len", &opt_arg) || check_arg (argc, argv, &i, "-l", &opt_arg))
9599
{

tools/smsfimport.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ using SpectMorph::Main;
4343

4444
using SpectMorph::string_printf;
4545
using SpectMorph::sm_round_positive;
46+
using SpectMorph::sm_try_atoi;
4647

4748
using std::string;
4849
using std::vector;
@@ -567,7 +568,11 @@ Options::parse (int *argc_p,
567568
}
568569
else if (check_arg (argc, argv, &i, "-m", &opt_arg))
569570
{
570-
midi_note = atoi (opt_arg);
571+
if (!sm_try_atoi (opt_arg, midi_note) || midi_note < 0 || midi_note > 127)
572+
{
573+
fprintf (stderr, "%s: invalid midi note '%s', should be integer between 0 and 127\n", options.program_name.c_str(), opt_arg);
574+
exit (1);
575+
}
571576
}
572577
else if (check_arg (argc, argv, &i, "-j", &opt_arg))
573578
{

0 commit comments

Comments
 (0)