CVE-2021-4246 (published 2022-12-17T19:15Z)

A vulnerability was found in roxlukas LMeve and classified as critical. Affected by this issue is some unknown functionality of the component Login Page. The manipulation of the argument X-Forwarded-For leads to sql injection. The attack may be launched remotely. The name of the patch is 29e1ead3bb1c1fad53b77dfc14534496421c5b5d. It is recommended to apply a patch to fix this issue. The identifier of this vulnerability is VDB-216176.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/roxlukas/lmeve
commit_details: repo_url: https://github.com/roxlukas/lmeve
author: Administrator
author_date: 2021-02-13 19:41:22+01:00
msg: important security update
- SQL Injection found in login page via x-forwarded-for header
repository: repo_url: https://github.com/roxlukas/lmeve
repo_name: roxlukas/lmeve
description: LMeve - industry manager and contribution tracker for EVE Online
repo_language: JavaScript
owner: roxlukas
file_changes: filename: Assets.php
change_type: ModificationType.MODIFY
diff: @@ -83,7 +83,9 @@ class Assets extends Route {
             if (count($checklist) > 0) {
                 for ($i = 0; $i < count($checklist) / $MAX_IDS; $i++) { //fix for #85 - can only ask about 1000 names in one batch
                     if ($this->ESI->getDEBUG()) inform(get_class(), "Getting page $i");
-                    $names = array_merge($names, $this->post('',json_encode(array_slice($checklist, $i * $MAX_IDS, $MAX_IDS))));
+                    $tmp = $this->post('',json_encode(array_slice($checklist, $i * $MAX_IDS, $MAX_IDS)));
+                    if ($this->ESI->getDEBUG()) inform(get_class(), "ESI respondend: ". print_r($tmp, TRUE));
+                    $names = array_merge($names, $tmp);
                 }
             }
         }  else {

programming_language: PHP
filename: db.php
change_type: ModificationType.MODIFY
diff: @@ -1,549 +1,556 @@
-<?php
-/**********************************************************************************
-								LM Framework v3
-								
-	A simple PHP based application framework.
-	
-	Contact: pozniak.lukasz@gmail.com
-	
-	Copyright (c) 2005-2013, �ukasz Po�niak
-	All rights reserved.
-
-	Redistribution and use in source and binary forms, with or without modification,
-	are permitted provided that the following conditions are met:
-	
-	Redistributions of source code must retain the above copyright notice,
-	this list of conditions and the following disclaimer.
-	Redistributions in binary form must reproduce the above copyright notice,
-	this list of conditions and the following disclaimer in the documentation
-	and/or other materials provided with the distribution.
-	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-	THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
-	BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-	OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-	OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-	OF THE POSSIBILITY OF SUCH DAMAGE.
-
-**********************************************************************************/
-
-include_once(dirname(__FILE__).'/log.php');
-include_once(dirname(__FILE__).'/../config/config.php');
-include_once(dirname(__FILE__).'/materials.php');
-
-$PDO_CONNECTION=null;
-
-/**
- * Get the URL of item icon for specific typeID from CCP Image Service
- * updated for new Image Service: https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
- * Type icons: https://images.evetech.net/types/587/icon
- * Type renders: https://images.evetech.net/types/587/render
- * 
- * @param int $typeID typeID of the item
- * @param int $size size of the icon (32, 64, 512)
- * @param string $type one of: 'icon', 'render', 'bp', 'bpc'
- * @return string URL to icon
- */
-function getTypeIDicon($typeID, $size=32, $type=null) {
-    if (!is_numeric($typeID)) $typeID=0;
-    if (!is_numeric($size) || ($size!=32 && $size!=64 && $size!=128 && $size!=256 && $size!=512)) $size=32;
-    
-    $bp = getBlueprint($typeID);
-    
-    if ($bp === FALSE) {
-        if (is_null($type) || ($type != 'icon' && $type != 'render')) {
-             $type = 'icon';
-        }
-        if ($size >= 512) {
-            $type = 'render';
-        }
-    } else {
-        if (is_null($type) || ($type != 'bp' && $type != 'bpc')) {
-            if ($bp['techLevel'] == 1) {
-                $type = 'bp';
-            } else {
-                $type = 'bpc';
-            }
-        }
-        
-    }
-    
-    if ($size != 512) {
-        if (file_exists("../wwwroot/ccp_img/${typeID}_${size}.png")) {
-            $icon=getUrl()."ccp_img/${typeID}_${size}.png";
-        } else {
-            //$icon="https://imageserver.eveonline.com/Type/${typeID}_${size}.png";
-            $icon="https://images.evetech.net/types/${typeID}/$type?size=${size}";
-        }
-    } else {
-        if (file_exists("../wwwroot/ccp_renders/${typeID}.png")) {
-            $icon=getUrl()."ccp_renders/${typeID}.png";
-        } else {
-            //$icon="https://imageserver.eveonline.com/Render/${typeID}_${size}.png";
-            $icon="https://images.evetech.net/types/${typeID}/$type?size=${size}";
-        }
-    }
-    return($icon);
-}
-
-/**
- * Get the URL of Corporation Logo for specific corporationID from CCP Image Service
- * updated for new Image Service: https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
- * Corporation logos: https://images.evetech.net/corporations/109299958/logo
- * 
- * @param int $corporationID corporationID of the corporation
- * @param int $size size of the icon (32, 64, 512)
- * @return string URL to icon
- */
-function getCorporationLogo($corporationID,$size=64) {
-    //echo("getCorporationLogo($corporationID,$size)");
-    if (!is_numeric($corporationID)) return "";
-    if (!is_numeric($size) || ($size!=32 && $size!=64 && $size!=128 && $size!=256 && $size!=512)) $size=64;
-    $icon="https://images.evetech.net/corporations/$corporationID/logo?size=$size";
-    return($icon);
-}
-
-/**
- * Get the URL of Character Portrait for specific characterID from CCP Image Service
- * updated for new Image Service: https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
- Character portraits: https://images.evetech.net/characters/1338057886/portrait
- * 
- * @param int $characterID characterID of the character
- * @param int $size size of the icon (32, 64, 512)
- * @return string URL to icon
- */
-function getCharacterPortrait($characterID,$size=64) {
-    //echo("getCorporationLogo($corporationID,$size)");
-    if (!is_numeric($characterID) || $characterID == 0) {
-        if ($size == 32) {
-            return getUrl()."img/character_32.png";
-        } else if ($size == 64) {
-            return getUrl()."img/character_64.png";
-        } else {
-            return "";
-        }
-    }
-    if (!is_numeric($size) || ($size!=32 && $size!=64 && $size!=128 && $size!=256 && $size!=512)) $size=64;
-    $icon="https://images.evetech.net/characters/$characterID/portrait?size=$size";
-    return($icon);
-}
-
-/**
- * Get the URL of Alliance Logo for specific allianceID from CCP Image Service
- * updated for new Image Service: https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
- * Alliance logos: https://images.evetech.net/alliances/434243723/logo
- * 
- * @param int $allianceID allianceID of the alliance
- * @param int $size size of the icon (32, 64, 512)
- * @return string URL to icon
- */
-function getAllianceLogo($allianceID,$size=64) {
-    //echo("getCorporationLogo($corporationID,$size)");
-    if (!is_numeric($allianceID)) return "";
-    if (!is_numeric($size) || ($size!=32 && $size!=64 && $size!=128 && $size!=256 && $size!=512)) $size=64;
-    $icon="https://images.evetech.net/alliances/$allianceID/logo?size=$size";
-    return($icon);
-}
-
-/**
- * Returns typeName for given typeID
- * 
- * @global string $LM_EVEDB
- * @param int $typeID
- * @return mixed returns typeName or FALSE if not found
- */
-function getTypeName($typeID) {
-    global $LM_EVEDB;
-    if (!is_numeric($typeID)) return FALSE;
-    
-    $data = db_asocquery("SELECT * FROM `$LM_EVEDB`.`invTypes` WHERE `typeID`=$typeID;");
-    if (count($data) > 0) {
-        return($data[0]['typeName']);
-    } else return FALSE;
-}
-
-/**
- * Returns typeID for given typeName
- * 
- * @global string $LM_EVEDB
- * @param string $typeName
- * @return mixed returns typeID or FALSE if not found
- */
-function getTypeID($typeName) {
-    global $LM_EVEDB;
-    $data = db_asocquery("SELECT * FROM `$LM_EVEDB`.`invTypes` WHERE `typeName`='$typeName';");
-    if (count($data) > 0) {
-        return($data[0]['typeID']);
-    } else return FALSE;
-}
-
-function get_remote_addr() {
-    if (isset($_SERVER['HTTP_X_REAL_IP'])) return $_SERVER['HTTP_X_REAL_IP'];
-    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR'];
-    if (isset($_SERVER['REMOTE_ADDR'])) return $_SERVER['REMOTE_ADDR'];
-    return FALSE;
-}
-
-function generate_title($subtitle = null) {
-    global $LM_APP_NAME, $lmver;
-    $main_title = "$LM_APP_NAME $lmver";
-    
-    if (is_null($subtitle)) $title="$main_title"; else $title="$main_title - $subtitle";
-    return $title;
-}
-
-function filter_description($description) {
-    return preg_replace('/[\x7F-\xFF]/','',$description);
-}
-
-function generate_meta($description=null, $title=null ,$image=null) {
-    global $META, $TITLE, $LM_APP_NAME, $lmver;
-    
-    if (is_null($description)) $description="LMeve: Industry Contribution and Mass Production Tracker."; else $description = htmlentities($description);
-    if (is_null($title)) $title = generate_title(); else $title = htmlentities($title);
-    if (is_null($image)) $image = getUrl() . "img/lmeve-social.jpg";
-    
-    $url = parse_url(getUrl());
-    $domain = $url['scheme'] . '://' . $url['host'] ;
-    $site = $url['host'];
-    
-    $meta = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-        <meta http-equiv="Pragma" CONTENT="content-cache">
-        <meta charset="utf-8">
-        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-        <meta name="description" content="' . filter_description($description) . '">
-        <meta name="title" content="' . $title . '">
-        <meta name="keywords" content="eve-online, eve, ccp, ccp games, lmeve, industry, production, invention, manufacturing, crafting, massively, multiplayer, online, role, playing, game, mmorpg, isk, mmorpg">
-        <meta name="robots" content="index,follow">
-        <meta property="og:locale" content="en_US">
-        <meta property="og:type" content="website">
-        <meta property="og:site_name" content="' . $site . '">
-        <meta property="fb:app_id" content="">
-        <meta name="twitter:site" content="@rox_lukas">
-        <meta name="twitter:domain" content="' . $domain . '">
-        <meta property="application-name" content="LMeve" />
-        <meta name="mobile-web-app-capable" content="yes">
-        <link rel="apple-touch-icon" sizes="120x120" href="' . getUrl() . 'img/apple-touch-icon.png">
-        <link rel="icon" type="image/png" sizes="32x32" href="' . getUrl() . 'img/favicon-32x32.png">
-        <link rel="icon" type="image/png" sizes="16x16" href="' . getUrl() . 'img/favicon-16x16.png">
-        <link rel="manifest" href="' . getUrl() . 'img/site.webmanifest">
-        <link rel="mask-icon" href="' . getUrl() . 'img/safari-pinned-tab.svg" color="#1d2c38">
-        <link rel="shortcut icon" href="' . getUrl() . 'img/favicon.ico">
-        <meta name="msapplication-TileColor" content="#1d2c38">
-        <meta name="msapplication-config" content="' . getUrl() . 'img/browserconfig.xml">
-        <meta name="theme-color" content="#1d2c38">
-        <meta name="twitter:title" content="' . $title . '">
-        <meta name="twitter:image" content="' . $image . '">
-        <meta name="twitter:card" content="summary">
-        <meta property="og:title" content="' . $title . '">
-        <meta property="og:url" content="' . getUrl() . 'index.php?' . $_SERVER['QUERY_STRING'] . '">
-        <meta property="twitter:description" content="' . filter_description($description) . '">
-        <meta property="og:description" content="' . filter_description($description) . '">
-        <meta property="og:image" content="' . $image . '">
-        <meta name="viewport" content="width=device-width, initial-scale=1.0">
-        <title>
-            ' . $title . '
-        </title>';
-    $META = $meta;
-    return $meta;
-}
-
-function printerr($text) {
-	echo("<br><table class=\"error\"><tr><td>$text</td></tr></table>");
-	echo('<input type="button" value="&lt; Back" onclick="history.back();">');
-}
-
-function secureGETnum($field) {
-	$what=$_REQUEST[$field];
-	if (!empty($what) && !preg_match('/^(\-){0,1}([\d]+)(\.\d+){0,1}$/',$what)) {
-		printerr("Niepoprawny parametr $field.");
-		die('');
-	}
-	return $what;
-}
-
-function secureGETstr($field,$len=32768,$http=false) {
-	if (!$http) {
-		$what=htmlspecialchars($_REQUEST[$field]);
-	} else {
-		$what=$_GET[$field];
-	}
-        //if (!get_magic_quotes_gpc()) $what=addslashes($what);
-        $what=addslashes($what);
-	//echo("DEBUG: $field='$what' (".strlen($what)." of $len)<br>");
-	$what=substr($what,0,$len);
-	return $what;
-}
-
-/*****************************************************************************
-Funkcje dost�pu do bazy danych
-*****************************************************************************/
-
-//db_connect zwraca identyfikator po��czenia z MySQL
-function db_connect() {
-    global $LM_DEBUG,$LM_DBENGINE,$LM_dbhost,$LM_dbname,$LM_dbuser,$LM_dbpass,$PDO_CONNECTION;
-    
-    if (!is_null($PDO_CONNECTION)) return($PDO_CONNECTION);
-    
-    if ($LM_DBENGINE=="MYSQL") {
-        $dsn='mysql';
-    } else if ($LM_DBENGINE=="PGSQL") {
-        $dsn='pgsql';
-    } else {
-        die('Error: $LM_DBENGINE setting is missing in config.php');
-    }
-		
-    try {
-        $ret = new PDO("$dsn:host=$LM_dbhost;dbname=$LM_dbname;charset=utf8", $LM_dbuser, $LM_dbpass, array(PDO::ATTR_EMULATE_PREPARES => false, 
-                                                                                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
-        $ret->exec("SET CHARACTER SET utf8");
-        
-        //for MySQL 5.7.5 and newer - workaround for ONLY_FULL_GROUP_BY
-        $ret->exec("SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));");
-        
-    } catch(PDOException $ex) {
-        if ($LM_DEBUG==1) {
-                    printerr("No connection to the database.<br />MySQL reply: ".$ex->getMessage());
-            } else {
-                    printerr("No connection to the database. Contact your administrator and report the problem.<br/>");
-        }
-        loguj(dirname(__FILE__).'/../var/error.txt',"Error connecting to the database. MySQL reply: ".$ex->getMessage());
-        die();
-    }
-    $PDO_CONNECTION=$ret;
-    return($ret);
-    
-}
-
-//db_query zwraca dwuwymiarow� tablic� z rekordami
-function db_query($sql) {
-	global $LM_DEBUG,$LM_DBENGINE;
-	$my_link=db_connect();
-	$i=0;
-	$result=array();
-	
-	    try {
-                $stmt = $my_link->query($sql); 
-                $result = $stmt->fetchAll(PDO::FETCH_NUM);
-            } catch(PDOException $ex) {
-                loguj(dirname(__FILE__).'/../var/error.txt',"Error in query: $sql MySQL reply: ".$ex->getMessage());
-                if ($LM_DEBUG==1) {
-                        printerr("Error in query: $sql<br />MySQL reply: ".$ex->getMessage());
-                } else {
-                        printerr("Database error. Contact your administrator and report the problem.<br/>");
-                }
-                die();
-            }
-        //echo("<pre>db_query($sql): "); var_dump($result); echo('</pre>');
-	return($result);
-}
-
-//db_asocquery zwraca asocjacyjn� tablic� z rekordami
-function db_asocquery($sql) {
-	global $LM_DEBUG,$LM_DBENGINE;
-	$my_link=db_connect();
-	$i=0;
-	$result=array();
-	
-        try {
-            $stmt = $my_link->query($sql); 
-            $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
-        } catch(PDOException $ex) {
-            loguj(dirname(__FILE__).'/../var/error.txt',"Error in query: $sql MySQL reply: ".$ex->getMessage());
-            if ($LM_DEBUG==1) {
-                    printerr("Error in query: $sql<br />MySQL reply: ".$ex->getMessage());
-            } else {
-                    printerr("Database error. Contact your administrator and report the problem.<br/>");
-            }
-            die();
-        }
-	
-        //echo("<pre>db_asocquery($sql): "); var_dump($result); echo('</pre>');
-	return($result);
-}
-
-//db_count zwraca ilo�� rekord�w wybranych przez zapytanie
-function db_count($sql) {
-	global $LM_DEBUG,$LM_DBENGINE;
-	$my_link=db_connect();
-	$i=0;
-	$result=array();
-        try {
-            $stmt = $my_link->query($sql); 
-            $rows = count($stmt->fetchAll(PDO::FETCH_NUM));
-        } catch(PDOException $ex) {
-            loguj(dirname(__FILE__).'/../var/error.txt',"Error in query: $sql MySQL reply: ".$ex->getMessage());
-            if ($LM_DEBUG==1) {
-                    printerr("Error in query: $sql<br />MySQL reply: ".$ex->getMessage());
-            } else {
-                    printerr("Database error. Contact your administrator and report the problem.<br/>");
-            }
-            die();
-        }
-        //echo("<pre>db_count($sql): "); var_dump($rows); echo('</pre>');
-	return($rows);
-}
-
-//db_uquery nie zwraca wynik�w, wysy�a tylko komend� SQL do serwera bazy
-function db_uquery($sql) {
-    global $LM_DEBUG, $LM_READONLY,$LM_DBENGINE;
-    if ($LM_READONLY==1) {
-		echo("<b>Read only mode.</b><br>");
-		return;
-	}
-	$my_link=db_connect();
-	$i=0;
-	$result=array();
-	
-        try {
-            $stmt = $my_link->query($sql);
-        } catch(PDOException $ex) {
-            loguj(dirname(__FILE__).'/../var/error.txt',"Error in query: $sql MySQL reply: ".$ex->getMessage());
-            if ($LM_DEBUG==1) {
-                    printerr("Error in query: $sql<br />MySQL reply: ".$ex->getMessage());
-            } else {
-                    printerr("Database error. Contact your administrator and report the problem.<br/>");
-            }
-            die();
-        }
-	
-        error_reporting(E_ALL & ~E_NOTICE);
-	return($stmt->rowCount());
-}
-
-//zwraca wiersz tabeli, kt�rego pole $field zawiera warto�� $id, je�li rekord nie istnieje zwracana jest pusta tablica
-function asoc_row($tablica,$field,$id) {
-	foreach($tablica as $row) {
-		if ($row[$field]==$id) return $row;
-	}
-	return array();
-}
-
-/*****************************************************************************
-Funkcje dost�pu do plik�w tekstowych
-*****************************************************************************/
-
-//czyta plik tekstowy z danymi
-function db_read($nazwa_pliku) {
-    $uchwyt = fopen($nazwa_pliku, "r");
-    $tresc = fread($uchwyt, filesize($nazwa_pliku));
-    fclose($uchwyt);
-    //$tresc=str_replace("\\\"","\"",$tresc);
-    $tresc=stripslashes($tresc);
-    $data=explode(',',$tresc);
-    return $data;
-}
-
-//zapisuje plik tekstowy z danymi
-function db_write($nazwa_pliku,$data) {
-include('../config/config.php');
-  if ($LM_READONLY==0) {
-    $uchwyt = fopen($nazwa_pliku, "w");
-    if (count($data)>0) {
-	$tresc=implode(',',$data);
-    }
-    fwrite($uchwyt, $tresc);
-    fclose($uchwyt);
-  }
-}
-
-//czyta plik tekstowy z danymi
-function db_read2($nazwa_pliku) {
-    $uchwyt = fopen($nazwa_pliku, "r");
-    $tresc = fread($uchwyt, filesize($nazwa_pliku));
-    fclose($uchwyt);
-    //$tresc=str_replace("\\\"","\"",$tresc);
-    $tresc=stripslashes($tresc);
-    $data=explode('|',$tresc);
-    return $data;
-}
-
-//zapisuje plik tekstowy z danymi
-function db_write2($nazwa_pliku,$data) {
-include('../config/config.php');
-  if ($LM_READONLY==0) {
-    $uchwyt = fopen($nazwa_pliku, "w");
-    if (count($data)>0) {
-		$tresc=implode('|',$data);
-    }
-    fwrite($uchwyt, $tresc);
-    fclose($uchwyt);
-  }
-}
-
-/*****************************************************************************
-Funkcje pobieraj�ce okre�lone tabele z bazy
-*****************************************************************************/
-
-//zwraca tabel�
-function admini($opcje='') { //DEPRECATED!! DO NOT USE
-	//echo("<br>admini(\"$opcje\");<br>");
-	//$sql="SELECT * FROM admin $opcje";
-	//$result=db_asocquery($sql);
-	//return($result);
-}
-
-//zwraca tabel�
-function message($opcje='') {
-	global $USERSTABLE;
-	$sql="SELECT m.*, a1.login AS od, a2.login AS do FROM `message` AS m LEFT JOIN `$USERSTABLE` AS a1 ON m.msgfrom = a1.`userID` LEFT JOIN `$USERSTABLE` AS a2 ON m.msgto = a2.`userID` $opcje ORDER BY m.id DESC";
-	$result=db_asocquery($sql);
-	return($result);
-}
-
-//zwraca tabel�
-function message_sent($opcje='') {
-	global $USERSTABLE;
-	$sql="SELECT m.*, a1.login AS od, a2.login AS do FROM `message_sent` AS m LEFT JOIN `$USERSTABLE` AS a1 ON m.msgfrom = a1.`userID` LEFT JOIN `$USERSTABLE` AS a2 ON m.msgto = a2.`userID` $opcje ORDER BY m.id DESC";
-	$result=db_asocquery($sql);
-	return($result);
-}
-
-/******************************************* INNE **********************************************/
-
-//konwertuje string na liczbe
-function str2num($z) {
-    settype($z,'integer');
-    return $z;
-}
-
-//tworzy lini� <link href= do nag��wka HTML - s�u�y do obs�ugi sk�rek CSS
-function applycss($css) {
-	printf('<link type="text/css" href="%s" rel="stylesheet">',getUrl().$css);
-}
-
-function stripslashes_deep($value)
-{
-    $value = is_array($value) ?
-                array_map('stripslashes_deep', $value) :
-                stripslashes($value);
-
-    return $value;
-}
-
-/**
- * Function returns lmeve URL path
- * Used to prevent RPO/PRSSI type of exploit
- * @return type
- */
-function getUrl(){
-  $a=parse_url(sprintf(
-    "%s://%s%s",
-    isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http',
-    $_SERVER['SERVER_NAME'],
-    $_SERVER['REQUEST_URI']
-  ));
-  if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT']!=80 && $_SERVER['SERVER_PORT']!=443) {
-      $port=":${_SERVER['SERVER_PORT']}"; 
-  } else {
-      $port='';
-  }
-  $path=preg_split('/[\w]+\.php/',$a['path']);
-  return $a['scheme'].'://'.$a['host'].$port.$path[0];
-}
-
-?>
+<?php
+/**********************************************************************************
+								LM Framework v3
+								
+	A simple PHP based application framework.
+	
+	Contact: pozniak.lukasz@gmail.com
+	
+	Copyright (c) 2005-2013, �ukasz Po�niak
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification,
+	are permitted provided that the following conditions are met:
+	
+	Redistributions of source code must retain the above copyright notice,
+	this list of conditions and the following disclaimer.
+	Redistributions in binary form must reproduce the above copyright notice,
+	this list of conditions and the following disclaimer in the documentation
+	and/or other materials provided with the distribution.
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+	THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+	BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+	OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+	OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+	OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**********************************************************************************/
+
+include_once(dirname(__FILE__).'/log.php');
+include_once(dirname(__FILE__).'/../config/config.php');
+include_once(dirname(__FILE__).'/materials.php');
+include_once(dirname(__FILE__).'/validator.php');
+
+$PDO_CONNECTION=null;
+
+/**
+ * Get the URL of item icon for specific typeID from CCP Image Service
+ * updated for new Image Service: https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
+ * Type icons: https://images.evetech.net/types/587/icon
+ * Type renders: https://images.evetech.net/types/587/render
+ * 
+ * @param int $typeID typeID of the item
+ * @param int $size size of the icon (32, 64, 512)
+ * @param string $type one of: 'icon', 'render', 'bp', 'bpc'
+ * @return string URL to icon
+ */
+function getTypeIDicon($typeID, $size=32, $type=null) {
+    if (!is_numeric($typeID)) $typeID=0;
+    if (!is_numeric($size) || ($size!=32 && $size!=64 && $size!=128 && $size!=256 && $size!=512)) $size=32;
+    
+    $bp = getBlueprint($typeID);
+    
+    if ($bp === FALSE) {
+        if (is_null($type) || ($type != 'icon' && $type != 'render')) {
+             $type = 'icon';
+        }
+        if ($size >= 512) {
+            $type = 'render';
+        }
+    } else {
+        if (is_null($type) || ($type != 'bp' && $type != 'bpc')) {
+            if ($bp['techLevel'] == 1) {
+                $type = 'bp';
+            } else {
+                $type = 'bpc';
+            }
+        }
+        
+    }
+    
+    if ($size != 512) {
+        if (file_exists("../wwwroot/ccp_img/${typeID}_${size}.png")) {
+            $icon=getUrl()."ccp_img/${typeID}_${size}.png";
+        } else {
+            //$icon="https://imageserver.eveonline.com/Type/${typeID}_${size}.png";
+            $icon="https://images.evetech.net/types/${typeID}/$type?size=${size}";
+        }
+    } else {
+        if (file_exists("../wwwroot/ccp_renders/${typeID}.png")) {
+            $icon=getUrl()."ccp_renders/${typeID}.png";
+        } else {
+            //$icon="https://imageserver.eveonline.com/Render/${typeID}_${size}.png";
+            $icon="https://images.evetech.net/types/${typeID}/$type?size=${size}";
+        }
+    }
+    return($icon);
+}
+
+/**
+ * Get the URL of Corporation Logo for specific corporationID from CCP Image Service
+ * updated for new Image Service: https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
+ * Corporation logos: https://images.evetech.net/corporations/109299958/logo
+ * 
+ * @param int $corporationID corporationID of the corporation
+ * @param int $size size of the icon (32, 64, 512)
+ * @return string URL to icon
+ */
+function getCorporationLogo($corporationID,$size=64) {
+    //echo("getCorporationLogo($corporationID,$size)");
+    if (!is_numeric($corporationID)) return "";
+    if (!is_numeric($size) || ($size!=32 && $size!=64 && $size!=128 && $size!=256 && $size!=512)) $size=64;
+    $icon="https://images.evetech.net/corporations/$corporationID/logo?size=$size";
+    return($icon);
+}
+
+/**
+ * Get the URL of Character Portrait for specific characterID from CCP Image Service
+ * updated for new Image Service: https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
+ Character portraits: https://images.evetech.net/characters/1338057886/portrait
+ * 
+ * @param int $characterID characterID of the character
+ * @param int $size size of the icon (32, 64, 512)
+ * @return string URL to icon
+ */
+function getCharacterPortrait($characterID,$size=64) {
+    //echo("getCorporationLogo($corporationID,$size)");
+    if (!is_numeric($characterID) || $characterID == 0) {
+        if ($size == 32) {
+            return getUrl()."img/character_32.png";
+        } else if ($size == 64) {
+            return getUrl()."img/character_64.png";
+        } else {
+            return "";
+        }
+    }
+    if (!is_numeric($size) || ($size!=32 && $size!=64 && $size!=128 && $size!=256 && $size!=512)) $size=64;
+    $icon="https://images.evetech.net/characters/$characterID/portrait?size=$size";
+    return($icon);
+}
+
+/**
+ * Get the URL of Alliance Logo for specific allianceID from CCP Image Service
+ * updated for new Image Service: https://developers.eveonline.com/blog/article/from-image-server-to-a-whole-new-image-service-1
+ * Alliance logos: https://images.evetech.net/alliances/434243723/logo
+ * 
+ * @param int $allianceID allianceID of the alliance
+ * @param int $size size of the icon (32, 64, 512)
+ * @return string URL to icon
+ */
+function getAllianceLogo($allianceID,$size=64) {
+    //echo("getCorporationLogo($corporationID,$size)");
+    if (!is_numeric($allianceID)) return "";
+    if (!is_numeric($size) || ($size!=32 && $size!=64 && $size!=128 && $size!=256 && $size!=512)) $size=64;
+    $icon="https://images.evetech.net/alliances/$allianceID/logo?size=$size";
+    return($icon);
+}
+
+/**
+ * Returns typeName for given typeID
+ * 
+ * @global string $LM_EVEDB
+ * @param int $typeID
+ * @return mixed returns typeName or FALSE if not found
+ */
+function getTypeName($typeID) {
+    global $LM_EVEDB;
+    if (!is_numeric($typeID)) return FALSE;
+    
+    $data = db_asocquery("SELECT * FROM `$LM_EVEDB`.`invTypes` WHERE `typeID`=$typeID;");
+    if (count($data) > 0) {
+        return($data[0]['typeName']);
+    } else return FALSE;
+}
+
+/**
+ * Returns typeID for given typeName
+ * 
+ * @global string $LM_EVEDB
+ * @param string $typeName
+ * @return mixed returns typeID or FALSE if not found
+ */
+function getTypeID($typeName) {
+    global $LM_EVEDB;
+    $data = db_asocquery("SELECT * FROM `$LM_EVEDB`.`invTypes` WHERE `typeName`='$typeName';");
+    if (count($data) > 0) {
+        return($data[0]['typeID']);
+    } else return FALSE;
+}
+
+function get_remote_addr() {
+    if (isset($_SERVER['HTTP_X_REAL_IP'])) $ip =  $_SERVER['HTTP_X_REAL_IP'];
+    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) $ip =  $_SERVER['HTTP_X_FORWARDED_FOR'];
+    if (isset($_SERVER['REMOTE_ADDR'])) $ip =  $_SERVER['REMOTE_ADDR'];
+       
+    if (! Validator::ipv4($ip)) {
+        loguj(dirname(__FILE__).'/../var/error.txt',"WARNING Possible SQL injection via x-forwarded-for header: '$ip'");
+        $ip = '0.0.0.0';
+    }
+    
+    return $ip;
+}
+
+function generate_title($subtitle = null) {
+    global $LM_APP_NAME, $lmver;
+    $main_title = "$LM_APP_NAME $lmver";
+    
+    if (is_null($subtitle)) $title="$main_title"; else $title="$main_title - $subtitle";
+    return $title;
+}
+
+function filter_description($description) {
+    return preg_replace('/[\x7F-\xFF]/','',$description);
+}
+
+function generate_meta($description=null, $title=null ,$image=null) {
+    global $META, $TITLE, $LM_APP_NAME, $lmver;
+    
+    if (is_null($description)) $description="LMeve: Industry Contribution and Mass Production Tracker."; else $description = htmlentities($description);
+    if (is_null($title)) $title = generate_title(); else $title = htmlentities($title);
+    if (is_null($image)) $image = getUrl() . "img/lmeve-social.jpg";
+    
+    $url = parse_url(getUrl());
+    $domain = $url['scheme'] . '://' . $url['host'] ;
+    $site = $url['host'];
+    
+    $meta = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+        <meta http-equiv="Pragma" CONTENT="content-cache">
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+        <meta name="description" content="' . filter_description($description) . '">
+        <meta name="title" content="' . $title . '">
+        <meta name="keywords" content="eve-online, eve, ccp, ccp games, lmeve, industry, production, invention, manufacturing, crafting, massively, multiplayer, online, role, playing, game, mmorpg, isk, mmorpg">
+        <meta name="robots" content="index,follow">
+        <meta property="og:locale" content="en_US">
+        <meta property="og:type" content="website">
+        <meta property="og:site_name" content="' . $site . '">
+        <meta property="fb:app_id" content="">
+        <meta name="twitter:site" content="@rox_lukas">
+        <meta name="twitter:domain" content="' . $domain . '">
+        <meta property="application-name" content="LMeve" />
+        <meta name="mobile-web-app-capable" content="yes">
+        <link rel="apple-touch-icon" sizes="120x120" href="' . getUrl() . 'img/apple-touch-icon.png">
+        <link rel="icon" type="image/png" sizes="32x32" href="' . getUrl() . 'img/favicon-32x32.png">
+        <link rel="icon" type="image/png" sizes="16x16" href="' . getUrl() . 'img/favicon-16x16.png">
+        <link rel="manifest" href="' . getUrl() . 'img/site.webmanifest">
+        <link rel="mask-icon" href="' . getUrl() . 'img/safari-pinned-tab.svg" color="#1d2c38">
+        <link rel="shortcut icon" href="' . getUrl() . 'img/favicon.ico">
+        <meta name="msapplication-TileColor" content="#1d2c38">
+        <meta name="msapplication-config" content="' . getUrl() . 'img/browserconfig.xml">
+        <meta name="theme-color" content="#1d2c38">
+        <meta name="twitter:title" content="' . $title . '">
+        <meta name="twitter:image" content="' . $image . '">
+        <meta name="twitter:card" content="summary">
+        <meta property="og:title" content="' . $title . '">
+        <meta property="og:url" content="' . getUrl() . 'index.php?' . $_SERVER['QUERY_STRING'] . '">
+        <meta property="twitter:description" content="' . filter_description($description) . '">
+        <meta property="og:description" content="' . filter_description($description) . '">
+        <meta property="og:image" content="' . $image . '">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <title>
+            ' . $title . '
+        </title>';
+    $META = $meta;
+    return $meta;
+}
+
+function printerr($text) {
+	echo("<br><table class=\"error\"><tr><td>$text</td></tr></table>");
+	echo('<input type="button" value="&lt; Back" onclick="history.back();">');
+}
+
+function secureGETnum($field) {
+	$what=$_REQUEST[$field];
+	if (!empty($what) && !preg_match('/^(\-){0,1}([\d]+)(\.\d+){0,1}$/',$what)) {
+		printerr("Niepoprawny parametr $field.");
+		die('');
+	}
+	return $what;
+}
+
+function secureGETstr($field,$len=32768,$http=false) {
+	if (!$http) {
+		$what=htmlspecialchars($_REQUEST[$field]);
+	} else {
+		$what=$_GET[$field];
+	}
+        //if (!get_magic_quotes_gpc()) $what=addslashes($what);
+        $what=addslashes($what);
+	//echo("DEBUG: $field='$what' (".strlen($what)." of $len)<br>");
+	$what=substr($what,0,$len);
+	return $what;
+}
+
+/*****************************************************************************
+Funkcje dost�pu do bazy danych
+*****************************************************************************/
+
+//db_connect zwraca identyfikator po��czenia z MySQL
+function db_connect() {
+    global $LM_DEBUG,$LM_DBENGINE,$LM_dbhost,$LM_dbname,$LM_dbuser,$LM_dbpass,$PDO_CONNECTION;
+    
+    if (!is_null($PDO_CONNECTION)) return($PDO_CONNECTION);
+    
+    if ($LM_DBENGINE=="MYSQL") {
+        $dsn='mysql';
+    } else if ($LM_DBENGINE=="PGSQL") {
+        $dsn='pgsql';
+    } else {
+        die('Error: $LM_DBENGINE setting is missing in config.php');
+    }
+		
+    try {
+        $ret = new PDO("$dsn:host=$LM_dbhost;dbname=$LM_dbname;charset=utf8", $LM_dbuser, $LM_dbpass, array(PDO::ATTR_EMULATE_PREPARES => false, 
+                                                                                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
+        $ret->exec("SET CHARACTER SET utf8");
+        
+        //for MySQL 5.7.5 and newer - workaround for ONLY_FULL_GROUP_BY
+        $ret->exec("SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));");
+        
+    } catch(PDOException $ex) {
+        if ($LM_DEBUG==1) {
+                    printerr("No connection to the database.<br />MySQL reply: ".$ex->getMessage());
+            } else {
+                    printerr("No connection to the database. Contact your administrator and report the problem.<br/>");
+        }
+        loguj(dirname(__FILE__).'/../var/error.txt',"Error connecting to the database. MySQL reply: ".$ex->getMessage());
+        die();
+    }
+    $PDO_CONNECTION=$ret;
+    return($ret);
+    
+}
+
+//db_query zwraca dwuwymiarow� tablic� z rekordami
+function db_query($sql) {
+	global $LM_DEBUG,$LM_DBENGINE;
+	$my_link=db_connect();
+	$i=0;
+	$result=array();
+	
+	    try {
+                $stmt = $my_link->query($sql); 
+                $result = $stmt->fetchAll(PDO::FETCH_NUM);
+            } catch(PDOException $ex) {
+                loguj(dirname(__FILE__).'/../var/error.txt',"Error in query: $sql MySQL reply: ".$ex->getMessage());
+                if ($LM_DEBUG==1) {
+                        printerr("Error in query: $sql<br />MySQL reply: ".$ex->getMessage());
+                } else {
+                        printerr("Database error. Contact your administrator and report the problem.<br/>");
+                }
+                die();
+            }
+        //echo("<pre>db_query($sql): "); var_dump($result); echo('</pre>');
+	return($result);
+}
+
+//db_asocquery zwraca asocjacyjn� tablic� z rekordami
+function db_asocquery($sql) {
+	global $LM_DEBUG,$LM_DBENGINE;
+	$my_link=db_connect();
+	$i=0;
+	$result=array();
+	
+        try {
+            $stmt = $my_link->query($sql); 
+            $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
+        } catch(PDOException $ex) {
+            loguj(dirname(__FILE__).'/../var/error.txt',"Error in query: $sql MySQL reply: ".$ex->getMessage());
+            if ($LM_DEBUG==1) {
+                    printerr("Error in query: $sql<br />MySQL reply: ".$ex->getMessage());
+            } else {
+                    printerr("Database error. Contact your administrator and report the problem.<br/>");
+            }
+            die();
+        }
+	
+        //echo("<pre>db_asocquery($sql): "); var_dump($result); echo('</pre>');
+	return($result);
+}
+
+//db_count zwraca ilo�� rekord�w wybranych przez zapytanie
+function db_count($sql) {
+	global $LM_DEBUG,$LM_DBENGINE;
+	$my_link=db_connect();
+	$i=0;
+	$result=array();
+        try {
+            $stmt = $my_link->query($sql); 
+            $rows = count($stmt->fetchAll(PDO::FETCH_NUM));
+        } catch(PDOException $ex) {
+            loguj(dirname(__FILE__).'/../var/error.txt',"Error in query: $sql MySQL reply: ".$ex->getMessage());
+            if ($LM_DEBUG==1) {
+                    printerr("Error in query: $sql<br />MySQL reply: ".$ex->getMessage());
+            } else {
+                    printerr("Database error. Contact your administrator and report the problem.<br/>");
+            }
+            die();
+        }
+        //echo("<pre>db_count($sql): "); var_dump($rows); echo('</pre>');
+	return($rows);
+}
+
+//db_uquery nie zwraca wynik�w, wysy�a tylko komend� SQL do serwera bazy
+function db_uquery($sql) {
+    global $LM_DEBUG, $LM_READONLY,$LM_DBENGINE;
+    if ($LM_READONLY==1) {
+		echo("<b>Read only mode.</b><br>");
+		return;
+	}
+	$my_link=db_connect();
+	$i=0;
+	$result=array();
+	
+        try {
+            $stmt = $my_link->query($sql);
+        } catch(PDOException $ex) {
+            loguj(dirname(__FILE__).'/../var/error.txt',"Error in query: $sql MySQL reply: ".$ex->getMessage());
+            if ($LM_DEBUG==1) {
+                    printerr("Error in query: $sql<br />MySQL reply: ".$ex->getMessage());
+            } else {
+                    printerr("Database error. Contact your administrator and report the problem.<br/>");
+            }
+            die();
+        }
+	
+        error_reporting(E_ALL & ~E_NOTICE);
+	return($stmt->rowCount());
+}
+
+//zwraca wiersz tabeli, kt�rego pole $field zawiera warto�� $id, je�li rekord nie istnieje zwracana jest pusta tablica
+function asoc_row($tablica,$field,$id) {
+	foreach($tablica as $row) {
+		if ($row[$field]==$id) return $row;
+	}
+	return array();
+}
+
+/*****************************************************************************
+Funkcje dost�pu do plik�w tekstowych
+*****************************************************************************/
+
+//czyta plik tekstowy z danymi
+function db_read($nazwa_pliku) {
+    $uchwyt = fopen($nazwa_pliku, "r");
+    $tresc = fread($uchwyt, filesize($nazwa_pliku));
+    fclose($uchwyt);
+    //$tresc=str_replace("\\\"","\"",$tresc);
+    $tresc=stripslashes($tresc);
+    $data=explode(',',$tresc);
+    return $data;
+}
+
+//zapisuje plik tekstowy z danymi
+function db_write($nazwa_pliku,$data) {
+include('../config/config.php');
+  if ($LM_READONLY==0) {
+    $uchwyt = fopen($nazwa_pliku, "w");
+    if (count($data)>0) {
+	$tresc=implode(',',$data);
+    }
+    fwrite($uchwyt, $tresc);
+    fclose($uchwyt);
+  }
+}
+
+//czyta plik tekstowy z danymi
+function db_read2($nazwa_pliku) {
+    $uchwyt = fopen($nazwa_pliku, "r");
+    $tresc = fread($uchwyt, filesize($nazwa_pliku));
+    fclose($uchwyt);
+    //$tresc=str_replace("\\\"","\"",$tresc);
+    $tresc=stripslashes($tresc);
+    $data=explode('|',$tresc);
+    return $data;
+}
+
+//zapisuje plik tekstowy z danymi
+function db_write2($nazwa_pliku,$data) {
+include('../config/config.php');
+  if ($LM_READONLY==0) {
+    $uchwyt = fopen($nazwa_pliku, "w");
+    if (count($data)>0) {
+		$tresc=implode('|',$data);
+    }
+    fwrite($uchwyt, $tresc);
+    fclose($uchwyt);
+  }
+}
+
+/*****************************************************************************
+Funkcje pobieraj�ce okre�lone tabele z bazy
+*****************************************************************************/
+
+//zwraca tabel�
+function admini($opcje='') { //DEPRECATED!! DO NOT USE
+	//echo("<br>admini(\"$opcje\");<br>");
+	//$sql="SELECT * FROM admin $opcje";
+	//$result=db_asocquery($sql);
+	//return($result);
+}
+
+//zwraca tabel�
+function message($opcje='') {
+	global $USERSTABLE;
+	$sql="SELECT m.*, a1.login AS od, a2.login AS do FROM `message` AS m LEFT JOIN `$USERSTABLE` AS a1 ON m.msgfrom = a1.`userID` LEFT JOIN `$USERSTABLE` AS a2 ON m.msgto = a2.`userID` $opcje ORDER BY m.id DESC";
+	$result=db_asocquery($sql);
+	return($result);
+}
+
+//zwraca tabel�
+function message_sent($opcje='') {
+	global $USERSTABLE;
+	$sql="SELECT m.*, a1.login AS od, a2.login AS do FROM `message_sent` AS m LEFT JOIN `$USERSTABLE` AS a1 ON m.msgfrom = a1.`userID` LEFT JOIN `$USERSTABLE` AS a2 ON m.msgto = a2.`userID` $opcje ORDER BY m.id DESC";
+	$result=db_asocquery($sql);
+	return($result);
+}
+
+/******************************************* INNE **********************************************/
+
+//konwertuje string na liczbe
+function str2num($z) {
+    settype($z,'integer');
+    return $z;
+}
+
+//tworzy lini� <link href= do nag��wka HTML - s�u�y do obs�ugi sk�rek CSS
+function applycss($css) {
+	printf('<link type="text/css" href="%s" rel="stylesheet">',getUrl().$css);
+}
+
+function stripslashes_deep($value)
+{
+    $value = is_array($value) ?
+                array_map('stripslashes_deep', $value) :
+                stripslashes($value);
+
+    return $value;
+}
+
+/**
+ * Function returns lmeve URL path
+ * Used to prevent RPO/PRSSI type of exploit
+ * @return type
+ */
+function getUrl(){
+  $a=parse_url(sprintf(
+    "%s://%s%s",
+    isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http',
+    $_SERVER['SERVER_NAME'],
+    $_SERVER['REQUEST_URI']
+  ));
+  if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT']!=80 && $_SERVER['SERVER_PORT']!=443) {
+      $port=":${_SERVER['SERVER_PORT']}"; 
+  } else {
+      $port='';
+  }
+  $path=preg_split('/[\w]+\.php/',$a['path']);
+  return $a['scheme'].'://'.$a['host'].$port.$path[0];
+}
+
+?>

programming_language: PHP
filename: dbcatalog.php
change_type: ModificationType.MODIFY
diff: @@ -214,7 +214,7 @@ function esiUpdateApicorps() {
     $table = db_asocquery("DESCRIBE `apicorps`;");
     $found = FALSE;
     foreach ($table as $column) {
-        if ($column['Field']=='tokenID' && $column['Type']=='int(11)') {
+        if ($column['Field']=='tokenID' && ($column['Type']=='int(11)' || $column['Type']=='int')) {
             $found = TRUE;
         }
     }    
@@ -241,7 +241,7 @@ function esiUpdateApiAssets() {
     $table = db_asocquery("DESCRIBE `apiassets`;");
     $found = FALSE;
     foreach ($table as $column) {
-        if ($column['Field']=='is_blueprint_copy' && $column['Type']=='int(11)') {
+        if ($column['Field']=='is_blueprint_copy' && ($column['Type']=='int(11)' || $column['Type']=='int')) {
             $found = TRUE;
         }
     }    
@@ -289,7 +289,7 @@ function esiUpdateApimarketorders() {
     
     $found = FALSE;
     foreach ($table as $column) {
-        if ($column['Field']=='range' && $column['Type']=='int(11)') {
+        if ($column['Field']=='range' && ($column['Type']=='int(11)' || $column['Type']=='int')) {
             $found = TRUE;
         }
     }    
@@ -299,7 +299,7 @@ function esiUpdateApimarketorders() {
     
     $found = FALSE;
     foreach ($table as $column) {
-        if ($column['Field']=='stationID' && $column['Type']=='int(11)') {
+        if ($column['Field']=='stationID' && ($column['Type']=='int(11)' || $column['Type']=='int')) {
             $found = TRUE;
         }
     }    
@@ -319,7 +319,7 @@ function esiUpdateApiContractItems() {
     $table = db_asocquery("DESCRIBE `apicontractitems`;");
     $found = FALSE;
     foreach ($table as $column) {
-        if ($column['Field']=='rawQuantity' && $column['Type']=='int(11)') {
+        if ($column['Field']=='rawQuantity' && ($column['Type']=='int(11)' || $column['Type']=='int')) {
             $found = TRUE;
         }
     }    
@@ -338,7 +338,7 @@ function esiUpdateApiIndustryJobsCrius() {
     $table = db_asocquery("DESCRIBE `apiindustryjobscrius`;");
     $found = FALSE;
     foreach ($table as $column) {
-        if ($column['Field']=='status' && $column['Type']=='int(11)') {
+        if ($column['Field']=='status' && ($column['Type']=='int(11)' || $column['Type']=='int')) {
             $found = TRUE;
         }
     }    
@@ -410,7 +410,7 @@ function esiUpdateApiCorpMembers() {
                 ($column['Field']=='logonDateTime' && $column['Type']=='datetime')
                 || ($column['Field']=='logoffDateTime' && $column['Type']=='datetime') 
                 || ($column['Field']=='solarSystemID' && $column['Type']=='bigint(11)') 
-                || ($column['Field']=='shipID' && $column['Type']=='int(11)') 
+                || ($column['Field']=='shipID' && ($column['Type']=='int(11)' || $column['Type']=='int')) 
            ) {
                 $found = TRUE;
         }

programming_language: PHP
filename: errorhandler.php
change_type: ModificationType.MODIFY
diff: @@ -89,7 +89,7 @@ function get_caller_info() {
     $trace = preg_replace ('/^#0\s+' . __FUNCTION__ . "[^\n]*\n/", '', $trace, 1);
 
     // Renumber backtrace items.
-    $trace = preg_replace ('/^#(\d+)/me', '\'#\' . ($1 - 1)', $trace);
+    $trace = preg_replace ('/^#(\d+)/m', '\'#\' . ($1 - 1)', $trace);
 
     return $trace; 
 }

programming_language: PHP
filename: validator.php
change_type: ModificationType.ADD
diff: @@ -0,0 +1,102 @@
+<?php
+
+/* 
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+class Validator {
+    static function phone($input) {
+        return preg_match('/^(\d{9,9}|\+48\d{9,9})$/',$input);
+    }
+    
+    static function email($input) {
+        return preg_match('/^([\-\_\.\w\d]+)\@(.+\.\w+)$/',$input);
+    }
+    
+    static function ipv4($input) {
+        return preg_match('/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/',$input);
+    }
+    
+    static function postCode($input) {
+        return preg_match('/^(\d{2,2})\-(\d{3,3})$/',$input);
+    }
+    
+    static function password($input) {
+        return preg_match('/[a-z]/',$input) && preg_match('/[A-Z]/',$input) && preg_match('/[0-9]/',$input);
+    }
+      
+    static function nip($input) {
+        if(!empty($input)) {
+            $weights = array(6, 5, 7, 2, 3, 4, 5, 6, 7);
+            $nip = preg_replace('/[\s-]/', '', $input);
+            if (strlen($nip) == 10 && is_numeric($nip)) {	 
+                $sum = 0;
+                for($i = 0; $i < 9; $i++)
+                    $sum += $nip[$i] * $weights[$i];
+                return ($sum % 11) == $nip[9];
+            }
+	}
+        return false;
+    }
+    
+    static function regon($input) {
+        return (Validator::regon9($input) || Validator::regon14($input));
+    }
+    
+    static function regon9($input) {
+        if(!empty($input)) {
+            $weights = array(8, 9, 2, 3, 4, 5, 6, 7);
+            $regon = preg_replace('/[\s-]/', '', $input);
+            if (strlen($regon) == 9 && is_numeric($regon)) {	 
+                $sum = 0;
+                for($i = 0; $i < 8; $i++)
+                    $sum += $regon[$i] * $weights[$i];
+                return ($sum % 11) == $regon[8];
+            }
+	}
+        return false;
+    }
+    
+    static function regon14($input) {
+        if(!empty($input)) {
+            $weights = array(2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8 );
+            $regon = preg_replace('/[\s-]/', '', $input);
+            if (strlen($regon) == 14 && is_numeric($regon)) {	 
+                $sum = 0;
+                for($i = 0; $i < 13; $i++)
+                    $sum += $regon[$i] * $weights[$i];
+                return ($sum % 11) == $regon[13];
+            }
+	}
+        return false;
+    }
+    
+    static function notEmpty($input) {
+        if (strlen($input) > 0) { return TRUE; } else { return FALSE; }
+    }
+    
+    static function filterScriptTags($html) {
+        $dom = new DOMDocument();
+        
+        $dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
+        
+        $script = $dom->getElementsByTagName('script');
+        $remove = [];
+        foreach($script as $item)
+        {
+          $remove[] = $item;
+        }
+        foreach ($remove as $item)
+        {
+          $item->parentNode->removeChild($item); 
+        }
+        $html = $dom->saveHTML();
+        return $html;
+    }
+    
+    static function filterNonAlphanum($input) {
+        return preg_replace("/[^a-z0-9_\-.:!?;ąćęłńóśźżĄĆĘŁŃÓŚŹŻ ]/is", "", $input);
+    }
+}
\ No newline at end of file

programming_language: PHP
filename: api.php
change_type: ModificationType.MODIFY
diff: @@ -44,8 +44,11 @@ if (getConfigItem('northboundApi')!='enabled') RESTfulError("API is disabled.",5
 if ($LM_STATGATHERING === TRUE && $endpoint == "STATS") {
     $seven = secureGETnum('sevenDayStats');
     $thirty = secureGETnum('thirtyDayStats');
+    if (empty($seven)) $seven = 0;
+    if (empty($thirty)) $thirty = 0;
+    
     $ip = get_remote_addr();
-    if ($seven >= 0 && $thirty >= 0) {
+    if ($seven > 0 && $thirty > 0) {
         //insert in db
         db_uquery("CREATE TABLE IF NOT EXISTS `lmglobalstats` (
         `statID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
@@ -57,6 +60,7 @@ if ($LM_STATGATHERING === TRUE && $endpoint == "STATS") {
         ) ENGINE = MYISAM ;");
         db_uquery("INSERT INTO `lmglobalstats` VALUES(DEFAULT, $seven, $thirty, '$ip', NOW())");
     }
+    //always return OK
     $ret = new stdClass();
     $ret->result = "ok";
     echo(encode($ret));

programming_language: PHP
filename: index.php
change_type: ModificationType.MODIFY
diff: @@ -1,141 +1,145 @@
-<?php
-/**********************************************************************************
-								LM Framework v3
-								
-	A simple PHP based application framework.
-	
-	Contact: pozniak.lukasz@gmail.com
-	
-	Copyright (c) 2005-2013, �ukasz Po�niak
-	All rights reserved.
-
-	Redistribution and use in source and binary forms, with or without modification,
-	are permitted provided that the following conditions are met:
-	
-	Redistributions of source code must retain the above copyright notice,
-	this list of conditions and the following disclaimer.
-	Redistributions in binary form must reproduce the above copyright notice,
-	this list of conditions and the following disclaimer in the documentation
-	and/or other materials provided with the distribution.
-	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-	THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
-	BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-	OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-	OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-	OF THE POSSIBILITY OF SUCH DAMAGE.
-
-**********************************************************************************/
-header('Content-Type: text/html; charset=UTF-8');
-
-if (!function_exists('mb_internal_encoding')) die('Please make sure you\'ve installed and enabled php-mbstring');
-
-mb_internal_encoding('UTF-8'); 
-mb_http_output('UTF-8'); 
-mb_http_input('UTF-8'); 
-mb_regex_encoding('UTF-8'); 
-
-set_include_path("../include");
-date_default_timezone_set(@date_default_timezone_get());
-if (!is_file('../config/config.php')) die('Config file not found.');
-include_once('../config/config.php'); //load config file
-include_once("db.php");  //db access functions
-include_once("log.php");  //logging facility
-include_once('auth.php'); //authentication and authorization
-include_once("lang.php");  //translations
-include_once("menu.php");  //menu
-include_once("template.php");  //templates
-include_once("csrf.php");  //anti-csrf token implementation (secure forms)
-include_once('configuration.php'); //configuration settings in db
-include_once('mobile.php'); //mobile device related functions
-include_once('hooks.php'); //hooks - login hook
-include_once('errorhandler.php'); //custom error handling
-
-$lmver="0.1.60 beta";
- 
-//setting session cookie params
-$param=session_get_cookie_params();
-session_set_cookie_params($LM_SESSION,$LM_COOKIEPATH,$param['domain'],$LM_COOKIESECUREONLY,true);
-session_start();
-//this prevents a forced logout after $LM_SESSION seconds
-//so the user session always lasts $LM_SESSION seconds after the last action in LMeve
-setcookie(session_name(),session_id(),time()+$LM_SESSION);
-
-//Security addon - regenerate session ID after HTTP->HTTPS redirect
-if ($_SESSION['regenerateID']===true) {
-    session_regenerate_id(true);
-    $_SESSION=array();
-}
-
-check_changed_session_ip(); //CHECK IF THE IP DID NOT CHANGE DURING SESSION
-check_changed_session_path(); //CHECK IF COOKIEPATH HAS CHANGED DURING SESSION
-//token_generate();
-
-//check if we force HTTPS, and if we do, check if we are indeed on HTTPS
-//if not, redirect user to HTTPS
-if($LM_FORCE_SSL && $_SERVER["HTTPS"] != "on")
-{
-    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
-    //Security addon - regenerate session ID after HTTP->HTTPS redirect
-    $_SESSION['regenerateID']=true;
-    exit();
-}
-//echo("PHP_SESS_ID=".session_id()." regenerateID=".$_SESSION['regenerateID']);
-
-if (isMobileUserAgent()) $MOBILE=1; else $MOBILE=0;
-
-$META = generate_meta();
-//$TITLE = "$LM_APP_NAME $lmver";
-
-//
-//AUTOLOGIN HERE IF YOU WANT
-//set the POST variable to the desired username and password
-//
-if ($LM_LOCKED==1) { //APP IS LOCKED!
-	//$MOBILE ? mobile_template_locked($META) : template_locked($META);
-        template_locked($META);
-} else { 			 //APP NOT LOCKED
-	if ($_SESSION['status']==0) { //NOT LOGGED ON
-		if (empty($_POST['login'])&&empty($_SESSION["status"])) { //NO LOGIN DATA? DISPLAY PROMPT
-                        //$MOBILE ? mobile_template_login($META) : template_login(generate_meta(null, generate_title("Login")));
-                        template_login(generate_meta(null, generate_title("Login")));
-		} else { //FILLED DATA? CHECK CREDENTIALS
-                        //if user table is empty, reset admin password
-                        resetAdminPassword();
-                        //check authorization
-			$granted=auth_user(addslashes($_POST['login']),addslashes($_POST['password']));
-			if ($granted>-1) { //LOGIN SUCCESS?
-				$_SESSION["granted"]=$granted;
-				$_SESSION["status"]=1;
-                                //LOGIN HOOK
-                                login_hook();
-				//redirect to MAIN WINDOW
-                                $contents = template_contents();
-                                $MOBILE ? mobile_template_main($contents,$TITLE,$META) : template_main($contents,$TITLE,$META);
-			} else { //LOGIN FAILURE?
-				//WRITE TO LOG FILE
-				$uzytk=htmlspecialchars($_POST['login']);
-				$do_logu=sprintf("<b>Bad logon!</b> login: <b>%s</b>.",$uzytk);
-				loguj("../var/access.txt",$do_logu);
-				$_SESSION=array();
-				//DISPLAY BAD LOGON
-                                $MOBILE ? mobile_template_badlogon() : template_badlogon();
-			}
-		}
-	} else if ($_SESSION['status']==1) { //LOGGED ON
-            check_expired_accounts();
-		if ($_GET['logoff']==1) { //TRYING TO LOG OUT?
-			$_SESSION=array();
-			$MOBILE ? mobile_template_logout() : template_logout();
-		} else { //MAIN WINDOW
-			updatelast(date('d.m.Y G:i'),get_remote_addr());
-                        $contents = template_contents();
-			$MOBILE ? mobile_template_main($contents,$TITLE,$META) : template_main($contents,$TITLE,$META);
-		}
-	}
-}
+<?php
+/**********************************************************************************
+								LM Framework v3
+								
+	A simple PHP based application framework.
+	
+	Contact: pozniak.lukasz@gmail.com
+	
+	Copyright (c) 2005-2013, �ukasz Po�niak
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification,
+	are permitted provided that the following conditions are met:
+	
+	Redistributions of source code must retain the above copyright notice,
+	this list of conditions and the following disclaimer.
+	Redistributions in binary form must reproduce the above copyright notice,
+	this list of conditions and the following disclaimer in the documentation
+	and/or other materials provided with the distribution.
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+	THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+	BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+	OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+	OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+	OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**********************************************************************************/
+header('Content-Type: text/html; charset=UTF-8');
+
+if (!function_exists('mb_internal_encoding')) die('Please make sure you\'ve installed and enabled php-mbstring');
+
+mb_internal_encoding('UTF-8'); 
+mb_http_output('UTF-8'); 
+mb_http_input('UTF-8'); 
+mb_regex_encoding('UTF-8'); 
+
+set_include_path("../include");
+date_default_timezone_set(@date_default_timezone_get());
+if (!is_file('../config/config.php')) die('Config file not found.');
+include_once('../config/config.php'); //load config file
+include_once("db.php");  //db access functions
+include_once("log.php");  //logging facility
+include_once('auth.php'); //authentication and authorization
+include_once("lang.php");  //translations
+include_once("menu.php");  //menu
+include_once("template.php");  //templates
+include_once("csrf.php");  //anti-csrf token implementation (secure forms)
+include_once('configuration.php'); //configuration settings in db
+include_once('mobile.php'); //mobile device related functions
+include_once('hooks.php'); //hooks - login hook
+include_once('errorhandler.php'); //custom error handling
+
+$lmver="0.1.60 beta";
+
+ini_set('display_errors', 1);
+ini_set('display_startup_errors', 1);
+error_reporting(E_ALL);
+ 
+//setting session cookie params
+session_set_cookie_params($LM_SESSION,parse_url($LM_COOKIEPATH, PHP_URL_PATH),parse_url($LM_COOKIEPATH, PHP_URL_HOST),$LM_COOKIESECUREONLY,true);
+$ret = session_start();
+if ($ret === FALSE) die("Unable to open session. session_start() returned FALSE.");
+//this prevents a forced logout after $LM_SESSION seconds
+//so the user session always lasts $LM_SESSION seconds after the last action in LMeve
+setcookie(session_name(),session_id(),time()+$LM_SESSION);
+
+//Security addon - regenerate session ID after HTTP->HTTPS redirect
+if ($_SESSION['regenerateID']===true) {
+    session_regenerate_id(true);
+    $_SESSION=array();
+}
+
+check_changed_session_ip(); //CHECK IF THE IP DID NOT CHANGE DURING SESSION
+check_changed_session_path(); //CHECK IF COOKIEPATH HAS CHANGED DURING SESSION
+//token_generate();
+
+//check if we force HTTPS, and if we do, check if we are indeed on HTTPS
+//if not, redirect user to HTTPS
+if($LM_FORCE_SSL && $_SERVER["HTTPS"] != "on")
+{
+    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
+    //Security addon - regenerate session ID after HTTP->HTTPS redirect
+    $_SESSION['regenerateID']=true;
+    exit();
+}
+//echo("PHP_SESS_ID=".session_id()." regenerateID=".$_SESSION['regenerateID']);
+
+if (isMobileUserAgent()) $MOBILE=1; else $MOBILE=0;
+
+$META = generate_meta();
+//$TITLE = "$LM_APP_NAME $lmver";
+
+//
+//AUTOLOGIN HERE IF YOU WANT
+//set the POST variable to the desired username and password
+//
+if ($LM_LOCKED==1) { //APP IS LOCKED!
+	//$MOBILE ? mobile_template_locked($META) : template_locked($META);
+        template_locked($META);
+} else { 			 //APP NOT LOCKED
+	if ($_SESSION['status']==0) { //NOT LOGGED ON
+		if (empty($_POST['login'])&&empty($_SESSION["status"])) { //NO LOGIN DATA? DISPLAY PROMPT
+                        //$MOBILE ? mobile_template_login($META) : template_login(generate_meta(null, generate_title("Login")));
+                        template_login(generate_meta(null, generate_title("Login")));
+		} else { //FILLED DATA? CHECK CREDENTIALS
+                        //if user table is empty, reset admin password
+                        resetAdminPassword();
+                        //check authorization
+			$granted=auth_user(addslashes($_POST['login']),addslashes($_POST['password']));
+			if ($granted>-1) { //LOGIN SUCCESS?
+				$_SESSION["granted"]=$granted;
+				$_SESSION["status"]=1;
+                                //LOGIN HOOK
+                                login_hook();
+				//redirect to MAIN WINDOW
+                                $contents = template_contents();
+                                $MOBILE ? mobile_template_main($contents,$TITLE,$META) : template_main($contents,$TITLE,$META);
+			} else { //LOGIN FAILURE?
+				//WRITE TO LOG FILE
+				$uzytk=htmlspecialchars($_POST['login']);
+				$do_logu=sprintf("<b>Bad logon!</b> login: <b>%s</b>.",$uzytk);
+				loguj("../var/access.txt",$do_logu);
+				$_SESSION=array();
+				//DISPLAY BAD LOGON
+                                $MOBILE ? mobile_template_badlogon() : template_badlogon();
+			}
+		}
+	} else if ($_SESSION['status']==1) { //LOGGED ON
+            check_expired_accounts();
+		if ($_GET['logoff']==1) { //TRYING TO LOG OUT?
+			$_SESSION=array();
+			$MOBILE ? mobile_template_logout() : template_logout();
+		} else { //MAIN WINDOW
+			updatelast(date('d.m.Y G:i'),get_remote_addr());
+                        $contents = template_contents();
+			$MOBILE ? mobile_template_main($contents,$TITLE,$META) : template_main($contents,$TITLE,$META);
+		}
+	}
+}
 ?>
\ No newline at end of file

programming_language: PHP