Skip to content
This repository was archived by the owner on Dec 18, 2019. It is now read-only.

Literal: Check Literal::Integer at limits and when overflowing#38

Merged
Hywan merged 7 commits intotagua-vm:masterfrom
Hywan:literal_overflow
Aug 9, 2016
Merged

Literal: Check Literal::Integer at limits and when overflowing#38
Hywan merged 7 commits intotagua-vm:masterfrom
Hywan:literal_overflow

Conversation

@Hywan
Copy link
Member

@Hywan Hywan commented Aug 3, 2016

First, Literal::Integer was a u64 which is wrong regarding the specification (https://github.com/php/php-langspec/blob/master/spec/05-types.md#the-integer-type):

This type is binary, signed, and uses twos-complement representation for negative values. The range of values that can be stored is implementation-defined; however, the range [-2147483648, 2147483647], must be supported. This range must be finite.

Second, new test cases are added to test the limit values of integer representation (before and after overflow).

Third, only decimal will overflow to reals. The specification says:

Certain operations on integer values produce a mathematical result that cannot be represented as an integer.
[…]
In such cases, the computation is done as though the types of the values were float with the result having that type.

It does not mention the parsing behavior. The Zend Engine will apply the overflow from integer to real for all “number” representations, aka binary, octal, decimal and hexadecimal. However, the f32::from_str_radix and f64::from_str_radix functions have been removed from Rust std (see https://internals.rust-lang.org/t/deprecate-f-32-64-from-str-radix/2405) for good reasons I have to admit. So I consider this is an edge case and only the support for decimal overflow is added.

If a volunteer woud like to reimplement a safe and stable from_str_radix for f64 (for 2, 8, 10 and 16 radices only), good! I am pretty sure it will be hard (to write and to test). If this is a very important conformance issue, let's open an issue.

Thoughts @jubianchi, @nikic?

Hywan added 5 commits August 3, 2016 00:23
The specification says:

> This type is binary, signed, and uses twos-complement representation
> for negative values. The range of values that can be stored is
> implementation-defined; however, the range [-2147483648, 2147483647],
> must be supported. This range must be finite.

https://github.com/php/php-langspec/blob/master/spec/05-types.md#the-integer-type
@nikic
Copy link

nikic commented Aug 3, 2016

I suspect that overflowing hex literals are more common than one might think due to people trying to use unsigned 64-bit literals, like 0xffffffffffffffff, which are actually floating point literals. Btw, I think the hex/bin/oct float literal parsing in PHP is actually broken (not accurate)...

@Hywan
Copy link
Member Author

Hywan commented Aug 3, 2016

@nikic I am pretty sure it is. Even in Rust, the f64.from_str_radix with a decimal representation is not accurate. I wonder if we should land inaccurate code or not land anything at all. By the way, this is a good opportunity for a Rust contribution. We can release it as a standalone crate and use it inside tagua/parser. Thoughts?

#[test]
fn case_octal_maximum_integer_value() {
let input = b"0777777777777777777777";
let output = Done(&b""[..], Literal::Integer(!(1i64 << 63)));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use std::i64::MAX here.

Hywan added 2 commits August 3, 2016 12:26
It is better to use the `MAX` constant instead of computing the maximum
value with bitwise operations.
@Hywan
Copy link
Member Author

Hywan commented Aug 9, 2016

A new issue has been created to split the work. Let's merge this one and address other number representations in new PR.

@Hywan Hywan merged commit 17e1471 into tagua-vm:master Aug 9, 2016
@Hywan Hywan removed the in progress label Aug 9, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants