diff --git a/apps/encoder.c b/apps/encoder.c index 0bad34878bedc00a8d67d921b9a953db0af9531f..005794d939b2fd41279963342142bdaa2c366d31 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -1273,8 +1273,21 @@ static bool parseCmdlIVAS_enc( arg->inputFormat = IVAS_ENC_INPUT_ISM; i++; +#ifdef IMPROVE_CMDLINE_ROBUSTNESS + if ( i < argc - 4 ) +#else if ( i < argc - 5 ) +#endif { +#ifdef IMPROVE_CMDLINE_ROBUSTNESS + if ( !is_digits_only( argv[i] ) ) + { + fprintf( stderr, "Error: Number of ISM channels must be an integer number!\n\n" ); + usage_enc(); + return false; + } +#endif + if ( sscanf( argv[i], "%d", &tmp ) > 0 ) { i++; @@ -1286,6 +1299,14 @@ static bool parseCmdlIVAS_enc( usage_enc(); return false; } +#ifdef IMPROVE_CMDLINE_ROBUSTNESS + else if ( tmp > IVAS_MAX_NUM_OBJECTS ) + { + fprintf( stderr, "Error: Too high number of ISM channels specified!\n\n" ); + usage_enc(); + return false; + } +#endif else { arg->inputFormatConfig.ism.numObjects = (int16_t) tmp; @@ -1317,7 +1338,11 @@ static bool parseCmdlIVAS_enc( } else { +#ifdef IMPROVE_CMDLINE_ROBUSTNESS + fprintf( stderr, "Error: not enough metadata arguments specified!\n\n" ); +#else fprintf( stderr, "Error: not enough arguments\n\n" ); +#endif usage_enc(); return false; } @@ -1329,17 +1354,25 @@ static bool parseCmdlIVAS_enc( arg->inputFormat = IVAS_ENC_INPUT_SBA; /* SBA configuration */ - if ( i < argc - 4 ) + if ( i < argc - 4 +#ifdef IMPROVE_CMDLINE_ROBUSTNESS + && is_number( argv[i] ) && sscanf( argv[i], "%d", &tmp ) > 0 +#endif + ) { +#ifndef IMPROVE_CMDLINE_ROBUSTNESS if ( sscanf( argv[i], "%d", &tmp ) > 0 ) { +#endif i++; +#ifndef IMPROVE_CMDLINE_ROBUSTNESS } +#endif } else { tmp = -1; /* this is to avoid a compilation warning */ - fprintf( stderr, "Error: SBA order not specified!\n\n" ); + fprintf( stderr, "Error: SBA order must be specified, expecting a number!\n\n" ); usage_enc(); return false; } @@ -1371,6 +1404,15 @@ static bool parseCmdlIVAS_enc( if ( i < argc - 4 ) { +#ifdef IMPROVE_CMDLINE_ROBUSTNESS + if ( !is_digits_only( argv[i] ) ) + { + fprintf( stderr, "Error: Number of MASA channels must be an integer number!\n\n" ); + usage_enc(); + return false; + } +#endif + if ( sscanf( argv[i], "%d", &tmp ) > 0 ) { i++; @@ -1385,7 +1427,11 @@ static bool parseCmdlIVAS_enc( arg->inputFormatConfig.masaVariant = IVAS_ENC_MASA_2CH; break; default: +#ifdef IMPROVE_CMDLINE_ROBUSTNESS + fprintf( stderr, "Error: MASA channels must be 1 or 2.\n\n" ); +#else fprintf( stderr, "Error: MASA channels must for the moment be 1 or 2.\n\n" ); +#endif usage_enc(); return false; } @@ -1410,7 +1456,6 @@ static bool parseCmdlIVAS_enc( if ( i < argc - 4 ) { - if ( strcmp( to_upper( argv[i] ), "5_1" ) == 0 ) { arg->inputFormatConfig.mcLayout = IVAS_ENC_MC_5_1; diff --git a/lib_com/options.h b/lib_com/options.h index 9dc8ab44c80be8e4f09041ddd95648f28ab549dc..8a84da5d9f5375155690d2e4d2f53caa446133d5 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -153,7 +153,7 @@ #define FIX_ITD_CNG /* Eri Contribution 11: Fix for CNG ITD */ #define FIX_VBR_COMPLEXITY /* Issue 234: fix extremely high complexity numbers for IVAS EVS mode */ #define FIX_ISM_INACTIVE_BITS /* Issue 230: fix bitbudget distribution in inactive frames in ISM format */ - +#define IMPROVE_CMDLINE_ROBUSTNESS /* Issue 233: Improve robustness of command-line parameters */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_util/cmdl_tools.c b/lib_util/cmdl_tools.c index d0d2d0d374eec0328fa6aeb56df3024f28880921..d36112f8a305716af771731437523d206d54fe7d 100644 --- a/lib_util/cmdl_tools.c +++ b/lib_util/cmdl_tools.c @@ -62,7 +62,7 @@ char *to_upper( char *str ) * Check if a string contains only digits. *---------------------------------------------------------------------*/ -bool is_digits_only( char *str ) +bool is_digits_only( const char *str ) { int16_t i; @@ -86,19 +86,58 @@ bool is_digits_only( char *str ) * Check if a string is a number. *---------------------------------------------------------------------*/ -bool is_number( char *str ) +bool is_number( const char *str ) { + bool decimal_separator_found; int16_t i; + int16_t numeric_len; + decimal_separator_found = false; i = 0; + numeric_len = 0; + + /* Check for null string or sign character */ + if ( str[i] == '\0' ) + { + return false; + } + else if ( str[i] == '+' || str[i] == '-' ) + { + i++; + } + + /* Ensure rest of string is numeric and only one decimal separator is present */ while ( str[i] != 0 ) { - if ( ( str[i] < '0' || str[i] > '9' ) && str[i] != '.' && str[i] != '-' && str[i] != '\n' && str[i] != '\r' ) + if ( str[i] < '0' || str[i] > '9' ) { - return false; + if ( str[i] == '.' ) + { + if ( decimal_separator_found ) + { + return false; + } + else + { + decimal_separator_found = true; + } + } + else if ( str[i] != '\r' && str[i] != '\n' ) + { + return false; + } + } + else + { + numeric_len++; } i++; } + if ( numeric_len == 0 ) + { + return false; + } + return true; } diff --git a/lib_util/cmdl_tools.h b/lib_util/cmdl_tools.h index 829ec985b0314f375f3489447296734754423617..52b6e694536c376bea5bff1160d98ecaa09d8ce4 100644 --- a/lib_util/cmdl_tools.h +++ b/lib_util/cmdl_tools.h @@ -36,9 +36,9 @@ #include #include -bool is_digits_only( char *str ); +bool is_digits_only( const char *str ); -bool is_number( char *str ); +bool is_number( const char *str ); char *to_upper( char *str );