2

I just upgraded to php 8.1 from 7.3 and going through to resolve a handful of stuff that broke. One message that pops up is "PHP Deprecated: addslashes()". We use the command quite a bit, and it's not to prevent mysql injections. We have to deal with names that could have special characters in them ' ~ etc.

But when I check out https://www.php.net/manual/en/function.addslashes.php it says that it is supported in PHP8.

Sorry, I guess the newb in me... but what am I missing? If it's out, ok, what is the supported way for dealing with it now?

Update to add code example and question clarification

Now that I've slept on it, I see it's not a deprecation error on addslashes(). It's an error saying that the value that we are passing into the function is NULL. And I see in the docs this is no longer allowed as of 8.1.

So based on that information what is the new and improved way handle the example below.

$(function () {
$('.adminheader').html('<?php addslashes(GetMainEventNames()); ?>');
$('.maineventbuttons').button().each(function () {
  var MainEventCode = $(this).attr('data-code');
          $(this).click(function () {
            ChangeLocalActiveStatus(MainEventCode);
          });
      });

Error Message

PHP Deprecated:  addslashes(): Passing null to parameter #1 ($string) of type string is deprecated in....
Matt Winer
  • 495
  • 9
  • 26
  • 5
    `addslashes()` has never been the right tool for any job. If you can provide an example of where you're using it, I guarantee I (or somebody else here) can provide a better alternative – Phil Mar 02 '22 at 04:38
  • 2
    Can you share an example of the error message in full? `addslashes()` has not been marked for deprecation as you noted and there's no errors here ~ https://3v4l.org/TFMoY#v8.1.3 – Phil Mar 02 '22 at 04:43
  • added examples, error messages and I see now it's not about addslashes being deprecated. It's that the value cannot be null. – Matt Winer Mar 02 '22 at 14:29
  • 2
    `addslashes` is, as Phil said, the wrong tool for the job here. `json_encode` would make more sense. – Quentin Mar 02 '22 at 15:14
  • "Passing null to parameter #1 (...) is deprecated" - why not fix that? – Nico Haase Mar 02 '22 at 15:54
  • @Quentin why json_encode? I think the method where the php output is being used takes an html string – Don't Panic Mar 02 '22 at 16:08
  • 1
    @Don'tPanic — It's generating a JavaScript string. The JavaScript then generates HTML from it. – Quentin Mar 02 '22 at 16:17

2 Answers2

4

So your PHP function GetMainEventNames() is returning null at least sometimes. Is this expected or desired behaviour? If it is then there are two possible solutions. One is for your function to check if the return value is null and return an empty string instead. The other is to use the null coalescing operator inside your addslashes() function like this:

<?php addslashes(GetMainEventNames() ?? ''); ?>
Martin
  • 22,212
  • 11
  • 70
  • 132
mark_b
  • 1,393
  • 10
  • 18
-2

Addslashes is never the right answer

to address your specific code,

$('.adminheader').html('<?php addslashes(GetMainEventNames()); ?>');

should be replaced with

$('.adminheader').html(<?php echo json_encode(htmlentities(GetMainEventNames(), ENT_QUOTES|ENT_SUBSTITUTE|ENT_DISALLOWED),JSON_THROW_ON_ERROR); ?>);

and generally speaking,

if you need to escape HTML, it's (unfortunately)

echo htmlentities($html, ENT_QUOTES|ENT_SUBSTITUTE|ENT_DISALLOWED);

if you need to quote shell arguments, it's

$cmd.= " --file=" . escapeshellarg($arg);

if you need to quote SQL strings it's

$sql.= "WHERE col = '".$mysqli->real_escape_string($str)."'";

or

$sql.= "WHERE col = " . $pdo->quote($str);

if you need to quote javascript/json strings its

let str = <?=json_encode($str, JSON_THROW_ON_ERROR);?>;

if you need to quote a string in xpath it's

//based on https://stackoverflow.com/a/1352556/1067003
function xpath_quote(string $value):string{
    if(false===strpos($value,'"')){
        return '"'.$value.'"';
    }
    if(false===strpos($value,'\'')){
        return '\''.$value.'\'';
    }
    // if the value contains both single and double quotes, construct an
    // expression that concatenates all non-double-quote substrings with
    // the quotes, e.g.:
    //
    //    concat("'foo'", '"', "bar")
    $sb='concat(';
    $substrings=explode('"',$value);
    for($i=0;$i<count($substrings);++$i){
        $needComma=($i>0);
        if($substrings[$i]!==''){
            if($i>0){
                $sb.=', ';
            }
            $sb.='"'.$substrings[$i].'"';
            $needComma=true;
        }
        if($i < (count($substrings) -1)){
            if($needComma){
                $sb.=', ';
            }
            $sb.="'\"'";
        }
    }
    $sb.=')';
    return $sb;
}
$xp->query('/catalog/items/item[title='.xpath_quote($var).']');

if you need to quote strings in CSS its

// CSS escape code ripped from Zend Framework ( https://github.com/zendframework/zf2/blob/master/library/Zend/Escaper/Escaper.php )
function css_escape_string($string)
{
    $cssMatcher = function ($matches) {
        $chr = $matches[0];
        if (strlen($chr) == 1) {
            $ord = ord($chr);
        } else {
            $chr = mb_convert_encoding($chr, 'UTF-16BE', 'UTF-8'); // $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8');
            $ord = hexdec(bin2hex($chr));
        }
        return sprintf('\\%X ', $ord);
    };
    $originalEncoding = mb_detect_encoding($string);
    if ($originalEncoding === false) {
        $originalEncoding = 'UTF-8';
    }
    ;
    $string = mb_convert_encoding($string, 'UTF-8', $originalEncoding); // $this->toUtf8($string);
                                                                        // throw new Exception('mb_convert_encoding(\''.$string.'\',\'UTF-8\',\''.$originalEncoding.'\');');
    if ($string === '' || ctype_digit($string)) {
        return $string;
    }
    $result = preg_replace_callback('/[^a-z0-9]/iSu', /*$this->*/$cssMatcher, $string);
    // var_dump($result);
    return mb_convert_encoding($result, $originalEncoding, 'UTF-8'); // $this->fromUtf8($result);
}


at no point is addslashes ever the right answer, and (mis)using it can lead to security exploits.

hanshenrik
  • 19,904
  • 4
  • 43
  • 89