rfc:throw_error_for_invalid_characters_for_number_base

PHP RFC: Throw ValueError for invalid characters in number base functions

Introduction

Functions that convert numbers from one base to another (bindec(), octdec(), hexdec(), and base_convert()) accept a string representation of a number and convert it. Historically, these functions have been very lenient with their inputs, silently ignoring characters that are invalid for the specified number base.

For example, hexdec('z') treats z as an invalid character, silently ignores it, and returns int(0).

In PHP 7.4, an RFC titled Base Convert Improvements introduced a deprecation notice (E_DEPRECATED) when invalid characters are passed to these functions, with the intention of eventually turning it into an exception in PHP 8. While the deprecation notice was successfully implemented, the exception step was never completed.

This RFC proposes to complete that transition by throwing a ValueError when invalid characters are passed to bindec(), octdec(), hexdec(), and base_convert(), starting in PHP 8.7.

Proposal

We propose changing the behavior of bindec(), octdec(), hexdec(), and base_convert() when they encounter characters that are invalid within the context of the requested number base. Instead of emitting a deprecation notice and returning a partial/fallback conversion, these functions will immediately throw a ValueError.

Affected functions:

  • bindec() - Binary to decimal
  • octdec() - Octal to decimal
  • hexdec() - Hexadecimal to decimal
  • base_convert() - Convert a number between arbitrary bases

Examples

Simple example:

<?php
var_dump(hexdec('z'));
 
// PHP 7.4 - 8.6:
// Deprecated: Invalid characters passed for attempted conversion, these have been ignored in ...
// int(0)
 
// PHP 8.7 (Proposed):
// Fatal error: Uncaught ValueError: hexdec(): Argument #1 ($hex_string) has invalid characters for attempted conversion in ...
?>

Error in base_convert depends on the number base:

<?php
base_convert('f', 16, 10);
// 'f' is valid base 16, so no error
 
base_convert('f', 15, 10);
// Fatal error: Uncaught ValueError: base_convert(): Argument #1 ($num) has invalid characters for attempted conversion in ...
?>

Backward Incompatible Changes

Code that relies on the legacy behavior of silently ignoring invalid characters (or catching the current E_DEPRECATED notice) will experience behavior changes. If invalid characters are passed, a ValueError will now be thrown, which must be handled using try/catch blocks if invalid inputs are expected from untrusted sources.

Impact

Code that currently relies on the lenient behavior of these functions will fail. I can imagine that legitimate use is primarily having separators in input strings: hexdec('1234-5678'). First, this already throws a deprecation warning since PHP 7.4. Second, this is easily solved with normal string manipulation functions.

Proposed PHP Version(s)

PHP 8.7

Future Scope

Other string-to-number or decoding functions (such as base64_decode(), intval(), etc.) are currently unaffected by this change.

Voting Choices

Vote: Throw a ValueError for invalid characters in number base conversion functions (bindec, octdec, hexdec, base_convert) in PHP 8.7? (Yes / No)


Primary Vote requiring a 2/3 majority to accept the RFC:

Throw a ValueError for invalid characters in number base conversion functions?
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.

Patches and Tests

Implementation

After the RFC is implemented, this section should contain:

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Links to external references, discussions, or RFCs.

Rejected Features

Keep this updated with features that were discussed on the mail lists.

Changelog

If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.

rfc/throw_error_for_invalid_characters_for_number_base.txt · Last modified: by sjoerd