Change parser to handle numbers as unsigned

Lexer always parsed numbers as unsigned, but parser handled them as
signed and grammar contained many unnecessary checks for negativity.
This commit is contained in:
Ondrej Zajicek (work) 2017-05-23 17:22:53 +02:00
parent 0705a1c565
commit 6aaaa63519
7 changed files with 32 additions and 34 deletions

View file

@ -27,16 +27,16 @@ CF_HDR
CF_DEFINES CF_DEFINES
static void static void
check_u16(unsigned val) check_u16(uint val)
{ {
if (val > 0xFFFF) if (val > 0xFFFF)
cf_error("Value %d out of range (0-65535)", val); cf_error("Value %u out of range (0-65535)", val);
} }
CF_DECLS CF_DECLS
%union { %union {
int i; uint i;
u32 i32; u32 i32;
u64 i64; u64 i64;
ip_addr a; ip_addr a;
@ -175,7 +175,7 @@ ipa_scope:
pxlen4: pxlen4:
'/' NUM { '/' NUM {
if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2); if ($2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %u", $2);
$$ = $2; $$ = $2;
} }
| ':' IP4 { | ':' IP4 {
@ -196,8 +196,8 @@ net_ip4_: IP4 pxlen4
net_ip6_: IP6 '/' NUM net_ip6_: IP6 '/' NUM
{ {
if ($3 < 0 || $3 > IP6_MAX_PREFIX_LENGTH) if ($3 > IP6_MAX_PREFIX_LENGTH)
cf_error("Invalid prefix length %d", $3); cf_error("Invalid prefix length %u", $3);
net_fill_ip6(&($$), $1, $3); net_fill_ip6(&($$), $1, $3);
@ -223,16 +223,16 @@ net_roa4_: net_ip4_ MAX NUM AS NUM
{ {
$$ = cfg_alloc(sizeof(net_addr_roa4)); $$ = cfg_alloc(sizeof(net_addr_roa4));
net_fill_roa4($$, net4_prefix(&$1), net4_pxlen(&$1), $3, $5); net_fill_roa4($$, net4_prefix(&$1), net4_pxlen(&$1), $3, $5);
if ($3 < (int) net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH) if ($3 < net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH)
cf_error("Invalid max prefix length %d", $3); cf_error("Invalid max prefix length %u", $3);
}; };
net_roa6_: net_ip6_ MAX NUM AS NUM net_roa6_: net_ip6_ MAX NUM AS NUM
{ {
$$ = cfg_alloc(sizeof(net_addr_roa6)); $$ = cfg_alloc(sizeof(net_addr_roa6));
net_fill_roa6($$, net6_prefix(&$1), net6_pxlen(&$1), $3, $5); net_fill_roa6($$, net6_prefix(&$1), net6_pxlen(&$1), $3, $5);
if ($3 < (int) net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH) if ($3 < net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH)
cf_error("Invalid max prefix length %d", $3); cf_error("Invalid max prefix length %u", $3);
}; };
net_ip_: net_ip4_ | net_ip6_ ; net_ip_: net_ip4_ | net_ip6_ ;

View file

@ -728,8 +728,8 @@ fprefix:
| net_ip_ '-' { $$.net = $1; $$.lo = 0; $$.hi = $1.pxlen; } | net_ip_ '-' { $$.net = $1; $$.lo = 0; $$.hi = $1.pxlen; }
| net_ip_ '{' NUM ',' NUM '}' { | net_ip_ '{' NUM ',' NUM '}' {
$$.net = $1; $$.lo = $3; $$.hi = $5; $$.net = $1; $$.lo = $3; $$.hi = $5;
if ((0 > $3) || ($3 > $5) || ($5 > net_max_prefix_length[$1.type])) if (($3 > $5) || ($5 > net_max_prefix_length[$1.type]))
cf_error("Invalid prefix pattern range: {%d, %d}", $3, $5); cf_error("Invalid prefix pattern range: {%u, %u}", $3, $5);
} }
; ;

View file

@ -19,11 +19,11 @@ struct f_inst { /* Instruction */
u16 code; /* Instruction code, see the interpret() function and P() macro */ u16 code; /* Instruction code, see the interpret() function and P() macro */
u16 aux; /* Extension to instruction code, T_*, EA_*, EAF_* */ u16 aux; /* Extension to instruction code, T_*, EA_*, EAF_* */
union { union {
int i; uint i;
void *p; void *p;
} a1; /* The first argument */ } a1; /* The first argument */
union { union {
int i; uint i;
void *p; void *p;
} a2; /* The second argument */ } a2; /* The second argument */
int lineno; int lineno;

View file

@ -349,8 +349,8 @@ iface_patt:
; ;
tos: tos:
CLASS expr { $$ = $2 & 0xfc; if (($2 < 0) || ($2 > 255)) cf_error("TX class must be in range 0-255"); } CLASS expr { $$ = $2 & 0xfc; if ($2 > 255) cf_error("TX class must be in range 0-255"); }
| DSCP expr { $$ = ($2 & 0x3f) << 2; if (($2 < 0) || ($2 > 63)) cf_error("TX DSCP must be in range 0-63"); } | DSCP expr { $$ = ($2 & 0x3f) << 2; if ($2 > 63) cf_error("TX DSCP must be in range 0-63"); }
; ;
/* Direct device route protocol */ /* Direct device route protocol */

View file

@ -126,7 +126,7 @@ static inline void
ospf_check_defcost(int cost) ospf_check_defcost(int cost)
{ {
if ((cost <= 0) || (cost >= LSINFINITY)) if ((cost <= 0) || (cost >= LSINFINITY))
cf_error("Default cost must be in range 1-%d", LSINFINITY-1); cf_error("Default cost must be in range 1-%u", LSINFINITY-1);
} }
static inline void static inline void
@ -185,10 +185,10 @@ ospf_proto_item:
| RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; } | RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; }
| STUB ROUTER bool { OSPF_CFG->stub_router = $3; } | STUB ROUTER bool { OSPF_CFG->stub_router = $3; }
| ECMP bool { OSPF_CFG->ecmp = $2 ? OSPF_DEFAULT_ECMP_LIMIT : 0; } | ECMP bool { OSPF_CFG->ecmp = $2 ? OSPF_DEFAULT_ECMP_LIMIT : 0; }
| ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); } | ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; }
| MERGE EXTERNAL bool { OSPF_CFG->merge_external = $3; } | MERGE EXTERNAL bool { OSPF_CFG->merge_external = $3; }
| TICK expr { OSPF_CFG->tick = $2; if($2 <= 0) cf_error("Tick must be greater than zero"); } | TICK expr { OSPF_CFG->tick = $2; if($2 <= 0) cf_error("Tick must be greater than zero"); }
| INSTANCE ID expr { OSPF_CFG->instance_id = $3; if (($3<0) || ($3>255)) cf_error("Instance ID must be in range 0-255"); } | INSTANCE ID expr { OSPF_CFG->instance_id = $3; if ($3 > 255) cf_error("Instance ID must be in range 0-255"); }
| ospf_area | ospf_area
; ;
@ -318,7 +318,7 @@ ospf_iface_item:
| REAL BROADCAST bool { OSPF_PATT->real_bcast = $3; if (!ospf_cfg_is_v2()) cf_error("Real broadcast option requires OSPFv2"); } | REAL BROADCAST bool { OSPF_PATT->real_bcast = $3; if (!ospf_cfg_is_v2()) cf_error("Real broadcast option requires OSPFv2"); }
| PTP NETMASK bool { OSPF_PATT->ptp_netmask = $3; if (!ospf_cfg_is_v2()) cf_error("PtP netmask option requires OSPFv2"); } | PTP NETMASK bool { OSPF_PATT->ptp_netmask = $3; if (!ospf_cfg_is_v2()) cf_error("PtP netmask option requires OSPFv2"); }
| TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); } | TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
| PRIORITY expr { OSPF_PATT->priority = $2 ; if (($2<0) || ($2>255)) cf_error("Priority must be in range 0-255"); } | PRIORITY expr { OSPF_PATT->priority = $2 ; if ($2>255) cf_error("Priority must be in range 0-255"); }
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; } | STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
| STUB bool { OSPF_PATT->stub = $2 ; } | STUB bool { OSPF_PATT->stub = $2 ; }
| CHECK LINK bool { OSPF_PATT->check_link = $3; } | CHECK LINK bool { OSPF_PATT->check_link = $3; }
@ -404,7 +404,7 @@ ospf_iface_start:
ospf_instance_id: ospf_instance_id:
/* empty */ /* empty */
| INSTANCE expr { OSPF_PATT->instance_id = $2; if (($2<0) || ($2>255)) cf_error("Instance ID must be in range 0-255"); } | INSTANCE expr { OSPF_PATT->instance_id = $2; if ($2 > 255) cf_error("Instance ID must be in range 0-255"); }
; ;
ospf_iface_patt_list: ospf_iface_patt_list:

View file

@ -91,14 +91,14 @@ radv_iface_item:
| MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); } | MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); }
| MANAGED bool { RADV_IFACE->managed = $2; } | MANAGED bool { RADV_IFACE->managed = $2; }
| OTHER CONFIG bool { RADV_IFACE->other_config = $3; } | OTHER CONFIG bool { RADV_IFACE->other_config = $3; }
| LINK MTU expr { RADV_IFACE->link_mtu = $3; if ($3 < 0) cf_error("Link MTU must be 0 or positive"); } | LINK MTU expr { RADV_IFACE->link_mtu = $3; }
| REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if (($3 < 0) || ($3 > 3600000)) cf_error("Reachable time must be in range 0-3600000"); } | REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if ($3 > 3600000) cf_error("Reachable time must be in range 0-3600000"); }
| RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; if ($3 < 0) cf_error("Retrans timer must be 0 or positive"); } | RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; }
| CURRENT HOP LIMIT expr { RADV_IFACE->current_hop_limit = $4; if (($4 < 0) || ($4 > 255)) cf_error("Current hop limit must be in range 0-255"); } | CURRENT HOP LIMIT expr { RADV_IFACE->current_hop_limit = $4; if ($4 > 255) cf_error("Current hop limit must be in range 0-255"); }
| DEFAULT LIFETIME expr radv_sensitive { | DEFAULT LIFETIME expr radv_sensitive {
RADV_IFACE->default_lifetime = $3; RADV_IFACE->default_lifetime = $3;
if (($3 < 0) || ($3 > 9000)) cf_error("Default lifetime must be in range 0-9000"); if ($3 > 9000) cf_error("Default lifetime must be in range 0-9000");
if ($4 != -1) RADV_IFACE->default_lifetime_sensitive = $4; if ($4 != (uint) -1) RADV_IFACE->default_lifetime_sensitive = $4;
} }
| DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; } | DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; }
| PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); } | PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); }
@ -125,7 +125,7 @@ radv_iface_finish:
if ((ic->min_ra_int > 3) && if ((ic->min_ra_int > 3) &&
(ic->min_ra_int > (ic->max_ra_int * 3 / 4))) (ic->min_ra_int > (ic->max_ra_int * 3 / 4)))
cf_error("Min RA interval must be at most 3/4 * Max RA interval %d %d", ic->min_ra_int, ic->max_ra_int); cf_error("Min RA interval must be at most 3/4 * Max RA interval");
if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int)) if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int))
cf_error("Default lifetime must be either 0 or at least Max RA interval"); cf_error("Default lifetime must be either 0 or at least Max RA interval");
@ -163,13 +163,11 @@ radv_prefix_item:
| AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; } | AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; }
| VALID LIFETIME expr radv_sensitive { | VALID LIFETIME expr radv_sensitive {
RADV_PREFIX->valid_lifetime = $3; RADV_PREFIX->valid_lifetime = $3;
if ($3 < 0) cf_error("Valid lifetime must be 0 or positive"); if ($4 != (uint) -1) RADV_PREFIX->valid_lifetime_sensitive = $4;
if ($4 != -1) RADV_PREFIX->valid_lifetime_sensitive = $4;
} }
| PREFERRED LIFETIME expr radv_sensitive { | PREFERRED LIFETIME expr radv_sensitive {
RADV_PREFIX->preferred_lifetime = $3; RADV_PREFIX->preferred_lifetime = $3;
if ($3 < 0) cf_error("Preferred lifetime must be 0 or positive"); if ($4 != (uint) -1) RADV_PREFIX->preferred_lifetime_sensitive = $4;
if ($4 != -1) RADV_PREFIX->preferred_lifetime_sensitive = $4;
} }
; ;

View file

@ -65,7 +65,7 @@ rip_proto_item:
proto_item proto_item
| proto_channel | proto_channel
| ECMP bool { RIP_CFG->ecmp = $2 ? RIP_DEFAULT_ECMP_LIMIT : 0; } | ECMP bool { RIP_CFG->ecmp = $2 ? RIP_DEFAULT_ECMP_LIMIT : 0; }
| ECMP bool LIMIT expr { RIP_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); } | ECMP bool LIMIT expr { RIP_CFG->ecmp = $2 ? $4 : 0; }
| INFINITY expr { RIP_CFG->infinity = $2; } | INFINITY expr { RIP_CFG->infinity = $2; }
| INTERFACE rip_iface | INTERFACE rip_iface
; ;