php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #19733 hexdec() returns floats when supplied string begins with '0'
Submitted: 2002-10-03 05:33 UTC Modified: 2002-10-03 21:29 UTC
From: andy at vegebyte dot co dot uk Assigned:
Status: Closed Package: Math related
PHP Version: 4.2.3 OS: Windows 2000
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: andy at vegebyte dot co dot uk
New email:
PHP Version: OS:

 

 [2002-10-03 05:33 UTC] andy at vegebyte dot co dot uk
hexdec('012345') should return int(74565), but instead it returns float(74565), contrary to the documentation. This happens for all numbers in strings I've tested that begin with 0, which does not include non-hexadecimal characters which are taken to be 0, eg, hexdec('q12345') returns int.

(Fixing the problem by casting the result to an (int) works fine. It originally catched me out when I used array_flip on an array of results, which demands integer or string keys.)

I'm not sure what the configure line is, but it's just a regular install from the downloaded executable binary, with no extra modules loaded. Since maths functions are in the PHP core, it hopefully won't matter.

Thanks
Andrew Alderwick, United Kingdom

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-10-03 08:05 UTC] mfischer@php.net
Interesting catch.

The relevant code looks as following:
    for (i = Z_STRLEN_P(arg); i > 0; i--) {
        c = *s++;

        digit = (c >= '0' && c <= '9') ? c - '0'
            : (c >= 'A' && c <= 'Z') ? c - 'A' + 10
            : (c >= 'a' && c <= 'z') ? c - 'a' + 10
            : base;

        if (digit >= base)
            continue;

        switch (mode) {
        case 0: /* Integer */
            onum = num;
            num = num * base + digit;

            fprintf(stderr, "num = %d, onum = %d\n", num, onum);
            if (num > onum)
                break; /* No overflow, continue */

            fnum = onum;
            mode = 1;
            /* fall-through */
        case 1: /* Float */
            fnum = fnum * base + digit;
        }
    }


from ext/standard/math.c ( _php_math_basetozval ).

This code assumed that an overflow also occured when the newer 'num' == 'onum'. "A" fix would be to change the comparison to be ">=" instead of ">" .

But I don't know the code well enough, someone else needs to check this toroughly.
 [2002-10-03 21:29 UTC] sas@php.net
Fixed in CVS. There were also a number of other issues regarding overflow detection which have been addressed now.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 07:01:28 2024 UTC