Simple Machines Community Forum

SMF Support => SMF 2.0.x Support => Topic started by: s3cc0 on January 14, 2017, 12:11:30 PM

Title: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: s3cc0 on January 14, 2017, 12:11:30 PM
Hello. Are the spiders being shown in the online user list of your forum?

On my forum they are no longer shown after upgrading to 2.0.12, and the problem persist now in 2.0.13.

Those are the settings:

(https://s29.postimg.org/jjbm4zdqv/capture.png)

Can anybody confirm this feature is still working in 2.0.12/2.0.13? I'm trying to figure if this is a problem on my side or a bug introduced with the last patches.



Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: lurkalot on January 14, 2017, 01:27:49 PM
Working in all my sites, and they have the same settings as in your screen shot. All running SMF 2.0.13
Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: s3cc0 on January 14, 2017, 07:03:51 PM
Ok. Then the problem is on my side. I did some research and probably discovered where the problem could be...

First I noticed an error appearing after the update:

Quotehttp://bitcoingarden.org/forum/index.php?action=whoApply Filter: Only show the errors with the same message2: Invalid argument supplied for foreach()Apply Filter: Only show the errors from this file File: /home/fb/domains/bitcoingarden.org/public_html/forum/Sources/Who.php
Line: 227

The line erroring is:

Quoteforeach (safe_unserialize($modSettings['spider_name_cache']) as $id => $name)

Now I had a look at the changelog between 2.0.11 and 2.0.12 and I noticed the serialize function has been completely rewritten. The new function is the safe_unserialize mentioned above.

I think something changed in the way the function manages the data; it looks like the new function crashes processing the spider_name_cache array, while the old serialize was handling it with no problems.

This makes sense as in the past I enriched the list of bots to include something like 400 bots. (see below)

(https://s24.postimg.org/mtaketpdx/capture.png)

I'm trying to figure which record is causing the problem. I tried to delete the ones containing weird chars like %, ! and stuff like that, but no luck. I'm a bit lost...

1) Maybe the array is just too long? I don't think it should...

2) Maybe there's a forbidden keyword in the bot list? Wasn't the function re-written to avoid sql injection hacks?

3) Maybe I copy-pasted a non standard char?

Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: Arantor on January 15, 2017, 03:23:11 AM
Add another one, then remove it.
Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: s3cc0 on January 15, 2017, 06:02:37 AM
Quote from: Arantor on January 15, 2017, 03:23:11 AM
Add another one, then remove it.

Test done. Added a new one, removed it after 20 minutes. Nothing changed.
Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: Arantor on January 15, 2017, 06:08:28 AM
I would wonder if the 2.0.13 patch was applied correctly. 2.0.12 would definitely have aborted on your list of spiders since it caps serialised arrays to 256 items and you have 400 but that should be rectified in 2.0.13.
Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: s3cc0 on January 15, 2017, 07:19:53 AM
Quote from: Arantor on January 15, 2017, 06:08:28 AM
I would wonder if the 2.0.13 patch was applied correctly. 2.0.12 would definitely have aborted on your list of spiders since it caps serialised arrays to 256 items and you have 400 but that should be rectified in 2.0.13.

I think the 2.0.13 update was applied correctly. All tests were successful and the update completed regularly.
Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: Arantor on January 15, 2017, 07:23:52 AM
Take a look at Subs.php and specifically at the safe_unserialise function as to whether there's a test early on for the length of string over 4096 as a first check.
Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: s3cc0 on January 15, 2017, 08:18:09 AM
This is how the safe_unserialize function looks like. I'm not much skilled in PHP. I see a check for empty string at the very begin but I don't think there's a check for strings over 4096 bytes.

function _safe_unserialize($str)
{
// Input  is not a string.
if(empty($str) || !is_string($str))
return false;

$stack = array();
$expected = array();

/*
* states:
*   0 - initial state, expecting a single value or array
*   1 - terminal state
*   2 - in array, expecting end of array or a key
*   3 - in array, expecting value or another array
*/
$state = 0;
while($state != 1)
{
$type = isset($str[0]) ? $str[0] : '';
if($type == '}')
$str = substr($str, 1);

else if($type == 'N' && $str[1] == ';')
{
$value = null;
$str = substr($str, 2);
}
else if($type == 'b' && preg_match('/^b:([01]);/', $str, $matches))
{
$value = $matches[1] == '1' ? true : false;
$str = substr($str, 4);
}
else if($type == 'i' && preg_match('/^i:(-?[0-9]+);(.*)/s', $str, $matches))
{
$value = (int)$matches[1];
$str = $matches[2];
}
else if($type == 'd' && preg_match('/^d:(-?[0-9]+\.?[0-9]*(E[+-][0-9]+)?);(.*)/s', $str, $matches))
{
$value = (float)$matches[1];
$str = $matches[3];
}
else if($type == 's' && preg_match('/^s:([0-9]+):"(.*)/s', $str, $matches) && substr($matches[2], (int)$matches[1], 2) == '";')
{
$value = substr($matches[2], 0, (int)$matches[1]);
$str = substr($matches[2], (int)$matches[1] + 2);
}
else if($type == 'a' && preg_match('/^a:([0-9]+):{(.*)/s', $str, $matches) && $matches[1] < 256)
{
$expectedLength = (int)$matches[1];
$str = $matches[2];
}

// Object or unknown/malformed type.
else
return false;

switch($state)
{
case 3: // In array, expecting value or another array.
if($type == 'a')
{

$stack[] = &$list;
$list[$key] = array();
$list = &$list[$key];
$expected[] = $expectedLength;
$state = 2;
break;
}
if($type != '}')
{
$list[$key] = $value;
$state = 2;
break;
}

// Missing array value.
return false;

case 2: // in array, expecting end of array or a key
if($type == '}')
{
// Array size is less than expected.
if(count($list) < end($expected))
return false;

unset($list);
$list = &$stack[count($stack)-1];
array_pop($stack);

// Go to terminal state if we're at the end of the root array.
array_pop($expected);

if(count($expected) == 0)
$state = 1;

break;
}

if($type == 'i' || $type == 's')
{
// Array size exceeds expected length.
if(count($list) >= end($expected))
return false;

$key = $value;
$state = 3;
break;
}

// Illegal array index type.
return false;

// Expecting array or value.
case 0:
if($type == 'a')
{

$data = array();
$list = &$data;
$expected[] = $expectedLength;
$state = 2;
break;
}

if($type != '}')
{
$data = $value;
$state = 1;
break;
}

// Not in array.
return false;
}
}

// Trailing data in input.
if(!empty($str))
return false;

return $data;
}
Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: Arantor on January 15, 2017, 08:28:21 AM
Hmmm, that looks like it has been patched. I wonder how come it broke with (quite a bit) more data in it. I'd be sceptical about it being an invalid character though.
Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: s3cc0 on January 15, 2017, 12:30:39 PM
I finally sorted it out. I reduced the number of spiders at 250 and it is working fine now.

Tested again adding a few more spiders and the list disappeared again. List went back again once I removed them.

I'm not 100% if it is a matter of number of elements in the array (in my case limit is close to 256) or if it is a matter of total length of array in bytes. In any case, the problem was the list too long.

Thank you guys for helping me debug this.

Title: Re: 2.0.12 / 2.0.13 Spiders not shown in Online User List
Post by: THE BRA1N on January 30, 2017, 02:03:29 AM
Same issue here after updating to 2.0.12 and 13. I will try reducing the number of spiders to see if that works.

Edit - it worked!