0

This caught me by surprise. The code

$strA = '1234';
$strB = '56';
$cast = (int) $strA.$strB;
var_dump($cast);

outputs: string(6) "123456"

I was expecting $cast to be an integer. This behavior might cause a security hole if someone were putting together strings from $_POST. The code

$strA = '1234';
$strB = '56-SQL Injection';
$cast = (int) $strA.$strB;

outputs: string(20) "123456-SQL Injection"

If $strB were from an external source like $_POST; the script might be open to an injection attack.

I've been reading posts like the difference between (int) and intval() trying to find out where this full behavior of (int) is documented.

So my question is: I was expecting "(int) $strA.$strB" to be an integer. Why is it still a string and where is this behavior documented?

Community
  • 1
  • 1
  • 2
    parentheses! `(int) "abc"."def"` is not the same as `(int) ("abc"."def")`, but the same as `((int) "abc")."def"` - oh, and by the way: to prevent SQL Injection, use **parameterized statements only!** – Franz Gleichmann Jan 30 '17 at 21:10
  • 1
    Exactly - operator precendence: http://php.net/manual/en/language.operators.precedence.php – nibnut Jan 30 '17 at 21:12
  • @FranzGleichmann you can definitely write an answer) – u_mulder Jan 30 '17 at 21:15

1 Answers1

1

The behaviour is caused by operator precedence, see also the corresponding manual page.

basically:

(int) $a.$b;

is not the same as

(int) ($a.$b); //which is the one you want

but the same as

((int) $a).$b;

which in your case casts $a to an int, which is valid, which then is implicitely cast back to string to concatenate with $b.
(for non-numeric strings, for example $a="b", this would result in the final string "0456")

see this example output:

<?php
$a = "123";
$b = "456";
$c = (int) $a.$b;
$d = (int) ($a.$b);
$e = ((int) $a).$b;
var_dump($c, $d, $e);

string '123456' (length=6)
int 123456
string '123456' (length=6)

Also: unless you absolutely can not, always use parameterized statements to prevent SQL Injection - they are as close to foolproof as possible.

Franz Gleichmann
  • 3,420
  • 4
  • 20
  • 30
  • Thanks. I admit I had pretty much figured out the answer before asking the question. (int) behaves like an operator. It has an unexpectedly high order of precedence. – Kevin Delaney Jan 30 '17 at 22:54