Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: String#to_i to avoid future overflow #7172

Merged
merged 1 commit into from
Dec 11, 2018

Conversation

bcardiff
Copy link
Member

This is a small refactor on String#to_i methods.

Before this PR when parsing the minimum negative value (eg: -128 for Int8) the code will first convert the UInt64 absolute value to a Int8 and then return it with opposite sign.

The positive 128 is not a valid Int8 so we should change the conversion to use 2's complement.

First compute the binary Int64 representation of negative number to return, cast it as Int64 and then narrow its type to the expected one.

Copy link
Member

@asterite asterite left a comment

Choose a reason for hiding this comment

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

Can a spec be added for this?

@bcardiff bcardiff mentioned this pull request Dec 10, 2018
@bcardiff bcardiff force-pushed the refactor/string-to-i branch from 78301e0 to 06f344b Compare December 10, 2018 18:59
@bcardiff
Copy link
Member Author

@asterite done

@@ -497,7 +497,7 @@ class String
if info.negative
{% if max_negative %}
return yield if info.value > {{max_negative}}
-info.value.to_{{method}}
(~info.value &+ 1).unsafe_as(Int64).to_{{method}}
Copy link
Contributor

Choose a reason for hiding this comment

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

What does ~ mean? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

It's Int#~:

  def ~
    self ^ -1
  end

Source: int.cr

Copy link
Member Author

Choose a reason for hiding this comment

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

@vladfaust it's inverting bits to perform https://en.wikipedia.org/wiki/Two%27s_complement

Sample:

00000011 ( 3. info.value)   
11111100 (-4. ~info.value)
11111101 (-3. ~info.value &+ 1)

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, @z64, @bcardiff

Copy link
Member

Choose a reason for hiding this comment

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

This method could use some API docs.

@bcardiff bcardiff merged commit 5a3f04c into crystal-lang:master Dec 11, 2018
@bcardiff bcardiff added this to the 0.27.1 milestone Dec 11, 2018
@bcardiff bcardiff deleted the refactor/string-to-i branch December 12, 2018 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants