nl2br in PHP suddenly doesn't work anymore - php

I noticed that one of my scripts wasn't working anymore, and started investigating. Eventually it boiled down to nl2br() not working anymore. Check out what results I get from a test script:
nl2br("asd",true): NULL
nl2br("asd",false): NULL
nl2br("asd"): string(3) "asd"
If the second parameter is specified, it returns NULL. WTF? The PHP installation on that box hasn't been touched in ages, it's an aging 5.2.6 on Apache2. Why has it stopped working all of a sudden?

Optional second parameter was added in 5.3.0

The second parameter has been added in 5.3.
My best guess: PHP interprets your comma as the comma operator, not as a delimiter for params, so it evaluates the expression to true or false instead of the string and that gets sent to the nl2br function.

Related

String exectuion without a function

One of my website was hacked, during the cleanup process I found a few files with some cryptic code. Doing a bit of research I found that a piece of string was getting executed without being passed to a function. I am a bit stumped as to how PHP is executing that string? Does PHP automatically eval strings?
Here's a piece of the string I found $VCAzeJzvMaKiJXvfeJZd='99V38=jVN4C;.Z<'^'ZK3RLX50;Z OG5R'; when I add it to a test script as below it produces create_function:
<?php
echo $VCAzeJzvMaKiJXvfeJZd='99V38=jVN4C;.Z<'^'ZK3RLX50;Z OG5R';
// output : create_function
P.S: in the malicious file I found, there's no echo, just a long cryptic string. I added echo in the code above for test purpose.
No, strings don't automagically get eval'ed, in this case it's actually 2 strings being bitwise Xor'd. Note the ^ between the 2 strings.

json_encode() turn non-UTF8 strings into null, but on live site returns false

In the framework I have to use for a project (Lithium) the output on a specific page goes through json_encode(). Locally and on live I try with one and the same data, and the result is:
Locally it returns the JSON, but some of the values are turned into null.
Live site - it returns false.
In both cases when I run json_last_error() - it gives me int(5). I can run phpinfo() on both places, if some setting is causing the problem.
(Locally I'm with PHP 5.3.*, on live it's 5.5.9.)
Actually you need to use optional parameters of json_encode in case of UTF8 characters
So You can use
JSON_UNESCAPED_UNICODE
option of
JSON_ENCODE
Example:
json_encode($array, JSON_UNESCAPED_UNICODE)
Visit php documentation here.
Although this is not documented on the version log here, non-UTF8 handling behaviour has changed in 5.5, in a way that can make debugging difficult.
Passing a non UTF-8 string to json_encode() will make the function return false in PHP 5.5, while it will only nullify this string (and only this one) in previous versions.
In a Latin-1 encoded file, write this:
$a = array('é', 1);
var_dump(json_encode($a));
PHP < 5.4: string(8) "[null,1]"
PHP >= 5.5: bool(false)
PHP 5.5 has it right of course (if encoding fails, return false) but its likely to introduce errors when updating to 5.5 because previously you could get the rest of the JSON even when one string was not in UTF8 (if this string wasn't used, you'd never notify it's nulled)
Finally - I used a slightly modified version of this gist - http://gist.github.com/oscar-broman/3653399 - but instead of encoding properties - I'm removing all the non-UTF8 strings ... and it's working. But - I had to modify the PHP framework the website is using ... and this is something I was really trying to avoid ... ... ... ... but anyway, this approach does the job for now :) ...
I get the same error with PhP 7.3.
You can fix it in multiple ways :
Ignore no-UTF8 char
json_encode(array("a" => "ç"), JSON_INVALID_UTF8_IGNORE);
This solution is fine if you just want to ignore all possible strange caractere, without trying to show them.
Replace no-UTF8 char
json_encode(array("a" => "ç"), JSON_INVALID_UTF8_SUBSTITUTE);
This is possible, but in my case I was getting "?" result.
UTF8-ize char
json_encode(array("a" => utf8_encode("ç")));
I'm using this solution which just convert into UTF8 format all char.

json_decode thinks a normal string is valid

Seems my old server this would return NULL or false...the new server returns the value, weird.
var_dump(json_decode("this is a normal string, not JSON"));
Output:
string(33) "this is a normal string, not JSON"
Expected:
NULL
You have not really formulated a question, but I try to answer it anyway:
Every software contains bugs. That's normal. We share the code, we share the bugs. What you ask about is a reported and fixed software flaw in PHP. Upgrade your PHP version or live with the bug.

PHP 5.4's simplified string offset reading

As many of you already know, PHP 5.4 alpha has been released. I have a question regarding the following.
Simplified string offset reading.
$str[1][0] is now a legal construct.
How exactly does $str[1][0] work?
EDIT: http://php.net/releases/NEWS_5_4_0_alpha1.txt
It just means that when reading a string offset PHP returns a string again, on which you again can access an offset. (And on that access yet another offset. It gets funny with $str[0][0][0][0][0][0])
Before PHP 5.4 you would get an "Cannot use string offset as an array" error.
This is a side effect, and was mentioned in the proposal here:
http://php.markmail.org/thread/yiujwve6zdw37tpv
The feature is speed/optimization of string offsets.
Hi,
Recently I noticed that reading of
string offset is performed in two
steps. At first special string_offset
variant of temporary_variable is
created in
zend_fetch_dimension_address_read()
and then the real string value is
created in
_get_zval_ptr_var_string_offset().
I think we can create the real string
in the first place. This makes 50%
speed-up on string offset reading
operation and allows to eliminate some
checks and conditional brunches in VM.
The patch is attached (don't forget to
regenerate zend_vm_execute.h to test
it). However it changes behavior in
one bogus case. The following code now
will emit "b" (currently it generates
a fatal error - cannot use string
offset as an array).
$str = "abs";
var_dump($str[1][0]);
I think it's not a problem at all. "b"
makes sense because "abs"[1] -> "b"
and "b"[0] -> "b".
I'm going to commit the patch in case
of no objections.
Thanks. Dmitry.
This can actually create some interesting bugs when you upgrade code from php 5.3 to 5.4.
In 5.3 this construct would return false:
$array = array("This is a string");
echo isset($array[0][0][0]);
In 5.4 this would return true.

why I still don't get an empty array?

Quoted from here:
If delimiter contains a value that is
not contained in string and a negative
limit is used, then an empty array
will be returned, otherwise an array
containing string will be returned.
But why I still don't get an empty array?
var_dump(explode(',', '', -1))
I get this:
array(1) {
[0]=>
string(0) ""
}
UPDATE
Try it in windows,with PHP 5.2.8 (cli) (built: Dec 8 2008 19:31:23)
I can confirm that this doesn't work in PHP 5.2.8.
It does work in PHP 5.2.11. In my opinion, there are many bugs in the 5.2 branch, so try always to use the latest version. 5.3 is more stable in my experience.
I've tried this example and got empty array. Wrong question.
Tested your code, and it does return an empty array: array(0) { }.
Running PHP 5.2.11.
Maybe there's an issue with your PHP version. Can you tell us which one you are running?

Categories