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
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
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-2021 The PHP Group
All rights reserved.
Last updated: Sun Nov 28 00:03:13 2021 UTC