option: Fix to reject invalid and overflowing numbers
parse_option_number() fails to check for these errors after strtoull(). Has always been broken. Fix that. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1487708048-2131-10-git-send-email-armbru@redhat.com>
This commit is contained in:
		
							parent
							
								
									4baef2679e
								
							
						
					
					
						commit
						3403e5eb88
					
				| 
						 | 
					@ -603,17 +603,15 @@ static void test_opts_parse_number(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Above upper limit */
 | 
					    /* Above upper limit */
 | 
				
			||||||
    opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
 | 
					    opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
 | 
				
			||||||
                           false, &error_abort);
 | 
					                           false, &err);
 | 
				
			||||||
    /* BUG: should reject */
 | 
					    error_free_or_abort(&err);
 | 
				
			||||||
    g_assert_cmpuint(opts_count(opts), ==, 1);
 | 
					    g_assert(!opts);
 | 
				
			||||||
    g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Below lower limit */
 | 
					    /* Below lower limit */
 | 
				
			||||||
    opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
 | 
					    opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
 | 
				
			||||||
                           false, &error_abort);
 | 
					                           false, &err);
 | 
				
			||||||
    /* BUG: should reject */
 | 
					    error_free_or_abort(&err);
 | 
				
			||||||
    g_assert_cmpuint(opts_count(opts), ==, 1);
 | 
					    g_assert(!opts);
 | 
				
			||||||
    g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Hex and octal */
 | 
					    /* Hex and octal */
 | 
				
			||||||
    opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052",
 | 
					    opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052",
 | 
				
			||||||
| 
						 | 
					@ -624,9 +622,8 @@ static void test_opts_parse_number(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Invalid */
 | 
					    /* Invalid */
 | 
				
			||||||
    opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
 | 
					    opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
 | 
				
			||||||
    /* BUG: should reject */
 | 
					    error_free_or_abort(&err);
 | 
				
			||||||
    g_assert_cmpuint(opts_count(opts), ==, 1);
 | 
					    g_assert(!opts);
 | 
				
			||||||
    g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0);
 | 
					 | 
				
			||||||
    opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
 | 
					    opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
 | 
				
			||||||
    error_free_or_abort(&err);
 | 
					    error_free_or_abort(&err);
 | 
				
			||||||
    g_assert(!opts);
 | 
					    g_assert(!opts);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,11 +141,16 @@ static void parse_option_bool(const char *name, const char *value, bool *ret,
 | 
				
			||||||
static void parse_option_number(const char *name, const char *value,
 | 
					static void parse_option_number(const char *name, const char *value,
 | 
				
			||||||
                                uint64_t *ret, Error **errp)
 | 
					                                uint64_t *ret, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *postfix;
 | 
					 | 
				
			||||||
    uint64_t number;
 | 
					    uint64_t number;
 | 
				
			||||||
 | 
					    int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    number = strtoull(value, &postfix, 0);
 | 
					    err = qemu_strtou64(value, NULL, 0, &number);
 | 
				
			||||||
    if (*postfix != '\0') {
 | 
					    if (err == -ERANGE) {
 | 
				
			||||||
 | 
					        error_setg(errp, "Value '%s' is too large for parameter '%s'",
 | 
				
			||||||
 | 
					                   value, name);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (err) {
 | 
				
			||||||
        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
 | 
					        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue