0

After execute this simple code:

$message = 'some text '.inet_pton('119.252.33.171');
throw new \Exception($message);

PHP returns Fatal Error

Fatal error</b>: in ...

This code is expected to return

Fatal error: Uncaught Exception: ..

But this is not happening. With this message, the error occurs in the class "Exception"!

Code example 1 from sandbox.onlinephpfunctions.com (comment and uncomment 2 lines of code 3-4 and 6-7)

Code example 2 from sandbox.onlinephpfunctions.com

This behavior is noticed when converting many other IPs. At the moment I solved the problem with the following line before "throw new":

$message = preg_replace( '/[^[:print:]\r\n]/', '_', $message);

How to properly escape characters in message for Exception or it is PHP bug?

My PHP version is 7.2

8
  • Your title and your question don't match and confusing, when you throw an Exception, of cause it will cause a Fatal error. Did you catch the Exception? Commented Feb 7, 2019 at 23:49
  • No, because the error message 'some text '.inet_pton('119.252.33.171'); itself causes an error in the Exception class. Run my example on your hosting and look at the result. Commented Feb 7, 2019 at 23:57
  • I can't reproduce that error with just the inet_pton call. Are you sure that's the cause of the exception? Commented Feb 8, 2019 at 0:02
  • 1
    @Miron Are you sure about the fatal error? Doesn't happen on my 7.2.11 with display_errors set and E_ALL. What's the exact message for the fatal error? Commented Feb 8, 2019 at 0:03
  • <br /> <b>Fatal error</b>: in <b>...</b> on line <b>92</b><br /> Commented Feb 8, 2019 at 0:08

2 Answers 2

1

That would be because inet_pton() is not meant to ouput strings, but bytes in network order (I don't remember if it's little endian or big endian).

Exception messages are not meant to include bytes, but printable characters. You can, however, put pure bytes into strings. These are then decoded to (probably) UTF-8 or other encoding to display readable text.

The following code

$message = inet_pton('119.252.33.171');
var_dump($message);
for($i = 0; $i < strlen($message); $i++)
{
   echo ord($message[$i]) . "\n";
}

Produces

string(4) "w�!�"
119
252
33
171

Compare these two lines

throw new \Exception(chr(33)); // Displays stacktrace
throw new \Exception(chr(252)); // Fails to output

My guess would be that an error occurs while PHP is trying to format the string as UTF-8 to print the exception message to stdout, but invalid UTF-8 string is passed in and the write/decoding fails.

Either way, seems like a bug in PHP.

Sign up to request clarification or add additional context in comments.

1 Comment

So this is the PHP error - it is true. Only in your example is better to use mb_ord().
0

You are using inet_pton() incorrectly because this is what it does:

inet_pton — Converts a human readable IP address to its packed in_addr representation

You should append the address to the string without calling inet_pton().

Now, about the error.

The error doesn't occur in all my PHP setups, from 5.5.12 to 7.2.8. This is the error message I got from PHP 5.5.12:

Fatal error: Uncaught exception 'Exception' with message 'some text wü!«' in C:\wamp\www\so\54584039.php:5 Stack trace: #0 {main} thrown in C:\wamp\www\so\54584039.php on line 5

I got the same "Uncaught exception" error from other versions, confirmed by https://3v4l.org/Klpep.

This means that the error must be caused by a post-processing of the Exception message that occurs in your PHP setup but does not occur in 3v4l.org's setup and mine.

It occurred to me that a possible culprit is the html_errors configuration option. I set it to On to find out what's going to happen and sure enough, I got your error:

<br />
<b>Fatal error</b>:   in <b>C:\wamp\www\so\54584039.php</b> on line <b>5</b><br />

Thus, the solution is to set your html_errors to Off.

I highly recommend that you set it to Off always, because if you're working on a JSON output (or other formats) the HTML formatting is useless and it also makes the error message harder to read.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.