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

32bit integer overflow in stdlib_io_npy_save.fypp and load.fypp #647

Closed
degawa opened this issue Apr 6, 2022 · 1 comment · Fixed by #655
Closed

32bit integer overflow in stdlib_io_npy_save.fypp and load.fypp #647

degawa opened this issue Apr 6, 2022 · 1 comment · Fixed by #655
Labels
bug Something isn't working

Comments

@degawa
Copy link
Contributor

degawa commented Apr 6, 2022

When compiling stdlib using NAG Fortran compiler 7.0 for Windows on Windows 10, it terminates compiling with the error "Integer (KIND=3) overflow" (KIND=3 corresponds to int32 in NAG Fortran).
Errors are detected in to_bytes_i4 in stdlib_io_npy_save.fypp and in get_descriptor in stdlib_io_npy_load.fypp .

In the procedures, the integer literal 2**32 is used in expressions as below:

str = achar(mod(val, 2**8)) // &
& achar(mod(val, 2**16) / 2**8) // &
& achar(mod(val, 2**32) / 2**16) // &
& achar(val / 2**32)

if (major > 1) then
header_len = ichar(buf(1)) &
& + ichar(buf(2)) * 2**8 &
& + ichar(buf(3)) * 2**16 &
& + ichar(buf(4)) * 2**32
else
header_len = ichar(buf(1)) &
& + ichar(buf(2)) * 2**8
end if

I guess that 2**24 is probably correct instead of 2**32.

I have understood that to_bytes_i4 converts an integer to a byte string by converting a 32 bit decimal integer to a base-256 number and then to four ASCII characters.
In this case, the power of base number (=256) at each position are (256**0, 256**1, 256**2, 256**3), corresponding to (2**0, 2**8, 2**16, 2**24).

This consideration does not cover negative integers, but if my understanding is correct, the concerning expressions can be modified as follows:

        str = achar(mod(val, 256**1)) // &
            & achar(mod(val, 256**2) / 256**1) // &
            & achar(mod(val, 256**3) / 256**2) // &
            & achar(val / 256**3)

and

        if (major > 1) then
            header_len = ichar(buf(1)) &
                &      + ichar(buf(2)) * 256**1 &
                &      + ichar(buf(3)) * 256**2 &
                &      + ichar(buf(4)) * 256**3
        else
            header_len = ichar(buf(1))  &
                &      + ichar(buf(2)) * 256**1
        end if

If using 2**32 is a trick to handle negative integers, I need another solution to compile stdlib using NAG Fortran compiler.

@awvwgk awvwgk added the bug Something isn't working label Apr 18, 2022
@awvwgk
Copy link
Member

awvwgk commented Apr 18, 2022

I think the proposed patch looks fine. Feel free to open a pull request and we can include it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants