On Wed, Jun 06, 2012 at 05:30:03PM +0200, Laszlo Ersek wrote:
> On 06/06/12 17:16, Michael Roth wrote:
> > On Wed, Jun 06, 2012 at 04:10:44PM +0200, Paolo Bonzini wrote:
> 
> >> The uintXX visitors do not fail if you pass a negative value.  I'm fine
> >> with including the patch with the small bug and fixing it as a
> >> follow-up, there's plenty of time before 1.2.
> > 
> > How would we implement such a check?
> > 
> > In the case of uint64_t, the field we're visiting is passed in as a
> > uint64_t*, so -1 is indistinguishable from the unsigned interpretation
> > of the field, which is within the valid range. 
> > 
> > For uintXX_t where XX < 64, a negative value would exceed the UINTXX_MAX
> > check, so those cases are already handled.
> > 
> > Or am I missing something?
> 
> I found three instances of the patch on the list:
> 
>   http://lists.nongnu.org/archive/html/qemu-devel/2012-04/msg00333.html
>   http://lists.nongnu.org/archive/html/qemu-devel/2012-04/msg01292.html
>   http://lists.nongnu.org/archive/html/qemu-devel/2012-04/msg04068.html
> 
> looking at the third one, all of
> 
> - visit_type_uint8()
> - visit_type_uint16()
> - visit_type_uint32()
> - visit_type_uint64()
> 
> seem to define "value" as an int64_t. Thus when we fall back to
> (*v->type_int)(), the comparison is still done against an int64_t. Since
> "int" is equivalent to "int32_t" on the platforms I can think of, and
> "int64_t" to "long long", the comparisons are evaluated as follows:
> 
>   value > UINT8_MAX
>   value > UINT16_MAX
> 
> First the right hand sides are promoted to "int" (with unchanged value),
> and then "int" is converted to "long long" (both signed, different
> conversion rank).
> 
>   value > UINT32_MAX
> 
> The right hand side is directly converted to "long long" (signed vs.
> unsigned, signed has greater rank and can represent all values of the
> lower-rank unsigned type).
> 
> I propose
> 
>   value < 0 || value > UINT8_MAX
>   value < 0 || value > UINT16_MAX
>   value < 0 || value > UINT32_MAX

>   value < 0

I think this last one will cause problems though, since uint64_t's
within the valid range for visit_type_uint64() will fail due to being
interpreted as < 0 when cast to int64_t. With the others we can detect
these cases since the max unsigned value doesn't exceed the max signed
value of the intermediate type we're storing to.

> 
> Laszlo
> 

Reply via email to