From: Ben Pfaff Date: Fri, 12 Aug 2011 21:59:11 +0000 (-0700) Subject: ofp-parse: Fix parsing of register values 2**31 and greater. X-Git-Tag: v1.2.1~3 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=1bad6ee87d0128010e74dd4f9a1966a738a4d7d0;hp=6abb5deeb72e0bd49dfc0f621e1ca552e865a720;p=sliver-openvswitch.git ofp-parse: Fix parsing of register values 2**31 and greater. Reported-by: Ethan Jackson --- diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 58b0da1ea..d6be774a8 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -781,14 +781,20 @@ parse_field_value(struct cls_rule *rule, enum field_index index, static void parse_reg_value(struct cls_rule *rule, int reg_idx, const char *value) { - uint32_t reg_value, reg_mask; + /* This uses an oversized destination field (64 bits when 32 bits would do) + * because some sscanf() implementations truncate the range of %i + * directives, so that e.g. "%"SCNi16 interprets input of "0xfedc" as a + * value of 0x7fff. The other alternatives are to allow only a single + * radix (e.g. decimal or hexadecimal) or to write more sophisticated + * parsers. */ + unsigned long long int reg_value, reg_mask; if (!strcmp(value, "ANY") || !strcmp(value, "*")) { cls_rule_set_reg_masked(rule, reg_idx, 0, 0); - } else if (sscanf(value, "%"SCNi32"/%"SCNi32, + } else if (sscanf(value, "%lli/%lli", ®_value, ®_mask) == 2) { cls_rule_set_reg_masked(rule, reg_idx, reg_value, reg_mask); - } else if (sscanf(value, "%"SCNi32, ®_value)) { + } else if (sscanf(value, "%lli", ®_value)) { cls_rule_set_reg(rule, reg_idx, reg_value); } else { ovs_fatal(0, "register fields must take the form "