Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

include/Sugarpdf/FontManager.php (9 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2 1
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3
/*********************************************************************************
4
 * SugarCRM Community Edition is a customer relationship management program developed by
5
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6
7
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
8
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
9
 *
10
 * This program is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU Affero General Public License version 3 as published by the
12
 * Free Software Foundation with the addition of the following permission added
13
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
14
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
15
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
16
 *
17
 * This program is distributed in the hope that it will be useful, but WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
20
 * details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License along with
23
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
24
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
 * 02110-1301 USA.
26
 *
27
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
28
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
29
 *
30
 * The interactive user interfaces in modified source and object code versions
31
 * of this program must display Appropriate Legal Notices, as required under
32
 * Section 5 of the GNU Affero General Public License version 3.
33
 *
34
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
35
 * these Appropriate Legal Notices must retain the display of the "Powered by
36
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
37
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
38
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
39
 ********************************************************************************/
40
41 1
require_once("include/Sugarpdf/sugarpdf_config.php");
42
class FontManager{
43
    /**
44
     * Contain all the errors generated during the process of FontManager
45
     * @var String[]
46
     */
47
    var $errors = array();
48
    /**
49
     * store the log string when addFont is call
50
     * @var String
51
     */
52
    var $log = "";
53
    /**
54
     * Current font filename
55
     * @var String
56
     */
57
    var $filename = "";
58
     /**
59
     * Current font file path
60
     * @var String
61
     */
62
    var $fontPath = "";
63
    /**
64
     * Multidimentional array which contain all the detail of all the available fonts
65
     * @var Array
66
     */
67
    var $fontList = array();
68
    /**
69
     * Name of the font of the current font file
70
     * @var String
71
     */
72
    var $font_name = "";
73
    /**
74
     * Encoding of the current font
75
     * @var String
76
     */
77
    var $font_enc = "";
78
    /**
79
     * Display name of the current font
80
     * @var String
81
     */
82
    var $font_displayname = "";
83
    /**
84
     * Type of the current font
85
     * @var String
86
     */
87
    var $font_type = "";
88
89 1
    private function setFontPath(){
90 1
        if(file_exists(K_PATH_CUSTOM_FONTS.$this->filename)){
91
            $this->fontPath = K_PATH_CUSTOM_FONTS;
92 1
        }else if(file_exists(K_PATH_FONTS.$this->filename)){
93 1
            $this->fontPath = K_PATH_FONTS;
94
        }else{
95
            $this->fontPath = "";
96
            array_push($this->errors,  "Unable to find the font!");
97
        }
98 1
    }
99
    /**
100
     * This method return a boolean which describe if the font define
101
     * in filename is embedded or not.
102
     * @return boolean true if embedded.
103
     */
104
    private function getEmbedded(){
105
        if(empty($this->fontList[$this->getFilenameShort()]['type'])){
106
            if(!$this->loadFontFile()){
107
                array_push($this->errors,  translate('ERR_LOADFONTFILE', 'Configurator'));
108
                return false;
109
            }
110
        }
111
        if($this->font_type == "cidfont0" || $this->font_type == "core"){
112
            return false;
113
        }
114
        return true;
115
    }
116
    /**
117
     * This method return the style of the given font set in filename
118
     * Values can be regular, bold, italic.
119
     * @return array of styles on success
120
     * @return empty array on failure
121
     */
122
    private function getStyle(){
123
        if(empty($this->filename)){
124
            array_push($this->errors,  translate("ERR_FONT_EMPTYFILE","Configurator"));
125
            return array();
126
        }
127
        if(preg_match("/bi.php$/i",$this->filename)){
128
            return array("bold","italic");
129
        }else if(preg_match("/ib.php$/i",$this->filename)){
130
            return array("bold","italic");
131
        }else if(preg_match("/b.php$/i",$this->filename)){
132
            return array("bold");
133
        }else if(preg_match("/i.php$/i",$this->filename)){
134
            return array("italic");
135
        }else{
136
            return array("regular");
137
        }
138
    }
139
    /**
140
     * This method calculate the font size of $this->filename in KB
141
     * .php file + .z file + .ctg.z file
142
     * @return Integer font Size in KB
143
     */
144
    private function getFontSize(){
145
        $fileSize=filesize($this->fontPath.$this->filename);
146
        $name = substr($this->filename, 0, strrpos($this->filename, '.'));
147
        if(file_exists($this->fontPath.$name.".z")){
148
            $fileSize+=filesize($this->fontPath.$name.".z");
149
        }
150
        if(file_exists($this->fontPath.$name.".ctg.z")){
151
            $fileSize+=filesize($this->fontPath.$name.".ctg.z");
152
        }
153
        return round($fileSize/1024);
154
    }
155
    /**
156
     * Fill the fontList attribute with the data contains in the font file.
157
     */
158 1
    public function getDetail(){
159 1
        if($this->loadFontFile()){
160
            $this->fontList[$this->getFilenameShort()]['filename'] = $this->filename;
161
            $this->fontList[$this->getFilenameShort()]['fontpath'] = $this->fontPath;
162
            if(!empty($this->font_name)){
163
                $this->fontList[$this->getFilenameShort()]['name'] = $this->font_name;
164
            }else{
165
                $this->fontList[$this->getFilenameShort()]['name'] = $this->getFilenameShort();
166
            }
167
            if(!empty($this->font_displayname)){
168
                $this->fontList[$this->getFilenameShort()]['displayname'] = $this->font_displayname;
169
            }
170
            if(!empty($this->font_enc)){
171
                $this->fontList[$this->getFilenameShort()]['enc'] = $this->font_enc;
172
            }
173
            if(!empty($this->font_type)){
174
                if ($this->font_type == 'cidfont0' || $this->font_type == 'core' || $this->font_type == 'TrueType' || $this->font_type == 'Type1' || $this->font_type == 'TrueTypeUnicode') {
175
                    $this->fontList[$this->getFilenameShort()]['type'] = $this->font_type;
176
                }else{
177
                    array_push($this->errors,  translate("ERR_FONT_UNKNOW_TYPE","Configurator") . " " . $this->font_type);
178
                }
179
            }
180
            $this->fontList[$this->getFilenameShort()]['style'] = $this->getStyle();
181
            $this->fontList[$this->getFilenameShort()]['filesize'] = $this->getFontSize();
182
            $this->fontList[$this->getFilenameShort()]['embedded'] = $this->getEmbedded();
183
            return true;
184
        }
185 1
        return false;
186
    }
187
    /**
188
     * This method load the font file and check if it is good formatted.
189
     * @return boolean true on success
190
     */
191 1
    private function loadFontFile(){
192 1
        if(empty($this->filename))
193
            return false;
194 1
        $this->setFontPath();
195 1
        if(!file_exists($this->fontPath.$this->filename)){
196
            return false;
197
        }
198 1
        @include($this->fontPath.$this->filename);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
199 1
        if ((!isset($type)) OR (!isset($cw))) {
0 ignored issues
show
The variable $type seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
The variable $cw seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
200
            //The font definition file has a bad format
201 1
            return false;
202
        }
203
204
        $this->font_name = "";
205
        $this->font_enc = "";
206
        $this->font_displayname = "";
207
        $this->font_type = "";
208
209
        if(!empty($name)){
0 ignored issues
show
The variable $name seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
210
            $this->font_name = $name;
211
        }
212
        if(!empty($enc)){
0 ignored issues
show
The variable $enc seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
213
            $this->font_enc = $enc;
214
        }
215
        if(!empty($displayname)){
0 ignored issues
show
The variable $displayname seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
216
            $this->font_displayname = $displayname;
217
        }
218
        if(!empty($type)){
219
            $this->font_type = $type;
220
        }
221
        return true;
222
    }
223
    /**
224
     * This method parse the font path defined in the sugarpdf config file
225
     * and fill the fontList
226
     * @return boolean true if font files have been found
227
     */
228 1
    private function parseFolder(){
229 1
        if(!file_exists(K_PATH_FONTS) || !is_dir(K_PATH_FONTS)){
230
            array_push($this->errors, translate("ERR_NO_FONT_PATH","Configurator"));
231
            return false;
232
        }
233 1
        $result[0] = scandir(K_PATH_FONTS);
234 1
        if(file_exists(K_PATH_CUSTOM_FONTS) && is_dir(K_PATH_CUSTOM_FONTS)){
235
            $result[1] = scandir(K_PATH_CUSTOM_FONTS);
236
        }
237 1
        foreach($result as $v){
238 1
            foreach($v as $vv){
239 1
                if(preg_match("/.php$/i",$vv)){
240 1
                    $this->filename = $vv;
241 1
                    $this->getDetail();
242
                }
243
            }
244
        }
245 1
        ksort($this->fontList);
246 1
        if(count($this->fontList)>0){
247
            return true;
248
        }else{
249 1
            return false;
250
        }
251
    }
252
    /**
253
     * This method fill the fontList with all the fonts available
254
     */
255 1
    public function listFontFiles(){
256 1
        $this->fontList=array();
257 1
        if(file_exists($cachedfile = sugar_cached("Sugarpdf/cachedFontList.php"))) {
258
            require $cachedfile;
259
            $this->fontList=$cachedFontList;
260
            return true;
261
        }else{
262 1
            if($this->parseFolder()){
263
                $cacheDir = create_cache_directory('Sugarpdf/');
264
                write_array_to_file('cachedFontList', $this->fontList, $cacheDir . 'cachedFontList.php');
265
                return true;
266
            }
267
        }
268 1
        return false;
269
    }
270
    /**
271
     * This method generate an array of font which can be use with get_select_options_with_id
272
     * @return Array
273
     */
274
    public function getSelectFontList(){
275
        $returnArray = array();
276
        if($this->listFontFiles()){
277
            foreach($this->fontList as $k=>$v){
278
                if(!empty($v['displayname'])){
279
                    $returnArray[$k]=$v['displayname'];
280
                }else{
281
                    $returnArray[$k]=$v['name'];
282
                }
283
            }
284
        }
285
        return $returnArray;
286
    }
287
    /**
288
     * This method return the filename without the ".php"
289
     * @return String The short filename
290
     */
291
    private function getFilenameShort(){
292
        return preg_replace("/.php$/i", "",$this->filename);
293
    }
294
    /**
295
     * This method delete all the files related to the font define in the filename attribute.
296
     * @return boolean true on success
297
     */
298
    public function deleteFont(){
299
        global $current_user;
300
        if(!is_admin($current_user)){
301
            sugar_die($GLOBALS['app_strings']['ERR_NOT_ADMIN']);
302
        }
303
        $this->loadFontFile();
304
        if($this->font_type == "core" || $this->fontPath == K_PATH_FONTS){
305
            array_push($this->errors, translate("ERR_DELETE_CORE_FILE","Configurator"));
306
             return false;
307
        }
308
        if(file_exists($this->fontPath.$this->filename)){
309
            if(is_writable($this->fontPath.$this->filename)){
310
                unlink($this->fontPath.$this->filename);
311
                if(file_exists($this->fontPath.$this->getFilenameShort().".ctg.z") && is_writable($this->fontPath.$this->getFilenameShort().".ctg.z")){
312
                    unlink($this->fontPath.$this->getFilenameShort()."ctg.z");
313
                }
314
                if(file_exists($this->fontPath.$this->getFilenameShort().".z") && is_writable($this->fontPath.$this->getFilenameShort().".z")){
315
                    unlink($this->fontPath.$this->getFilenameShort().".z");
316
                }
317
                $this->clearCachedFile();
318
                return true;
319
            }else{
320
                array_push($this->errors, $this->fontPath.$this->filename . " " . translate("ERR_FONT_NOT_WRITABLE","Configurator"));
321
            }
322
        }else{
323
            array_push($this->errors, $this->fontPath . " " . translate("ERR_FONT_FILE_DO_NOT_EXIST","Configurator"));
324
        }
325
        return false;
326
    }
327
    /**
328
     * This method add a font to SugarCRM from a font file and a metric file using MakeFont()
329
     * @param $font_file string
330
     * @param $metric_file string
331
     * @param $embedded boolean
332
     * @param $encoding_table string
333
     * @param $patch array
334
     * @param $cid_info string
335
     * @param $style string
336
     * @return boolean true on success
337
     * @see MakeFont() in K_PATH_FONTS/utils
338
     */
339
    public function addFont($font_file, $metric_file, $embedded=true, $encoding_table='cp1252', $patch=array(), $cid_info="", $style="regular"){
340
        global $current_user;
341
        if(!is_admin($current_user)){
342
            sugar_die($GLOBALS['app_strings']['ERR_NOT_ADMIN']);
343
        }
344
        $error=false;
345
346
        $oldStr=ob_get_contents();
347
        ob_clean();
348
        require_once("include/tcpdf/fonts/utils/makefont.php");
349
        $filename = MakeFont($font_file,$metric_file, $embedded, $encoding_table, $patch, $cid_info);
350
351
        unlink($font_file);
352
        unlink($metric_file);
353
354
        $this->log=ob_get_contents();
355
        ob_clean();
356
357
        echo $oldStr;
358
359
        if(empty($filename)){
360
            array_push($this->errors, translate("ERR_FONT_MAKEFONT","Configurator"));
361
            $error=true;
362
        }else{
363
            require_once("include/utils/file_utils.php");
364
            $this->filename = basename($filename.".php");
365
            if(!$this->loadFontFile()){
366
                if(!mkdir_recursive(K_PATH_CUSTOM_FONTS)){
367
                    array_push($this->errors, "Error : Impossible to create the custom font directory.");
368
                    $error=true;
369
                }else{
370
                    $styleLetter="";
371
                    switch($style){
372
                        case "italic":
373
                            $styleLetter="i";break;
0 ignored issues
show
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
374
                        case "bold":
375
                            $styleLetter="b";break;
0 ignored issues
show
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
376
                        case "boldItalic":
377
                            $styleLetter="bi";break;
0 ignored issues
show
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
378
                        default:
379
                            $styleLetter="";
380
                    }
381
                    sugar_rename($filename.".php", K_PATH_CUSTOM_FONTS.basename($filename.$styleLetter.".php"));
382
                    $this->log .= "\n" . translate("LBL_FONT_MOVE_DEFFILE","Configurator") . K_PATH_CUSTOM_FONTS.basename($filename.$styleLetter.".php");
383
                    if(file_exists($filename.".z")){
384
                        sugar_rename($filename.".z", K_PATH_CUSTOM_FONTS.basename($filename.$styleLetter.".z"));
385
                        $this->log .= "\n" . translate("LBL_FONT_MOVE_FILE","Configurator") . K_PATH_CUSTOM_FONTS.basename($filename.$styleLetter.".z");
386
                    }
387
                    if(file_exists($filename.".ctg.z")){
388
                        sugar_rename($filename.".ctg.z", K_PATH_CUSTOM_FONTS.basename($filename.$styleLetter.".ctg.z"));
389
                        $this->log .= "\n" . translate("LBL_FONT_MOVE_FILE","Configurator") . K_PATH_CUSTOM_FONTS.basename($filename.$styleLetter.".ctg.z");
390
                    }
391
                }
392
            }else{
393
                array_push($this->errors, "\n".translate("ERR_FONT_ALREADY_EXIST","Configurator"));
394
                $error=true;
395
            }
396
            if($error){
397
                if(file_exists($filename.".php"))
398
                    unlink($filename.".php");
399
                if(file_exists($filename.".ctg.z"))
400
                    unlink($filename.".ctg.z");
401
                if(file_exists($filename.".z"))
402
                    unlink($filename.".z");
403
            }
404
405
        }
406
        $this->clearCachedFile();
407
        return $error;
408
    }
409
    /**
410
     * This method  delete the cached file cachedFontList.php
411
     * @return boolean
412
     */
413
    public function clearCachedFile(){
414
        global $current_user;
415
        if(!is_admin($current_user)){
416
            sugar_die($GLOBALS['app_strings']['ERR_NOT_ADMIN']);
417
        }
418
         if(file_exists($cachedfile = sugar_cached("Sugarpdf/cachedFontList.php"))) {
419
            return unlink($cachedfile);
420
        }
421
        return true;
422
    }
423
    /**
424
     * Check if the given font filename exist in the font directories
425
     * @return boolean
426
     */
427
    public function fontFileExist($filename){
428
        $this->filename = $filename;
429
        return $this->loadFontFile();
430
    }
431
}
432
433
?>