PHP Warning: Illegal string offset [SOLVED]

Started by Krillin, February 19, 2021, 11:19:27 AM

Previous topic - Next topic

0 Members and 3 Guests are viewing this topic.

Krillin

First off, I am NOT a programmer, but I have no problem diving into anything when it comes to web code. But for a few weeks I have been tracking down a few unknown issues and I do not know where to get help except here.

I have researched the "PHP Illegal String Offset" and thought the offset was caused by an array set as an string. But the string is not set in the array for the savestate (see below). I have not started tracking down the 'trackID' issue yet. Savestate is really important function as it prevents log files from being run for player stats a second time. Saving the savestate in a database is a very dumb idea for those who have log files for every map change like in HL1 - CS or CZ or HL2 CS:S and CSGO game mods like we do. I am stuck and cannot find or figure out a solution for these issues.

Here are the problems I am trying to solve to get the new version out. There are two warnings issued with VSP 0.50 and PHP v7.3.27, this could also bring VSP into PHP 8.0.2 (I hope). I will test PHP 8 after this is solved first.

Quote from: VSP.PHP CLIPHP Warning:  Illegal string offset 'savestate' in vsp.php on line 979
here is line 979.
$V0f14082c['parser-options'][$V51d3ee44['argv'][$V363b122c]]=$V51d3ee44['argv'][$V363b122c+1];

Here is the function this traces to:
function F92261ca6()
{
    global $V51d3ee44;
    if (cIS_SHELL) {
        if (!isset($_SERVER['argc'])) {
            echo "Error: args not registered.\n";
            echo " register_argc_argv may need to be set to On in shell mode\n";
            echo " Please edit your php.ini and set variable register_argc_argv to On\n";
            F56fd05e9();
        }
        $V51d3ee44['argv']=$_SERVER['argv'];
        $V51d3ee44['argc']=$_SERVER['argc'];
    } else {
        $V4f96c5a0=$_POST['V70e78261'];
        if (get_magic_quotes_gpc()) {
            $V4f96c5a0=stripslashes($V4f96c5a0);
        }
        $V51d3ee44=F126ba7b1("vsp.php ".$V4f96c5a0);
    }
    global $V0f14082c;
    $V0f14082c['parser-options']="";
    $V0f14082c['prompt']=1;
    if ($V51d3ee44['argc']>1) {
        for ($V865c0c0b=1;$V865c0c0b<$V51d3ee44['argc']-1;$V865c0c0b++) {
            if (strcmp($V51d3ee44['argv'][$V865c0c0b], "-a")==0) {
                $V865c0c0b++;
                $V0f14082c['action']=$V51d3ee44['argv'][$V865c0c0b];
                if ($V0f14082c['action']!='clear_db') {
                    Facf3bf61("error: invalid action");
                }
                break;
            }
            if (strcmp($V51d3ee44['argv'][$V865c0c0b], "-n")==0) {
                $V0f14082c['prompt']=0;
                continue;
            }
            if ($V865c0c0b+1 > $V51d3ee44['argc']-2) {
                Facf3bf61("error: no value specified for option ".$V51d3ee44['argv'][$V865c0c0b]);
            }
            if (strcmp($V51d3ee44['argv'][$V865c0c0b], "-p")==0) {
                $V865c0c0b++;
                for ($V363b122c=$V865c0c0b;$V363b122c<$V51d3ee44['argc']-1;$V363b122c=$V363b122c+2) {
                    $V0f14082c['parser-options'][$V51d3ee44['argv'][$V363b122c]]=$V51d3ee44['argv'][$V363b122c+1]; //This is link 979
                }
                break;
            } elseif (strcmp($V51d3ee44['argv'][$V865c0c0b], "-c")==0) {
                $V865c0c0b++;
                $V0f14082c['config']=$V51d3ee44['argv'][$V865c0c0b];
            } elseif (strcmp($V51d3ee44['argv'][$V865c0c0b], "-l")==0) {
                $V865c0c0b++;
                $V0f14082c['log-gamecode']=$V51d3ee44['argv'][$V865c0c0b];
                $V0f14082c['log-gametype']='';
                if (preg_match("/(.*)-(.*)/", $V0f14082c['log-gamecode'], $Vb74df323)) {
                    $V0f14082c['log-gamecode']=$Vb74df323[1];
                    $V0f14082c['log-gametype']=$Vb74df323[2];
                    $V0f14082c['parser-options']['gametype']=$V0f14082c['log-gametype'];
                }
            } else {
                Facf3bf61("error: invalid option ".$V51d3ee44['argv'][$V865c0c0b]);
            }
        }
    } else {
        Facf3bf61("error: logfile not specified");
    }
    $V0f14082c['logfile']=$V51d3ee44['argv'][$V51d3ee44['argc']-1];
    if (!isset($V0f14082c['action'])) {
        if (!isset($V0f14082c['logfile'])) {
            Facf3bf61("error: logFile not specified");
        }
        if (!isset($V0f14082c['log-gamecode'])) {
            Facf3bf61("error: logType not specified");
        }
    }
    $V55d5b418="pub/configs/";
    if (!isset($V0f14082c['config']) || preg_match("/\\.\\./", $V0f14082c['config']) || !is_file($V55d5b418.$V0f14082c['config'])) {
        $V0f14082c['config']=$V55d5b418."cfg-default.php";
    } else {
        $V0f14082c['config']=$V55d5b418.$V0f14082c['config'];
    }
    echo "max_execution_time is ".ini_get("max_execution_time")."\n\n";
    echo "[command-line options]: ";
    print_r($V0f14082c);
    if (isset($V0f14082c['parser-options']['savestate']) && $V0f14082c['parser-options']['savestate']) {
        $Vb3521e13="writetest_".md5(uniqid(rand(), true));
        $V2880b5ba = fopen('./logdata/'.$Vb3521e13, "wb");
        if (!$V2880b5ba || !fwrite($V2880b5ba, "* WRITE TEST *\n")) {
            echo "Error: savestate 1 processing requires logdata/ directory to be writable.\n";
            echo " Enable write permissions for logdata/ directory (chmod 777)\n";
            F56fd05e9();
        }
        fclose($V2880b5ba);
        unlink("logdata/$Vb3521e13");
    }
}


I did a var_dump in the variable used in $V0f14082c and the savestate option is NOT in the array (and I am thinking it should be), the savestate option is in the variable $V51d3ee44[5]. The fact the savestate variable is NOT in $V0f14082c array has me concerned as this is supposed to be passed from parserOptions from the CLI, and the array prints out as "savestate => 0" when "savestate 1" was passed to vsp and I DO NOT know how to get the option in $V0f14082c.

var_dump($V0f14082c);
array(6) {
  'parser-options' =>
  string(1) "g"
  'prompt' =>
  int(1)
  'log-gamecode' =>
  string(2) "hl"
  'log-gametype' =>
  string(0) ""
  'logfile' =>
  string(6) "./logs"
  'config' =>
  string(27) "pub/configs/cfg-default.php"
}

var_dump($V51d3ee44);
array(2) {
  'argv' =>
  array(7) {
    [0] =>
    string(7) "vsp.php"
    [1] =>
    string(2) "-l"
    [2] =>
    string(2) "hl"
    [3] =>
    string(2) "-p"
    [4] =>
    string(9) "savestate"
    [5] =>
    string(1) "1"
    [6] =>
    string(6) "./logs"
  }
  'argc' =>
  int(7)
}

var_dump($V865c0c0b)
NULL

var_dump($V363b122c)
NULL


Quote from: VSP.PHP CLIPHP Warning:  Illegal string offset 'trackID' in vsp.php on line 1038
here is line 1038

$V0f14082c['parser-options']['trackID']=$GLOBALS['cfg']['parser']['trackID'];

Here is the function this traces back to:
function F68c076b3()
{
    global $V0f14082c;
    global $V51d3ee44;
    require_once($V0f14082c['config']);
    if (preg_match("/^ftp:\\/\\//i", $V0f14082c['logfile'])) {
        $V0f14082c['logfile']=Fd2c39001($V0f14082c['logfile']);
    }
    $V0f14082c['parser-options']['trackID']=$GLOBALS['cfg']['parser']['trackID']; // This is link 1038
    if (isset($GLOBALS['cfg']['db']['adodb_path'])) {
        $GLOBALS['cfg']['db']['adodb_path']=F9578dd1f($GLOBALS['cfg']['db']['adodb_path']);
    } else {
        $GLOBALS['cfg']['db']['adodb_path']=F9578dd1f(Ce5c65ec5).'pub/lib/adodb/';
    }
    require_once("{$GLOBALS['cfg']['db']['adodb_path']}".'adodb.inc.php');
    include_once("{$GLOBALS['cfg']['db']['adodb_path']}".'tohtml.inc.php');
    require_once("sql/{$GLOBALS['cfg']['db']['adodb_driver']}.inc.php");
    include_once("pub/include/playerBanList-{$GLOBALS['cfg']['player_ban_list']}.inc.php");
    foreach ($GLOBALS['player_ban_list'] as $V7fa3b767 => $V36190f8a) {
        $GLOBALS['player_ban_list'][$V7fa3b767]="/^".preg_quote($V36190f8a)."$/";
    }
    $GLOBALS['V9c1ebee8'] = &ADONewConnection($GLOBALS['cfg']['db']['adodb_driver']);
    global $V9c1ebee8;
    if (!$V9c1ebee8->Connect($GLOBALS['cfg']['db']['hostname'], $GLOBALS['cfg']['db']['username'], $GLOBALS['cfg']['db']['password'], $GLOBALS['cfg']['db']['dbname'])) {
        echo "Attempting to create/connect to database {$GLOBALS['cfg']['db']['dbname']}\n";
        $GLOBALS['V9c1ebee8'] = null;
        $GLOBALS['V9c1ebee8'] = &ADONewConnection($GLOBALS['cfg']['db']['adodb_driver']);
        global $V9c1ebee8;
        $V9c1ebee8->Connect($GLOBALS['cfg']['db']['hostname'], $GLOBALS['cfg']['db']['username'], $GLOBALS['cfg']['db']['password']);
        $V9c1ebee8->Execute($sql_create[0]);
        if (!$V9c1ebee8->Connect($GLOBALS['cfg']['db']['hostname'], $GLOBALS['cfg']['db']['username'], $GLOBALS['cfg']['db']['password'], $GLOBALS['cfg']['db']['dbname'])) {
            echo " - failed to create/connect to database {$GLOBALS['cfg']['db']['dbname']}\n";
            F56fd05e9();
        }
        echo " - database created\n";
    }
    if (isset($V0f14082c['action']) && $V0f14082c['action']=="clear_db") {
        if (cIS_SHELL && $V0f14082c['prompt']) {
            echo "Are you sure you want to clear the database {$GLOBALS['cfg']['db']['dbname']} @ {$GLOBALS['cfg']['db']['hostname']}? (y/n)\n";
            Fa10803e1();
            $Vd0cf705f=Fd63c38c9();
        } else {
            $Vd0cf705f='y';
        }
        if ($Vd0cf705f=='y' || $Vd0cf705f=='Y') {
            foreach ($sql_destroy as $V7fa3b767 => $Vac5c74b6) {
                $V9c1ebee8->Execute($Vac5c74b6);
            }
            print "{$GLOBALS['cfg']['db']['table_prefix']}* tables in {$GLOBALS['cfg']['db']['dbname']} @ {$GLOBALS['cfg']['db']['hostname']} has been cleared\n";
        }
        Fa3e3aec1();
    }
    foreach ($sql_create as $V7fa3b767 => $Vac5c74b6) {
        if ($V7fa3b767==0) {
            continue;
        }
        $V9c1ebee8->Execute($Vac5c74b6);
    }
    $V9c1ebee8->SetFetchMode(ADODB_FETCH_NUM);
    if (!is_dir("pub/games/{$GLOBALS['cfg']['game']['name']}")) {
        echo "Error: The variable \$cfg['game']['name'] is not set properly in config file.\n";
        echo " Edit your config file ({$V0f14082c['config']})\n";
        echo " Read the comments beside that variable and set that variable properly.\n";
        F56fd05e9();
    }
    if (!file_exists("vsp-{$V0f14082c['log-gamecode']}.php")) {
        Facf3bf61("error: unrecognized logType");
    }
    require_once("vsp-{$V0f14082c['log-gamecode']}.php");
    include_once("pub/games/{$GLOBALS['cfg']['game']['name']}/skillsets/{$GLOBALS['cfg']['skillset']}/{$GLOBALS['cfg']['skillset']}-skill.php");
    if (!isset($GLOBALS['skillset'])) {
        echo "Skill Definitions not found.\n";
        echo " "."pub/games/{$GLOBALS['cfg']['game']['name']}/skillsets/{$GLOBALS['cfg']['skillset']}/{$GLOBALS['cfg']['skillset']}-skill.php"."\n";
    }
    $V21d8a920 = new F622a322a();
    $Vae2aeb93 = new F02ac4643();
    $V8db265ff=strtoupper($V0f14082c['log-gamecode']);
    eval("\$V3643b863 = new VSPParser$V8db265ff(\$V0f14082c['parser-options'],\$V21d8a920,\$Vae2aeb93);");
    $V3643b863->F1417ca90($V0f14082c['logfile']);
    $V21d8a920->F215f9169();
}


trackID above is pending as this is passed with $cfg from the default config file even though it seems to be okay as the GUID we are testing logs with are present in the player database accordingly.

Krillin


Krillin

I reached out to the wonderful people at phpfreaks.com for assistance. I will post back here for the record.

phpfreaks.com


Krillin

Was given a first attempt to fix this, but the solution was to change a line to code that is already posted on line #957 of vsp.php.

$V0f14082c['parser-options']="";

Back to waiting for another response, even though the function was posted with the line in there.

Krillin


Krillin

#3
A second reply gave us a clue as to what was needed to in order to get the "savestate" function working once again. I believe this has broken since PHP 7 came out, we just never knew it.

At phpfreaks.com a user named "kicken" came back and said that the line where the issue was happening #979, needed to be replaced with;
$V0f14082c['parser-options']=array();

Well, I tired that. Nothing changed, except the error message went away. In verifying the /logdata/ folder, nothing was being created in it telling me this was not the fix. So I replaced the line #957 with the above. No change there either. I tired a few more other things, just taking some guesses and nothing seemed to work the way it needed to.

So, I stared at the screen for a few and thought to myself. Yes, it needs they array. So I added the given line above the problem line #979. Saved it, copied the saved file to the production server. Ran the file, and to my surprise, you see the information about Hash file not found. Two lines I have not seen in a very long time. The savestate function is working once again!

One user did warn that this may cause other issues. And he was right. Because this statement is only stated in the "parser-options" section, if SAVESTATE 1 is NOT ran, the error message appears with the 'trackID' now.

Thanks the two users are thanked for their assistance in the _Docs/ChangeLog.html file. (One of the changes coming to vsp-core_v0.50).

Best Regards,
Krillin