0

Ok I find this very weird but there should be an explanation. Here is what happens.

This code here should echo nothing:

$str = '[email protected]';
$key = '11111';
echo strpos($str, $key);
exit;

.. and yes this is exactly what I get, nothing. But !! If I am to use the $key (which contains a string) as an actual key of an array:

$str = '[email protected]';
$arr = array('11111' => 'test');
foreach ($arr as $key => $val)
{
    echo 'String: '.$str.'<br>';
    echo 'Key: '.$key.'<br>';
    echo 'Found at position: '.strpos($str, $key);
}
exit;

I get this amazing, magical result:

String: [email protected]
Key: 11111
Found at position: 2

So what php found here was the string 11111 to be the letter g But what is even more amazing, is that the number of digits changes the result:

$str = '[email protected]';
$arr = array('111' => 'test');
foreach ($arr as $key => $val)
{
    echo 'String: '.$str.'<br>';
    echo 'Key: '.$key.'<br>';
    echo 'Found at position: '.strpos($str, $key);
}
exit;

This one gives:

String: [email protected]
Key: 111
Found at position: 9

Any experts on this ? Thank you.

EDIT: This is actual code example used in my project which gives such false positives:

$email = '[the email of the user here]';
$arr = array(
    // [...]
    '11111' => 'Banned',
    '22222' => 'Banned',
    '33333' => 'Banned',
    // [...]
);
foreach ($arr as $key => $reason)
{
    if (strpos($email, (string)$key) !== false)
    {
        return 'Keyword: '.(string)$key.' found in the user Email address with reason: '.(string)$reason;
    }
}

So even using the (string) in front of the variable $key it bans innocents at the login form

1

1 Answer 1

1

use this, It will work fine. I type casted $key into string. PHP function strpos for matching substring with in the string, not the integer value. If you look into the documentation, it is clearly mentioned

Second parameter: If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.

<?php
ini_set('display_errors', 1);
$str = '[email protected]';
$arr = array('11111' => 'test');
foreach ($arr as $key => $val)
{
    echo 'String: '.$str.'<br>';
    echo 'Key: '.$key.'<br>';
    echo 'Found at position: '.strpos($str, (string)$key);
}
Sign up to request clarification or add additional context in comments.

9 Comments

thanks for your answer, well this is exactly what I am doing in my project's code loop but it still hits this false positive. So again, the question is, WHY is this happening without or even WITH the (string) before the $key ? It is funny !
@durduvakis Please check my current code, if it is still not working, then please share that code in your post which is not working.
If you notice it is a string once it is in single quotes.
yes i see,but in itself strpos is treating it as integer, so if you type cast it into string It will start working the way you want.
right, give me a moment to find my code exactly at that point which banned a user an hour ago due to this false positive.
|

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.