From f014a82776c27a7b4250da3e9db842ae8bdb28cb Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared@osticket.com>
Date: Fri, 17 Jan 2014 09:49:28 -0600
Subject: [PATCH] Make using `realpath` safer

---
 api/cron.php                 | 2 +-
 api/pipe.php                 | 2 +-
 bootstrap.php                | 6 +++++-
 client.inc.php               | 2 +-
 include/class.i18n.php       | 2 +-
 include/class.misc.php       | 5 +++++
 include/class.pdf.php        | 2 +-
 pages/index.php              | 2 +-
 setup/cli/modules/deploy.php | 4 ++--
 setup/cli/modules/unpack.php | 2 +-
 10 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/api/cron.php b/api/cron.php
index f5d47e43e..787460ee7 100644
--- a/api/cron.php
+++ b/api/cron.php
@@ -13,7 +13,7 @@
 
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
-@chdir(realpath(dirname(__FILE__)).'/'); //Change dir.
+@chdir(dirname(__FILE__).'/'); //Change dir.
 require('api.inc.php');
 
 if (!osTicket::is_cli())
diff --git a/api/pipe.php b/api/pipe.php
index 7cf1ad1b4..249cfc8a7 100644
--- a/api/pipe.php
+++ b/api/pipe.php
@@ -15,7 +15,7 @@
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
 ini_set('memory_limit', '256M'); //The concern here is having enough mem for emails with attachments.
-@chdir(realpath(dirname(__FILE__)).'/'); //Change dir.
+@chdir(dirname(__FILE__).'/'); //Change dir.
 require('api.inc.php');
 
 //Only local piping supported via pipe.php
diff --git a/bootstrap.php b/bootstrap.php
index ff7cf6b64..5aaad77ba 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -261,7 +261,11 @@ class Bootstrap {
 }
 
 #Get real path for root dir ---linux and windows
-define('ROOT_DIR',str_replace('\\', '/', realpath(dirname(__FILE__))).'/');
+$here = dirname(__FILE__);
+$here = ($h = realpath($here)) ? $h : $here;
+define('ROOT_DIR',str_replace('\\', '/', $here.'/'));
+unset($here); unset($h);
+
 define('INCLUDE_DIR',ROOT_DIR.'include/'); //Change this if include is moved outside the web path.
 define('PEAR_DIR',INCLUDE_DIR.'pear/');
 define('SETUP_DIR',ROOT_DIR.'setup/');
diff --git a/client.inc.php b/client.inc.php
index 2ab016d15..7aeae56ee 100644
--- a/client.inc.php
+++ b/client.inc.php
@@ -15,7 +15,7 @@
 **********************************************************************/
 if(!strcasecmp(basename($_SERVER['SCRIPT_NAME']),basename(__FILE__))) die('kwaheri rafiki!');
 
-$thisdir=str_replace('\\', '/', realpath(dirname(__FILE__))).'/';
+$thisdir=str_replace('\\', '/', dirname(__FILE__)).'/';
 if(!file_exists($thisdir.'main.inc.php')) die('Fatal Error.');
 
 require_once($thisdir.'main.inc.php');
diff --git a/include/class.i18n.php b/include/class.i18n.php
index 7891d7ef9..c1f6bcf36 100644
--- a/include/class.i18n.php
+++ b/include/class.i18n.php
@@ -150,7 +150,7 @@ class DataTemplate {
         foreach ($langs as $l) {
             if (file_exists("{$this->base}/$l/$path")) {
                 $this->lang = $l;
-                $this->filepath = realpath("{$this->base}/$l/$path");
+                $this->filepath = Misc::realpath("{$this->base}/$l/$path");
                 break;
             }
         }
diff --git a/include/class.misc.php b/include/class.misc.php
index 41edef9f6..e0b9559b9 100644
--- a/include/class.misc.php
+++ b/include/class.misc.php
@@ -139,5 +139,10 @@ class Misc {
         return $output;
     }
 
+    function realpath($path) {
+        $rp = realpath($path);
+        return $rp ? $rp : $path;
+    }
+
 }
 ?>
diff --git a/include/class.pdf.php b/include/class.pdf.php
index 1555de772..8346ee3c7 100644
--- a/include/class.pdf.php
+++ b/include/class.pdf.php
@@ -14,7 +14,7 @@
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
 
-define('THIS_DIR', str_replace('\\', '/', realpath(dirname(__FILE__))) . '/'); //Include path..
+define('THIS_DIR', str_replace('\\', '/', Misc::realpath(dirname(__FILE__))) . '/'); //Include path..
 
 require_once(INCLUDE_DIR.'mpdf/mpdf.php');
 
diff --git a/pages/index.php b/pages/index.php
index fc65aebc1..f64685835 100644
--- a/pages/index.php
+++ b/pages/index.php
@@ -14,7 +14,7 @@
 
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
-@chdir(realpath(dirname(__file__).'/../'));
+@chdir(dirname(__file__).'/../');
 
 require_once('client.inc.php');
 require_once(INCLUDE_DIR.'class.format.php');
diff --git a/setup/cli/modules/deploy.php b/setup/cli/modules/deploy.php
index aa123bfcb..8fc0e142b 100644
--- a/setup/cli/modules/deploy.php
+++ b/setup/cli/modules/deploy.php
@@ -35,7 +35,7 @@ class Deployment extends Unpacker {
             if (is_file($start . '/main.inc.php')) break;
             $start .= '/..';
         }
-        return realpath($start);
+        return Misc::realpath($start);
     }
 
     /**
@@ -92,7 +92,7 @@ class Deployment extends Unpacker {
         if (!is_dir($this->destination))
             if (!@mkdir($this->destination, 0751, true))
                 die("Destination path does not exist and cannot be created");
-        $this->destination = realpath($this->destination).'/';
+        $this->destination = Misc::realpath($this->destination).'/';
 
         # Determine if this is an upgrade, and if so, where the include/
         # folder is currently located
diff --git a/setup/cli/modules/unpack.php b/setup/cli/modules/unpack.php
index 55fe6ab5a..3411c94eb 100644
--- a/setup/cli/modules/unpack.php
+++ b/setup/cli/modules/unpack.php
@@ -41,7 +41,7 @@ class Unpacker extends Module {
             if (is_dir($start . '/upload')) break;
             $start .= '/..';
         }
-        return realpath($start.'/upload');
+        return Misc::realpath($start.'/upload');
     }
 
     function change_include_dir($include_path) {
-- 
GitLab