Completed
Push — master ( fb7e4a...39c625 )
by
unknown
12:08
created

FPDM::fix_xref_start()   F

Complexity

Conditions 13
Paths 504

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 33
rs 3.1065
cc 13
eloc 21
nc 504
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*******************************************************************************
4
* FPDM                                                                         *
5
*                                                                              *
6
*@file    fpdm.php                                                             *
7
*@name    A free PDF form filling tool                                         *
8
*@package fpdftk                                                               *
9
*@version 2.8                                                                  *
10
*@date    2011-12-31                                                           *
11
*@author  0livier                                                              *
12
*@todo in the importance order, natively by fpdm                               *
13
*	 -stream inline support (content change,repack,offset/size calculations)   *
14
*	 -pdf inline protection                                                    *
15
*	 -flatten support          												   *
16
*	 -extends filling to another form fields types (checkboxes,combos..)       *
17
*@note   	                                                                   *
18
*	V2.8 (31.12.2011) added UTF-8 support                                      *
19
*	V2.7 (29.12.2011) compatibility with PDFs generated by pdftk               *
20
*	V2.6 (25.12.2010) OpenOffice 3 compatibility issues for Florian            *
21
*		see	tracking issue here: http://www.fpdf.org/?go=forum&i=53697&t=53697 *
22
*	V2.5 (06.12.2010) pdftk support for flatten mode and more...special        *
23
*	christmas release to the fpdf fanclub even if the red guy is busy	       *
24
*	V2.4 (01.12.2010) Hack for malformed stream definitions, new parsing and   *
25
*	stream core	with advanced verbose output. Fix() bonus for corrupted pdfs.  *
26
*	V2.3 (28.11.2010) stream type was lost when /length defined after /Filter  *
27
*	V2.2 (27.11.2010) Stream filter improved:decode now handles multi filters! *                                                      *
28
*	V2.1 (25.11.2010) Only filter support for streams, trailer detection was   * 
29
*	too restrictive. fixes FDF error occuring when empty array data is given.  *
30
*   V2.0 (05.11.2010) Load support for inline text fields datas or FDF content *
31
*	V1.1 (04.11.2010) Works now under php4 for backward compat.                *
32
* 	V1.0 (03.11.2010) First working release                                    *
33
*******************************************************************************/
34
35
$FPDM_FILTERS=array(); //holds all supported filters
36
$FPDM_REGEXPS= array(
37
	"/Type"=>"/\/Type\s+\/(\w+)$/",
38
	"/Subtype" =>"/^\/Subtype\s+\/(\w+)$/"
39
);
40
41
//Major stream filters come from FPDI's stuff but I've added some :)
42
require_once(APP_DIR . "/fpdm/filters/FilterASCIIHex.php");
43
require_once(APP_DIR . "/fpdm/filters/FilterASCII85.php");
44
require_once(APP_DIR . "/fpdm/filters/FilterFlate.php");
45
require_once(APP_DIR . "/fpdm/filters/FilterLZW.php");
46
require_once(APP_DIR . "/fpdm/filters/FilterStandard.php");
47
48
49
$__tmp = version_compare(phpversion(), "5") == -1 ? array('FPDM') : array('FPDM', false);
50
if (!call_user_func_array('class_exists', $__tmp)) {
51
    
52
	
53
	define('FPDM_VERSION',2.6); 
54
	define('FPDM_RELEASE',"Snowstream forever dream(20101225)");
55
	
56
	define('FPDM_INVALID',0);
57
	define('FPDM_STATIC',1);
58
	define('FPDM_COMMON',2);
59
	define('FPDM_VERBOSE',3);
60
	define('FPDM_CACHE',dirname(__FILE__).'/export/cache/'); //cache directory for fdf temporary files needed by pdftk.
61
	define('FPDM_PASSWORD_MAX_LEN',15); //Security to prevent shell overflow.
62
	
63
    class FPDM {
64
    //@@@@@@@@@
65
	
66
		private $FPDM_FILTERS = array();
67
    	private $FPDM_REGEXPS = array(
68
									"/Type"=>"/\/Type\s+\/(\w+)$/",
69
									"/Subtype" =>"/^\/Subtype\s+\/(\w+)$/"
70
								);
71
        var $pdf_source;      //string: full pathname to the input pdf , a form file
72
        var $fdf_source;	  //string: full pathname to the input fdf , a form data file
73
		var $pdf_output;      //string: full pathname to the resulting filled pdf 
74
		
75
        var $pdf_entries;     //array: Holds the content of the pdf file as array
76
		var $fdf_content;     //string: holds the content of the fdf file
77
		var $fdf_parse_needed;//boolean: false will use $fields data else extract data from fdf content 
78
		var $value_entries;   //array: a map of values to faliclitate access and changes 
79
        
80
		var $positions; 	  //array, stores what object id is at a given position n ($positions[n]=<obj_id>)
81
		
82
		var $offsets;   	  //array of offsets for objects, index is the object's id, starting at 1
83
		var $pointer;   	  //integer, Current line position in the pdf file during the parsing 
84
		
85
		var $shifts;    	  //array, Shifts of objects in the order positions they appear in the pdf, starting at 0.
86
		var $shift;     	  //integer, Global shift file size due to object values size changes
87
		
88
		var $streams;         //Holds streams configuration found during parsing
89
		var $streams_filter;  //Regexp to decode filter streams
90
		
91
		var $safe_mode;       //boolean, if set, ignore previous offsets do no calculations for the new xref table, seek pos directly in file
92
		var $check_mode;      //boolean, Use this to track offset calculations errors in corrupteds pdfs files for sample
93
		var $halt_mode; 	  //if true, stops when offset error is encountered
94
		
95
		var $info; 			  //array, holds the info properties
96
        var $fields; 		  //array that holds fields-Data parsed from FDF
97
		
98
		var $verbose;         //boolean ,  a debug flag to decide whether or not to show internal process 
99
		var $verbose_level;   //integer default is 1 and if greater than 3, shows internal parsing as well
100
		
101
		var $support; 		  //string set to 'native' for fpdm or 'pdftk' for pdf toolkit
102
		var $flatten_mode;	  //if true, flatten field data as text and remove form fields (NOT YET SUPPORTED BY FPDM)
103
		var $compress_mode;   //boolean , pdftk feature only to compress streams
104
		var $uncompress_mode; //boolean pdftk feature only to uncompress streams
105
		var $security;        //Array holding securtity settings  
106
							  //(password owner nad user,  encrypt (set to 40 or 128 or 0), allow <permissions>] see pdfk help
107
108
		var $needAppearancesTrue;	//boolean, indicates if /NeedAppearances is already set to true
109
		var $isUTF8;				//boolean (true for UTF-8, false for ISO-8859-1)
110
		
111
        /**
112
         * Constructor
113
         *
114
		 *@example Common use:
115
         *@param string $pdf_source Source-Filename
0 ignored issues
show
Bug introduced by
There is no parameter named $pdf_source. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
116
		 *@param string $fdf_source Source-Filename
0 ignored issues
show
Bug introduced by
There is no parameter named $fdf_source. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
117
		 *@param boolean $verbose , optional false per default
0 ignored issues
show
Bug introduced by
There is no parameter named $verbose. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
118
         */
119
    	function FPDM() { 
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
120
		//==============
121
		
122
			$args=func_get_args();
123
			$num_args=func_num_args();
124
			
125
			$FDF_FILE=($num_args>=FPDM_COMMON);
126
			$VERBOSE_FLAG=($num_args>=FPDM_VERBOSE);
127
			
128
			$verbose=false;
129
			
130
			//We are not joking here, let's have a polymorphic constructor!
131
			switch($num_args) {
132
				case FPDM_INVALID:
133
					$this->Error("Invalid instantiation of FPDM, requires at least one param");
134
					break;
135
				case FPDM_STATIC: 
136
					if($args[0] =='[_STATIC_]')  break; //static use, caller is anonymous function defined in _set_field_value 
137
					//else this is the pdf_source then, fdf content is loaded using Load() function
138
				default:
139
				case FPDM_VERBOSE: //Use the verbose value provided
0 ignored issues
show
Unused Code introduced by
case FPDM_VERBOSE: /...rbose = $args[2]; } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
140
					if($VERBOSE_FLAG) $verbose=$args[2];
141
				case FPDM_COMMON: //Common use
142
					$this->pdf_source = $args[0];//Blank pdf form
143
					
144
					if($FDF_FILE) {
145
						$this->fdf_source = $args[1];//Holds the data of the fields to fill the form
146
						$this->fdf_parse_needed=true; 
147
					}
148
					
149
					//calculation and map
150
					$this->offsets=array();
151
					$this->pointer=0;
152
					$this->shift=0;
153
					$this->shifts=array();
154
					$this->n=0;
0 ignored issues
show
Bug introduced by
The property n does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
155
					
156
					//Stream filters
157
					$filters=$this->getFilters("|");
158
					$this->streams_filter="/(\/($filters))+/";
159
					//$this->dumpContent($this->streams_filter);
160
					
161
					$this->info=array();
162
					
163
					//Debug modes
164
					$this->verbose=$verbose;
165
					$this->verbose_level=($verbose&&is_int($verbose)) ? $verbose : 1; 
166
					$this->safe_mode=false;
167
					$this->check_mode=false; //script will takes much more time if you do so
168
					$this->halt_mode=true;
169
					
170
					$this->support='native'; //may ne overriden
171
					$this->security=array('password'=>array('owner'=>null,'user'=>null),'encrypt'=>0,'allow'=>array());
172
					
173
					//echo "<br>filesize:".filesize($this->pdf_source);
174
					$this->load_file('PDF');
175
					
176
					if($FDF_FILE) $this->load_file('FDF');
177
						
178
			}
179
        }
180
		
181
		/**
182
		*Loads a form data to be merged
183
		*
184
		*@note this overrides fdf input source if it was previously defined
185
		*@access public
186
		*@param string|array $fdf_data a FDF file content or $pdf_data an array containing the values for the fields to change
0 ignored issues
show
Bug introduced by
There is no parameter named $fdf_data. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
187
		**/
188
		function Load($data,$isUTF8=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
189
		//------------------------
190
			$this->isUTF8 = $isUTF8;
191
			$this->load_file('FDF',$data);
192
		}
193
		
194
		/**
195
		*Loads a file according to its type
196
		*
197
		*@access private
198
		*@param string type 'PDF' or 'FDF'
199
		*@param String|array content the data content of FDF files only or directly the fields values as array 
200
		**/
201
		function load_file($type,$content=NULL) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
202
		//------------------------------------
203
			 switch($type) {
204
				case "PDF" : 
205
					if($content)
206
						$this->Error("load_file do not accept PDF content, only FDF content sorry");
207
					else
208
						$this->pdf_entries = $this->getEntries($this->pdf_source,'PDF');
209
				break;
210
				case "FDF" : 
211
					if(!is_null($content)) {
212
						if(is_array($content)) {
213
							$this->fields=$content;
214
							$this->fdf_parse_needed=false;
215
							//$this->dumpEntries($content,"PDF fields content");
216
						} else if(is_string($content)){ //String
217
							$this->fdf_content = $content; //TODO: check content 
218
							$this->fdf_parse_needed=true; 
219
						} else
220
							$this->Error('Invalid content type for this FDF file!');
221
					} else {
222
						$this->fdf_content = $this->getContent($this->fdf_source,'FDF');
223
						$this->fdf_parse_needed=true; 
224
					}
225
				break;
226
				default:
227
					$this->Error("Invalid file type $type");
228
			}
229
		}
230
		
231
		/**
232
		*Set a mode and play with your power debug toys
233
		*
234
		*@access public
235
		*@note for big boys only coz it may hurt
236
		*@param string $mode a choice between 'safe','check','verbose','halt' or 'verbose_level'
237
		*@param string|int $value an integer for verbose_level
238
		**/
239
		function set_modes($mode,$value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
240
		//-------------------------------
241
			switch($mode) {
242
				case 'safe':
243
					$this->safe_mode=$value;
244
				break;
245
				case 'check':
246
					$this->check_mode=$value;
247
				break;
248
				case 'flatten':
249
					$this->flatten_mode=$value;
250
				break;
251
				case 'compress_mode':
252
					$this->compress_mode=$value;
253
					if($value) $this->uncompress_mode=false;
254
				break;
255
				case 'uncompress_mode':
256
					$this->uncompress_mode=$value;
257
					if($value) $this->compress_mode=false;
258
				break;
259
				case 'verbose':
260
					$this->verbose=$value;
261
				break;
262
				case 'halt':
263
					$this->halt_mode=$value;
264
				break;
265
				case 'verbose_level':
266
					$this->verbose_level=$value;
267
				break;
268
				default:
269
					$this->Error("set_modes error, Invalid mode '<i>$mode</i>'");
270
			}
271
		}
272
		
273
		/**
274
		*Retrieves informations of the pdf
275
		*
276
		*@access public 
277
		*@note To track PDF versions and so on...
278
		*@param Boolean output	
279
		**/
280
		function Info($asArray=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
281
		//----------------------
282
			$info=$this->info;
283
			$info["Reader"]=($this->support == "native") ?  'FPDF-Merge '.FPDM_VERSION: $this->support;
284
			$info["Fields"]=$this->fields;
285
			$info["Modes"]=array(
286
				'safe'=>($this->safe_mode)? 'Yes' :'No',
287
				'check'=>($this->check_mode) ? 'Yes': 'No',
288
				'flatten'=>($this->flatten_mode)  ? 'Yes': 'No',
289
				'compress_mode'=>($this->compress_mode) ? 'Yes': 'No',
290
				'uncompress_mode'=>($this->uncompress_mode) ? 'Yes': 'No',
291
				'verbose'=>$this->verbose,
292
				'verbose_level'=>$this->verbose_level,
293
				'halt'=>$this->halt_mode
294
			);
295
			if($asArray) {
296
				return $info;
297
			} else {
298
				$this->dumpEntries($info,"Welcome on FPDMerge flight to ".FPDM_RELEASE.", here is the pdf temperature:");
299
			}
300
		}
301
		
302
		/**
303
		*Changes the support
304
		*
305
		*@access public 
306
		*@internal fixes xref table offsets
307
		*@note special playskool toy for Christmas dedicated to my impatient fanclub (Grant, Kris, nejck,...)
308
		*@param String support Allow to use external support that has more advanced features (ie 'pdftk')	
309
		**/
310
		function Plays($cool) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
311
		//----------------------
312
			if($cool=='pdftk')  //Use a coolest support as ..
313
				$this->support='pdftk';//..Per DeFinition This is Kool!
314
			else
315
				$this->support='native';
316
		}
317
		
318
		/**
319
		*Fixes a corrupted PDF file
320
		*
321
		*@access public 
322
		*@internal fixes xref table offsets
323
		*@note Real work is not made here but by Merge that should be launched after to complete the work
324
		**/
325
		function Fix() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
326
		//---------------
327
			if(!$this->fields) $this->fields=array(); //Default: No field data
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->fields of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
328
			$this->set_modes('check',true); //Compare xref table offsets with objects offsets in the pdf file
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
329
			$this->set_modes('halt',false); //Do no stop on errors so fix is applied during merge process
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
330
		}
331
		
332
		//######## pdftk's output configuration #######
333
		
334
		/**
335
		*Decides to use  the  compress filter to restore compression.
336
		*@note  This is only useful when you want to repack PDF that was previously edited in a text  editor like vim or emacs.	
337
		**/
338
		function Compress() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
339
		//-------------------
340
			$this->set_modes('compress',true); 
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
341
			$this->support="pdftk";
342
		}
343
		
344
		/**
345
		*Decides to remove PDF page stream compression by applying	the  uncompress  filter.
346
		*@note  This is only useful when you want to edit PDF code in a text  editor like vim or emacs.	
347
		**/
348
		function Uncompress() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
349
		//---------------------
350
			$this->set_modes('uncompress',true); 
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
351
			$this->support="pdftk";
352
		}
353
		/**
354
		*Activates the flatten output to remove form from pdf file keeping field datas.
355
		**/
356
		function Flatten() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
357
		//-----------------
358
			$this->set_modes('flatten',true); 
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
359
			$this->support="pdftk";
360
		}
361
		
362
		/***
363
		*Defines a password type
364
		*@param String type , 'owner' or  'user'
365
		**/
366 View Code Duplication
		function Password($type,$code) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
367
		//------------------------------
368
			switch($type) {
369
				case 'owner':
370
				case 'user':
371
				$this->security["password"]["$type"]=$code;
372
				break;
373
				default:
374
					$this->Error("Unsupported password type ($type), specify 'owner' or 'user' instead.");
375
			}
376
			$this->support="pdftk";
377
		}
378
		
379
		
380
		/**
381
		*Defines the encrytion to the given bits
382
		*@param integer $bits 0, 40 or 128
383
		**/
384 View Code Duplication
		function Encrypt($bits) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
385
		//-----------------------
386
			switch($bits) {
387
				case 0:
388
				case 40:
389
				case 128:				
390
				$this->security["encrypt"]=$bits;
391
				break;
392
				default:
393
					$this->Error("Unsupported encrypt value of $bits, only 0, 40 and 128 are supported");
394
			}
395
			$this->support="pdftk";
396
		}
397
		
398
		/**
399
		*Allow permissions
400
		*
401
		*@param Array permmissions If no arg is given, show help.
402
		*   Permissions  are applied to the output PDF only if an encryption
403
	    *  strength is specified or an owner or user password is given.  If
404
	    *  permissions  are	not  specified,  they default to 'none,' which
405
	    *  means all of the following features are disabled.
406
		*
407
	    *  The permissions section may include one or more of the following
408
	    *  features:
409
		*
410
	    *  Printing
411
		*    Top Quality Printing
412
		*
413
	    * DegradedPrinting
414
		*    Lower Quality Printing
415
		*
416
	    *  ModifyContents
417
		*     Also allows Assembly
418
		*
419
	    *  Assembly
420
		*
421
	    *  CopyContents
422
		*     Also allows ScreenReaders
423
		*
424
	    *  ScreenReaders
425
		*
426
	    *  ModifyAnnotations
427
		*     Also allows FillIn
428
		*
429
	    *  FillIn
430
		*
431
	    *  AllFeatures
432
		*     Allows  the  user	to  perform  all of the above, and top
433
		*     quality printing.
434
		**/
435
		function Allow($permissions=null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
436
		//--------------------------
437
			$perms_help=array(
438
				'Printing'=>'Top Quality Printing',
439
				'DegradedPrinting'=>'Lower Quality Printing',
440
				'ModifyContents' =>'Also allows Assembly',
441
				'Assembly' => '',
442
				'CopyContents' => 'Also allows ScreenReaders',
443
				'ScreenReaders' => '',
444
				'ModifyAnnotations'=>'Also allows FillIn',
445
				'FillIn'=>'',
446
				'AllFeatures'=> "All above"
447
			);
448
			if(is_null($permissions)) {
449
				echo '<br>Info Allow permissions:<br>';
450
				print_r($perms_help);
451
			}else {
452
				if(is_string($permissions)) $permissions=array($permissions);
453
				$perms=array_keys($perms_help);
454
				$this->security["allow"]=array_intersect($permissions, $perms);
455
				$this->support="pdftk";
456
			}
457
		}
458
		
459
		//#############################
460
		
461
		/**
462
		*Merge FDF file with a PDF file
463
		*
464
		*@access public 
465
		*@note files has been provided during the instantiation of this class
466
		*@internal flatten mode is not yet supported
467
		*@param Boolean flatten Optional, false by default, if true will use pdftk (requires a shell) to flatten the pdf form
468
		**/
469
		function Merge($flatten=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
470
		//------------------------------
471
		
472
			if($flatten) $this->Flatten();
473
		
474
			
475
			if($this->support == "native") {
476
			
477
				if($this->fdf_parse_needed) {
478
					$fields=$this->parseFDFContent();
479
				}else {
480
					$fields=$this->fields;
481
				}
482
				
483
				$count_fields=count($fields);
484
				
485
				if($this->verbose&&($count_fields==0)) 
486
					$this->dumpContent("The FDF content has either no field data or parsing may failed","FDF parser: ");
487
						
488
				$fields_value_definition_lines=array();
489
				
490
				$count_entries=$this->parsePDFEntries($fields_value_definition_lines);
491
			
492
			
493
				if($count_entries) {
494
				
495
					$this->value_entries=$fields_value_definition_lines;
496
					if($this->verbose) {
497
						$this->dumpContent("$count_entries Field entry values found for $count_fields field values to fill","Merge info: ");
498
					}
499
					//==== Alterate work is made here: change values ============
500
					if($count_fields) {
501
						foreach($fields as $name => $value) {
502
							$this->set_field_value("current",$name,$value);
503
//							$value=''; //Strategy applies only to current value, clear others
504
//							$this->set_field_value("default",$name,$value);
505
//							$this->set_field_value("tooltip",$name,$value);
506
						}
507
					}
508
					//===========================================================
509
				
510
					//===== Cross refs/size fixes (offsets calculations for objects have been previously be done in set_field_value) ======= 
511
					
512
					//Update cross reference table to match object size changes 
513
					$this->fix_xref_table();
514
					
515
					//update the pointer to the cross reference table
516
					$this->fix_xref_start();
517
					
518
				}else
519
					$this->Error("PDF file is empty!");
520
					
521
			} //else pdftk's job is done in Output, not here.
522
		}
523
		
524
		/**
525
		*Warns verbose/output conflicts
526
		*
527
		*@access private
528
		*@param string $dest a output destination
529
		**/
530
		function Close($dest) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
531
		//----------------
532
			$this->Error("Output: Verbose mode should be desactivated, it is incompatible with this output mode $dest");
533
		}
534
		
535
		/**
536
		*Get current pdf content (without any offset fixes)
537
		*
538
		*@access private
539
		*@param String pdf_file, if given , use the content as buffer (note file will be deleted after!)
540
		*@return string buffer the pdf content
541
		**/
542
		function get_buffer($pdf_file=''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
543
		//---------------------
544
			if($pdf_file == '') {
545
				$buffer=implode("\n",$this->pdf_entries);
546
			}else {
547
				$buffer=$this->getContent($pdf_file,'PDF');
548
				//@unlink($pdf_file);
549
			}
550
			return $buffer;
551
		}
552
		
553
	
554
		/**
555
		*Output PDF to some destination
556
		*
557
		*@access public
558
		*@note reproduces the fpdf's behavior
559
		*@param string name the filename
560
		*@string dest the destination
561
		*	by default it's a file ('F')
562
		*   if 'D'  , download
563
		*	and 'I' , Send to standard output
564
		*
565
		**/
566
		function Output($name='', $dest=''){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
567
		//-----------------------------------
568
			
569
			$pdf_file='';
570
			
571
			if($this->support == "pdftk") {
572
				//As PDFTK can only merge FDF files not data directly,
573
				require_once("lib/url.php"); //we will need a url support because relative urls for pdf inside fdf files are not supported by PDFTK...
574
				require_once("export/fdf/fdf.php"); //...conjointly with my patched/bridged forge_fdf that provides fdf file generation support from array data. 
575
				require_once("export/pdf/pdftk.php");//Of course don't forget to bridge to PDFTK!
576
577
				$tmp_file=false;
578
				$pdf_file=resolve_path(fix_path(dirname(__FILE__).'/'.$this->pdf_source));      //string: full pathname to the input pdf , a form file
579
				
580
				if($this->fdf_source) { //FDF file provided
581
					$fdf_file=resolve_path(fix_path(dirname(__FILE__).'/'.$this->fdf_source));
582
				}else {
583
				
584
					$pdf_url=getUrlfromDir($pdf_file); //Normaly http scheme not local file
585
				
586
					if($this->fdf_parse_needed) { //fdf source was provided
587
						$pdf_data=$this->parseFDFContent();
588
					}else { //fields data was provided as an array, we have to generate the fdf file
589
						$pdf_data=$this->fields;
590
					}	
591
					
592
					$fdf_file=fix_path(FPDM_CACHE)."fields".rnunid().".fdf";
593
					$tmp_file=true;
594
					$ret=output_fdf($pdf_url,$pdf_data,$fdf_file);
595
					if(!$ret["success"])
596
						$this->Error("Output failed as something goes wrong (Pdf was $pdf_url) <br> during internal FDF generation of file $fdf_file, <br>Reason is given by {$ret['return']}");
597
				}
598
				
599
				//Serializes security options (not deeply tested)
600
				$security='';
601 View Code Duplication
				if(!is_null($this->security["password"]["owner"])) $security.=' owner_pw "'.substr($this->security["password"]["owner"],0,FPDM_PASSWORD_MAX_LEN).'"';
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
602 View Code Duplication
				if(!is_null($this->security["password"]["user"])) $security.=' user_pw "'.substr($this->security["password"]["user"],0,FPDM_PASSWORD_MAX_LEN).'"';
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
603
				if($this->security["encrypt"]!=0) $security.=' encrypt_'.$this->security["encrypt"].'bit';
604
				if(count($this->security["allow"])>0) {
605
					$permissions=$this->security["allow"];
606
					$security.=' allow '; 
607
					foreach($permissions as $permission)
608
						$security.=' '.$permission;
609
				}
610
				
611
				//Serialize output modes
612
				$output_modes='';
613
				if($this->flatten_mode)  $output_modes.=' flatten';
614
				if($this->compress_mode) $output_modes.=' compress';
615
				if($this->uncompress_mode) $output_modes.=' uncompress';
616
		
617
				
618
				$ret=pdftk($pdf_file,$fdf_file,array("security"=>$security,"output_modes"=>$output_modes));
619
				
620
				if($tmp_file) @unlink($fdf_file); //Clear cache
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...
621
				
622
				if($ret["success"]) {
623
					$pdf_file=$ret["return"];
624
				}else 
625
					$this->Error($ret["return"]);
626
			}
627
			
628
			$this->buffer=$this->get_buffer($pdf_file);
0 ignored issues
show
Bug introduced by
The property buffer does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
629
			
630
			
631
			$dest=strtoupper($dest);
632
			if($dest=='')
633
			{
634
				if($name=='')
635
				{
636
					$name='doc.pdf';
637
					$dest='I';
638
				}
639
				else
640
					$dest='F';
641
			}
642
			
643
			//Abort to avoid to polluate output
644
			if($this->verbose&&(($dest=='I')||($dest=='D'))) {
645
				$this->Close($dest); 
646
			}
647
		
648
			switch($dest)
649
			{
650
				case 'I':
651
					//Send to standard output
652
					if(ob_get_length())
653
						$this->Error('Some data has already been output, can\'t send PDF file');
654
					if(php_sapi_name()!='cli')
655
					{
656
						//We send to a browser
657
						header('Content-Type: application/pdf');
658
						if(headers_sent())
659
							$this->Error('Some data has already been output, can\'t send PDF file');
660
						header('Content-Length: '.strlen($this->buffer));
661
						header('Content-Disposition: inline; filename="'.$name.'"');
662
						header('Cache-Control: private, max-age=0, must-revalidate');
663
						header('Pragma: public');
664
						ini_set('zlib.output_compression','0');
665
					}
666
					echo $this->buffer;
667
					break;
668
				case 'D':
669
					//Download file
670
					if(ob_get_length())
671
						$this->Error('Some data has already been output, can\'t send PDF file');
672
					header('Content-Type: application/x-download');
673
					if(headers_sent())
674
						$this->Error('Some data has already been output, can\'t send PDF file');
675
					header('Content-Length: '.strlen($this->buffer));
676
					header('Content-Disposition: attachment; filename="'.$name.'"');
677
					
678
					header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
679
					header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
680
					header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); // HTTP/1.1
681
					header("Cache-Control: post-check=0, pre-check=0", false);
682
					//header("Pragma: "); // HTTP/1.0
683
684
					header('Cache-Control: private, max-age=0, must-revalidate');
685
					header('Pragma: public,no-cache');
686
					ini_set('zlib.output_compression','0');
687
					echo $this->buffer;
688
					break;
689
				case 'F':
690
					//Save to local file
691
					if($this->verbose) $this->dumpContent("Write file $name","Output");
692
					$f=fopen($name,'wb');
693
					if(!$f)
694
						$this->Error('Unable to create output file: '.$name.' (currently opened under Acrobat Reader?)');
695
						
696
					fwrite($f,$this->buffer,strlen($this->buffer));
697
					fclose($f);
698
					break;
699
				case 'S':
700
					//Return as a string
701
					return $this->buffer;
702
				default:
703
					$this->Error('Incorrect output destination: '.$dest);
704
			}
705
			return '';
706
		}
707
708
		
709
		/**
710
		*Decodes and returns the binary form of a field hexified value
711
		*
712
		*@note static method due to callback..
713
		*@param string value the hexified string
714
		*@return string call the binary string
715
		**/
716
		function pdf_decode_field_value($value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
717
		//----------------------------------------
718
			$call=$this->static_method_call('_hex2bin',$value);
719
			return $call;
720
		}
721
		
722
		/**
723
		*Encodes and returns the headecimal form of a field binary value
724
		*
725
		*@note static method due to callback..
726
		*@param string value the binary string
727
		*@return string call the hexified string
728
		**/
729
		function pdf_encode_field_value($value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
730
		//---------------------------------------
731
			$value=$this->static_method_call('_bin2hex',$value);
732
			return $value;
733
		}
734
		
735
		
736
		/**
737
		*Universal Php4/5 static call helper
738
		*
739
		*@param String $method a name of a method belonging to this class
740
		*@return mixed the return value of the called method
741
		**/
742
		function static_method_call($method) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
743
		//---------------------------------------------
744
	
745
			$params_call=func_get_args();
746
			array_shift($params_call);
747
			//var_dump($params_call);
748
			
749
			return call_user_func_array(array($this,$method),$params_call);
750
		}
751
		
752
		/**
753
		*Changes a field value that can be in hex <> or binary form ()
754
		*
755
		*@param $matches the regexp matches of the line that contains the value to change
756
		*@param String $value the new value for the field property
757
		**/
758
		function replace_value($matches,$value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
759
		//----------------------------------------------
760
			
761
			array_shift($matches);
762
763
			if(($value!='')&&($matches[1]=="<")) //Value must be hexified..
764
				$value=$this->pdf_encode_field_value($value); 
765
		
766
			$matches[2]=$value;
767
			$value_type_code=$matches[0]; //Should be V, DV or TU
768
			$matches[0]="/".$value_type_code." ";
769
			
770
			$value=implode("",$matches);
771
			//echo(htmlentities($value));
772
			return $value;
773
		}
774
		
775
		/**
776
		*Core to change the value of a field property, inline.
777
		*
778
		*@access private
779
		*@param int $line the lien where the field property value is defined in the pdf file
780
		*@param string $value the new value to set
781
		*@return int $shift the size change of the field property value
782
		**/
783
		function _set_field_value($line,$value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
784
		//----------------------------------------
785
		
786
			$verbose_set=($this->verbose&&($this->verbose_level>1));
787
			//get the line content
788
			$CurLine =$this->pdf_entries[$line];
789
		
790
			$OldLen=strlen($CurLine);
791
			
792
			//My PHP4/5 static call hack, only to make the callback $this->replace_value($matches,"$value") possible!
793
			$callback_code='$THIS=new FPDM("[_STATIC_]");return $THIS->replace_value($matches,"'.$value.'");';
794
			
795
			$field_regexp='/^\/(\w+)\s?(\<|\()([^\)\>]*)(\)|\>)/';
796
			
797
			if(preg_match($field_regexp,$CurLine)) {
798
				//modify it according to the new value $value
799
				$CurLine = preg_replace_callback(
800
					$field_regexp,
801
					create_function('$matches',$callback_code),
802
					$CurLine
803
				);
804
			}else {
805
				if($verbose_set) echo("<br>WARNING:".htmlentities("Can not access to the value: $CurLine using regexp $field_regexp"));
806
			}
807
			
808
			
809
			$NewLen=strlen($CurLine);
810
			$Shift=$NewLen-$OldLen;
811
			$this->shift=$this->shift+$Shift;
812
			
813
			//Saves
814
			$this->pdf_entries[$line]=$CurLine;
815
			
816
			return $Shift;
817
		}
818
819
		function _encode_value($str) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
820
			if($this->isUTF8)
821
				$str="\xFE\xFF".iconv('UTF-8','UTF-16BE',$str);
822
			return $this->_bin2hex($str);
823
		}
824
		
825
		function _set_field_value2($line,$value,$append) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
826
			$CurLine=$this->pdf_entries[$line];
827
			$OldLen=strlen($CurLine);
828
829
			if($append)
830
			{
831
				$CurLine .= ' /V <'.$this->_encode_value($value).'>';
832
			}
833
			else
834
			{
835
				if(preg_match('#/V\s?[<(]([^>)]*)[>)]#', $CurLine, $a, PREG_OFFSET_CAPTURE))
836
				{
837
					$len=strlen($a[1][0]);
838
					$pos1=$a[1][1];
839
					$pos2=$pos1+$len;
840
					$CurLine=substr($CurLine,0,$pos1-1).'<'.$this->_encode_value($value).'>'.substr($CurLine,$pos2+1);
841
				}
842
				else
843
					$this->Error('/V not found');
844
			}
845
846
			$NewLen=strlen($CurLine);
847
			$Shift=$NewLen-$OldLen;
848
			$this->shift=$this->shift+$Shift;
849
			$this->pdf_entries[$line]=$CurLine;
850
			return $Shift;
851
		}
852
853
854
		/**
855
		*Changes the value of a field property, inline.
856
		*
857
		*@param string $type supported values for type are 'default' , 'current' or 'tooltip' 
858
		*@param string $name name of the field annotation to change the value
859
		*@param string $value the new value to set
860
		**/
861
		function set_field_value($type,$name,$value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
862
		//------------------------------------
863
			$verbose_set=($this->verbose&&($this->verbose_level>1));
0 ignored issues
show
Unused Code introduced by
$verbose_set is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
864
			
865
			//Get the line(s) of the misc field values
866
			if(isset($this->value_entries["$name"])) {
867
				
868
				$object_id=$this->value_entries["$name"]["infos"]["object"];
869
				
870
				if($type=="tooltip") {
871
			 
872
					$offset_shift=$this->set_field_tooltip($name,$value);
873
			 
874
				} else {//if(isset($this->value_entries["$name"]["values"]["$type"])) {
875
//				echo $this->value_entries["$name"]["values"]["$type"];
876
/*					$field_value_line=$this->value_entries["$name"]["values"]["$type"];
877
					$field_value_maxlen=$this->value_entries["$name"]["constraints"]["maxlen"];
878
					
879
					if($field_value_maxlen) //Truncates the size if needed
880
						$value=substr($value, 0, $field_value_maxlen);				
881
						
882
					if($verbose_set) echo "<br>Change $type value of the field $name at line $field_value_line to '<i>$value</i>'";
883
					$offset_shift=$this->_set_field_value($field_value_line,$value);*/
884
					if(isset($this->value_entries[$name]["values"]["current"]))
885
						$offset_shift=$this->_set_field_value2($this->value_entries[$name]["values"]["current"],$value,false);
886
					else
887
						$offset_shift=$this->_set_field_value2($this->value_entries[$name]["infos"]["name_line"],$value,true);
888
				}						
889
//				}else
890
//					$this->Error("set_field_value failed as invalid valuetype $type for object $object_id");
891
					
892
					
893
				//offset size shift will affect the next objects offsets taking into accound the order they appear in the file--
894
				$this->apply_offset_shift_from_object($object_id,$offset_shift);
895
					
896
			} else 
897
				$this->Error("field $name not found");
898
			
899
		}
900
		
901
		
902
		/**
903
		*Changes the tooltip value of a field property, inline.
904
		* 
905
		*@param string $name name of the field annotation to change the value
906
		*@param string $value the new value to set
907
		*@return int offset_shift the size variation
908
		**/
909
		function set_field_tooltip($name,$value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
910
		//------------------------------------
911
			$offset_shift=0;
912
			$verbose_set=($this->verbose&&($this->verbose_level>1));
913
			
914
			//Get the line(s) of the misc field values
915
			if(isset($this->value_entries["$name"])) {
916
				$field_tooltip_line=$this->value_entries["$name"]["infos"]["tooltip"];
917
				if($field_tooltip_line) {
918
					if($verbose_set) echo "<br>Change tooltip of the field $name at line $field_tooltip_line to value [$value]";
919
					$offset_shift=$this->_set_field_value($field_tooltip_line,$value);
920
				}else {
921
					if($verbose_set) echo "<br>Change toolpip value aborted, the field $name has no tooltip definition.";
922
				}
923
			} else 
924
				$this->Error("set_field_tooltip failed as the field $name does not exist");
925
			return $offset_shift;
926
		}
927
		
928
		/**
929
		*Dumps the line entries 
930
		*
931
		*@note for debug purposes
932
		*@access private
933
		*@param array entries the content to dump
934
		*@param string tag an optional tag to highlight
935
		*@param boolean halt decides to stop or not this script
936
		**/
937
		function dumpEntries($entries,$tag="",$halt=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
938
        //------------------------------------------------------------
939
			if($tag) echo "<br><h4>$tag</h4><hr>";
940
			if($entries) {
941
				echo "<pre>";
942
				echo htmlentities(print_r($entries,true));
943
				echo "</pre>";
944
			}
945
			if($halt) exit();
946
        }
947
		
948
		
949
		/**
950
		*Dumps the string content
951
		*
952
		*@note for debug purposes
953
		*@access private
954
		*@param string content the content to dump
955
		*@param string tag an optional tag to highlight
956
		*@param boolean halt decides to stop or not this script
957
		**/
958
		function dumpContent($content,$tag="",$halt=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
959
        //--------------------------------------------------
960
			if($tag) echo "<h4>$tag</h4>";
961
			if($content) {
962
				echo "<pre>";
963
				echo htmlentities($content);
964
				echo "</pre>";
965
			}
966
			if($halt) exit();
967
        }
968
		
969
		/**
970
		*Retrieves the content of a file as a string
971
		*
972
		*@access private
973
		*@param string $filename the filename of the file
974
		*@param string $filetype the type of file as info
975
		*@return string $content
976
		**/
977
		function getContent($filename,$filetype) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
978
        //----------------------------------------
979
            //$content = file_get_contents($filename);
980
			$handle=fopen($filename,'rb');
981
			$content = fread($handle, filesize($filename));
982
			fclose($handle);
983
			
984
            if (!$content)
985
                $this->Error(sprintf('Cannot open '.$filetype.' file %s !', $filename));
986
987
			if($filetype=='PDF')
988
			{
989
				$start = substr($content, 0, 2048);
990
				if(strpos($start, '/ObjStm')!==false)
991
					$this->Error('Object streams are not supported');
992
				if(strpos($start, '/Linearized')!==false)
993
					$this->Error('Fast Web View mode is not supported');
994
				$end = substr($content, -512);
995
				if(strpos($end, '/Prev')!==false)
996
					$this->Error('Incremental updates are not supported');
997
				$this->needAppearancesTrue = (strpos($content, '/NeedAppearances true')!==false);
998
			}
999
				
1000
          /*  if($this->verbose) {
1001
				$this->dumpContent($content,"$filetype file content read");
1002
            }*/
1003
            return $content;
1004
        }
1005
		
1006
		/**
1007
		*Retrieves the content of a file as an array of lines entries
1008
		*
1009
		*@access private
1010
		*@param string $filename the filename of the file
1011
		*@param string $filetype the type of file as info
1012
		*@return array $entries
1013
		**/
1014
		function getEntries($filename,$filetype) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1015
        //----------------------------------------
1016
			$content=$this->getContent($filename,$filetype);
1017
			$entries=explode("\n",$content);
1018
				
1019
           /* if($this->verbose) {
1020
				$this->dumpEntries($entries,"$filetype file entries");
1021
            }*/
1022
            return $entries;
1023
        }
1024
1025
		
1026
		/**
1027
		*Retrieves a binary string from its hexadecimal representation
1028
		*
1029
		*@access private
1030
		*@note Function was written because PHP has a bin2hex, but not a hex2bin!
1031
		*@internal note pack(�C�,hexdec(substr($data,$i,2))) DOES NOT WORK
1032
		*@param string $hexString the hexified string
1033
		*@return string $bin a binary string
1034
		**/
1035 View Code Duplication
		function _hex2bin ($hexString)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1036
		{
1037
			//echo "<br>_hex2bin($hexString)";
1038
			$BinStr = '';
1039
		
1040
			$hexLength=strlen($hexString);
1041
			// only hex numbers is allowed
1042
			 if ($hexLength % 2 != 0 || preg_match("/[^\da-fA-F]/",$hexString)) return FALSE;
1043
		
1044
		
1045
			//Loop through the input and convert it
1046
			for ($i = 0; $i < $hexLength; $i += 2)
1047
				$BinStr .= '%'.substr ($hexString, $i, 2);
1048
		
1049
			
1050
			// Raw url-decode and return the result
1051
			return rawurldecode ($BinStr);//chr(hexdec())
1052
		}
1053
	
1054
	
1055
		/**
1056
		*Encodes a binary string to its hexadecimal representation
1057
		*
1058
		*@access private
1059
		*@internal  dechex(ord($str{$i})); is buggy because for hex value of 0-15 heading 0 is missing! Using sprintf() to get it right.
1060
		*@param string $str a binary string
1061
		*@return string $hex the hexified string
1062
		**/
1063 View Code Duplication
		function _bin2hex($str) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1064
		//----------------------
1065
			$hex = "";
1066
			$i = 0;
1067
			do {
1068
				$hex .= sprintf("%02X", ord($str[$i]));
1069
				$i++;
1070
			} while ($i < strlen($str));
1071
			return $hex;
1072
		}	
1073
		
1074
		
1075
		/**
1076
         * Extracts the map object for the xref table
1077
		 * @note PDF lines should have been previouly been parsed to make this work
1078
		 * @return array a map that holds the xrefstart infos and values
1079
         */
1080
		function get_xref_table() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1081
		//------------------------
1082
			return $this->value_entries['$_XREF_$'];
1083
		}
1084
		
1085
		/**
1086
         * Extracts the offset of the xref table 
1087
		 * @note PDF lines should have been previouly been parsed to make this work
1088
		 * @return int the xrefstart value
1089
         */
1090
		function get_xref_start() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1091
		//------------------------
1092
			return $this->value_entries['$_XREF_$']["infos"]["start"]["pointer"]; 
1093
		}
1094
		
1095
		
1096
		/**
1097
         * Extracts the line where the offset of the xref table is stored
1098
		 * @note PDF lines should have been previouly been parsed to make this work
1099
		 * @return int the wished line number
1100
         */
1101
		function get_xref_start_line() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1102
		//-------------------------------
1103
			return $this->value_entries['$_XREF_$']["infos"]["start"]["line"];
1104
		}
1105
		
1106
		/**
1107
         * Calculates the offset of the xref table
1108
		 *
1109
		 * @return int the wished xrefstart offset value
1110
         */
1111
		function get_xref_start_value() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1112
		//-------------------------------
1113
			$size_shift=$this->shift;
1114
			$xref_start=$this->get_xref_start();
1115
			return $xref_start+$size_shift;
1116
		}
1117
		
1118
		
1119
		/**
1120
         * Read the offset of the xref table directly from file content
1121
		 *
1122
         * @note content has been previously been defined in $this->buffer
1123
		 * @param int $object_id an object id, a integer value starting from 1
0 ignored issues
show
Bug introduced by
There is no parameter named $object_id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1124
		 * @return int the wished xrefstart offset value
1125
         */
1126
		function read_xref_start_value() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1127
		//------------------------------
1128
			$buffer=$this->get_buffer();
1129
			$chunks = preg_split('/\bxref\b/', $buffer, -1, PREG_SPLIT_OFFSET_CAPTURE);
1130
			return intval($chunks[1][1])-4; //-4 , relative to end of xref
1131
		}
1132
		
1133
		
1134
		/**
1135
         * Calculates the new offset/xref for this object id by applying the offset_shift due to value changes
1136
		 *
1137
         * @note uses internally precalculated $offsets,$positions and $shifts
1138
		 * @param int $object_id an object id, a integer value starting from 1
1139
		 * @return int the wished offset
1140
         */
1141
		function get_offset_object_value($object_id) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1142
		//--------------------------------------------
1143
		
1144
			//Static is to keep forever...
1145
			static $offsets=null;
1146
			static $positions=null;
1147
			static $shifts=null;
1148
			
1149
			if(is_null($offsets)) { //...variables content set once. This is the beauty of php :)
1150
			
1151
				//!NOTE: xref table is ordered by object id (position's object is not defined linearly in the pdf !)
1152
				$positions=$this->_get_positions_ordered();
1153
				//Makes it 0 indexed as object id starts from 1 and positions starts from 0
1154
				$offsets=$this->_get_offsets_starting_from_zero();
1155
				//Shifts are already 0 indexed, don't change.
1156
				$shifts=$this->shifts;
1157
			}
1158
			
1159
			$p=$positions[$object_id];
1160
			$offset=$offsets[$p];
1161
			$shift=$shifts[$p]; //size shift of the object due to value changes
1162
			return $offset+$shift;
1163
		}
1164
		
1165
		
1166
		/**
1167
         * Reads the offset of the xref table directly from file content
1168
		 *
1169
         * @note content has been previously been defined in $this->buffer
1170
		 * @param int $object_id an object id, a integer value starting from 1
1171
		 * @return int the wished offset
1172
         */
1173
		function read_offset_object_value($object_id) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1174
		//------------------------------
1175
			$buffer=$this->buffer;
1176
			$previous_object_footer='';//'endobj' or comment;
1177
			$object_header=$previous_object_footer.'\n'.$object_id.' 0 obj';
1178
			$chars = preg_split('/'.$object_header.'/', $buffer, -1, PREG_SPLIT_OFFSET_CAPTURE);
1179
			$offset=intval($chars[1][1])-strlen($object_header)+strlen($previous_object_footer)+2;
1180
			return $offset;
1181
		}
1182
		
1183
		
1184
		/**
1185
         * Fix the offset of the xref table
1186
         * 
1187
         */
1188
		function fix_xref_start() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1189
		//-------------------------	
1190
				
1191
			$pdf_entries=&$this->pdf_entries;
1192
			$verbose_fix=($this->verbose&&($this->verbose_level>1));			
1193
			$calculate_xrefstart_value=((!$this->safe_mode)||$this->check_mode);
1194
			$extract_xrefstart_value_from_file=($this->safe_mode||$this->check_mode);
1195
				
1196
			if($calculate_xrefstart_value) {		
1197
				$xref_start_value_calculated=$this->get_xref_start_value(); //get computed value from old one
1198
				if(!$this->safe_mode) $xref_start_value=$xref_start_value_calculated;
1199
			}
1200
			
1201
			if($extract_xrefstart_value_from_file) { 
1202
				$xref_start_value_safe=$this->read_xref_start_value();//read direct from new file content
1203
				if($this->safe_mode) $xref_start_value=$xref_start_value_safe;
1204
			} 
1205
1206
			if($this->check_mode) { //Compared calculated value with position value read direct from file
1207
				if($xref_start_value_calculated != $xref_start_value_safe) {
1208
					if($verbose_fix) echo "<br>xrefstart's value must be $xref_start_value_safe calculated is $xref_start_value_calculated.Don't worry, FPDFM-merge will fix it for you.<br>";
0 ignored issues
show
Bug introduced by
The variable $xref_start_value_safe does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $xref_start_value_calculated does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1209
					$xref_start_value=$xref_start_value_safe; //Overrides with the good value
1210
					if($this->halt_mode) 
1211
					    $this->Error("Halt on error mode enabled, aborting. Use \$pdf->set_modes('halt',false); to disable this mode and go further fixing corrupted pdf.");
1212
				} else {
1213
					if($verbose_fix) echo "<br>xrefstart's value for the file is correct and vaults <b>$xref_start_value</b>";
0 ignored issues
show
Bug introduced by
The variable $xref_start_value does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1214
				}
1215
			}
1216
			
1217
			//updates xrefstart's value
1218
			$xref_start_line=$this->get_xref_start_line();
1219
			$pdf_entries[$xref_start_line]="$xref_start_value";
1220
		}
1221
		
1222
		/**
1223
         * Get the offsets table 0 indexed
1224
         * 
1225
		 * @return array $offsets 
1226
         */
1227
		function _get_offsets_starting_from_zero() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1228
		//-------------------------------------------
1229
			$offsets=$this->offsets; 
1230
			return array_values($offsets); 
1231
		}
1232
		
1233
		/**
1234
         * Sorts the position array by key
1235
         * 
1236
		 * @return array $positions the ordered positions
1237
         */
1238
		function _get_positions_ordered() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1239
		//--------------------------------
1240
			$positions=$this->positions;
1241
			ksort($positions);
1242
			return $positions;
1243
		}
1244
		
1245
		/**
1246
         * Fix the xref table by rebuilding its offsets entries
1247
         * 
1248
         */
1249
		function fix_xref_table() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1250
		//------------------------
1251
	
1252
			$xref_table=$this->get_xref_table();
1253
			$xLen=$xref_table["infos"]["count"];
1254
			$pdf_entries=&$this->pdf_entries;
1255
			
1256
			//Do some checks
1257
			$offsets=$this->offsets; 
1258
			//$offsets=array_values($offsets); 
1259
			$oLen=count($offsets);
1260
			
1261
			
1262
			if($xLen == $oLen) { //...to rectify xref entries 
1263
			
1264
				//jump over len and header, this is the first entry with n
1265
				$first_xref_entry_line=$xref_table["infos"]["line"]+3;
1266
				
1267
				//echo "xREF:{$pdf_entries[$first_xref_entry_line]}";
1268
			
1269
				//!NOTE: xref table is ordered by object id (position's object is not defined linearly in the pdf !)
1270
				//$positions=$this->positions;
1271
				//ksort($positions);
1272
				$verbose_fix=($this->verbose&&($this->verbose>1));
1273
				$calculate_offset_value=((!$this->safe_mode)||$this->check_mode);
1274
				$extract_offset_value_from_file=($this->safe_mode||$this->check_mode);
1275
				
1276
				//Get new file content (ie with values changed)
1277
				$this->buffer=$this->get_buffer();
1278
				
1279
				for($i=0;$i<$xLen;$i++) {
1280
				
1281
					$obj_id=$i+1;
1282
					
1283
					//Try two way to retrieve xref offset value of an object of the given id
1284
					
1285
					if($calculate_offset_value) {
1286
						$offset_value_calculated=$this->get_offset_object_value($obj_id);;
1287
						if(!$this->safe_mode) $offset_value=$offset_value_calculated;
1288
					}
1289
					
1290
					if($extract_offset_value_from_file) {
1291
						$offset_value_read=$this->read_offset_object_value($obj_id);	
1292
						if($this->safe_mode) $offset_value=$offset_value_read;
1293
					} 
1294
					
1295
					if($this->check_mode) {
1296
						if($offset_value_calculated !=  $offset_value_read)  {
1297
							if($verbose_fix) echo "<br>Offset for object $obj_id read is <b>$offset_value_read</b>, calculated $offset_value_calculated";
0 ignored issues
show
Bug introduced by
The variable $offset_value_read does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $offset_value_calculated does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1298
							$offset_value=$offset_value_read; //overrides to fix bad values
1299
							if($this->halt_mode) $this->Error("<br>Offset for object $obj_id read is <b>$offset_value_read</b>, calculated $offset_value_calculated");
1300
						}else {
1301
							if($verbose_fix) echo "<br>Offset for object $obj_id is correct and vaults <b>$offset_value</b>";
0 ignored issues
show
Bug introduced by
The variable $offset_value does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1302
						}
1303
					}
1304
					$pdf_entries[$first_xref_entry_line+$i]=sprintf('%010d 00000 n ',$offset_value);
1305
				}
1306
				
1307
			}else { 
1308
				//Congratulations you won the corrupted Error Prize
1309
				$this->Error("Number of objects ($oLen) differs with number of xrefs ($xLen), something , pdf xref table is corrupted :("); 
1310
			}
1311
			
1312
				
1313
		}
1314
	
1315
	
1316
		/**
1317
         * Applies a shift offset $shift from the object whose id is given as param
1318
         * 
1319
         * @note offset shift will affect the next objects taking into accound the order they appear in the file
1320
         * @access public
1321
         * @param int object_id the id whose size shift has changed
1322
		 * @param int offset_shift the shift value to use
1323
         */
1324
		function apply_offset_shift_from_object($object_id,$offset_shift) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1325
		//---------------------------------------------------------
1326
			//get the position of object
1327
			$object_pos=$this->positions[$object_id];
1328
			//get the next object position
1329
			$next_object_pos=$object_pos+1;
1330
			//Applies offset change to next following objects 				
1331
			$this->_apply_offset_shift($next_object_pos,$offset_shift);
1332
		}
1333
1334
		/**
1335
         * Applies a shift offset $shift starting at the index $from to the shifts array
1336
         * 
1337
         * @access private
1338
         * @param int from  the index to start apply the shift
1339
		 * @param int shift the shift value to use
1340
         */
1341
		function _apply_offset_shift($from,$shift) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1342
		//------------------------------------------
1343
			$offsets=&$this->shifts;
1344
			$params=array($from,$shift);
0 ignored issues
show
Unused Code introduced by
$params is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1345
			
1346
			foreach($offsets as $key=>$value) {
1347
				if($key>=$from) {
1348
					$offset=$offsets[$key]+$shift;
1349
					$offsets[$key]=$offset;
1350
				}
1351
			}
1352
			
1353
		}
1354
		
1355
		/**
1356
         * Decodes a PDF value according to the encoding
1357
         * 
1358
		 * @access public
1359
         * @param string $encoding  the encoding to use for decoding the value, only 'hex' is supported
1360
		 * @param string value a value to decode
1361
		 * @return string the value decoded
1362
         */
1363
		function decodeValue($encoding,$value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1364
		//----------------------------------------------
1365
			//echo "Decoding $encoding value($value)";
1366
			if($encoding=="hex") 
1367
				$value=$this->pdf_decode_field_value($value);
1368
			return $value;
1369
		}
1370
		
1371
		/**
1372
		*Retrieve the list of supported filters
1373
		*
1374
		*@note Uses $FPDM_FILTERS array built dynamically 
1375
		*@param String $sep a separator to merge filter names, default is '|'
1376
		*@return String the suported filters
1377
		**/
1378
		function getFilters($sep="|") {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1379
		//---------------------
1380
			if ($this->FPDM_FILTERS) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->FPDM_FILTERS of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1381
				return implode($sep,$this->FPDM_FILTERS);
1382
			} else {
1383
				return null;
1384
			}
1385
		}
1386
		
1387
		
1388
		/**
1389
		*Get a filter by name
1390
		*
1391
		*@param name a string matching one of the supported default filters (marked with +)		*
1392
		*Without parameters:
1393
		*+	ASCIIHexDecode : Decodes data encoded in an ASCII hexadecimal representation, reproducing the original binary data.
1394
		*+	ASCII85Decode  : Decodes data encoded in an ASCII base-85 representation, reproducing the original binary data.
1395
		*	RunLengthDecode : Decompresses data encoded using a byte-oriented run-length encoding algorithm, reproducing the original text or binary data (typically monochrome image data, or any data that contains frequent long runs of a single byte value).
1396
		*	JPXDecode : (PDF 1.5) Decompresses data encoded using the wavelet-based JPEG2000 standard, reproducing the original image data.
1397
		*With parameter(s):
1398
		*+  LZWDecode      : Decompresses data encoded using the LZW (Lempel-Ziv-Welch) adaptive compression method, reproducing the original text or binary data.
1399
		*+	FlateDecode (PDF�1.2): Decompresses data encoded using the zlib/deflate compression method, reproducing the original text or binary data.
1400
		*   CCITTFaxDecode : Decompresses data encoded using the CCITT facsimile standard, reproducing the original data (typically monochrome image data at 1 bit per pixel).
1401
		*   JBIG2Decode (PDF�1.4) :Decompresses data encoded using the JBIG2 standard, reproducing the original monochrome (1 bit per pixel) image data (or an approximation of that data).
1402
		*   DCTDecode : Decompresses data encoded using a DCT (discrete cosine transform) technique based on the JPEG standard, reproducing image sample data that approximates the original data.
1403
		*	Crypt (PDF 1.5) :Decrypts data encrypted by a security handler, reproducing the data as it was before encryption.
1404
		*@return the wished filter class to access the stream
1405
		**/
1406
		function getFilter($name) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1407
		//---------------------
1408
			
1409
			switch($name) {
1410
				case "LZWDecode":
1411
					$filter=new FilterLZW();
1412
				break;
1413
				case "ASCIIHexDecode": 
1414
					$filter=new FilterASCIIHex();
1415
				break;
1416
				case "ASCII85Decode": 
1417
					$filter=new FilterASCII85();
1418
				break;
1419
				case "FlateDecode":
1420
					$filter=new FilterFlate();
1421
				break;
1422
				case "Standard": //Raw
1423
					$filter=new FilterStandard();
1424
				break;
1425
				default:
1426
					$filter=new FilterStandard();
1427
			}
1428
			
1429
			
1430
			return $filter;					
1431
		}
1432
	
1433
	
1434
		//========= Stream manipulation stuff (alpha, not used by now!) ================
1435
		
1436
		/**
1437
         * Detect if the stream has a textual content
1438
         * 
1439
		 * @access public
1440
         * @param string $stream the string content of the stream
0 ignored issues
show
Documentation introduced by
There is no parameter named $stream. Did you maybe mean $stream_content?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1441
         * @return boolean 
1442
         */
1443
		function is_text_stream($stream_content) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1444
		//--------------------------------------
1445
			return preg_match("/(\s*Td\s+[\<\(])([^\>\)]+)([\>\)]\s+Tj)/",$stream_content);
1446
		}
1447
	
1448
		/**
1449
         * changes the text value of a text stream
1450
         * 
1451
		 * @access public
1452
         * @param array $stream  the stream defintion retrieved during PDF parsing
1453
         * @param string $value the new text value 
1454
         */
1455
		function change_stream_value($stream,$value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1456
		//--------------------------------------------
1457
		
1458
			$entries=&$this->pdf_entries;
1459
		
1460
			$verbose_parsing=($this->verbose&&($this->verbose_level>3));
1461
			
1462
			if($is_text_stream) {
0 ignored issues
show
Bug introduced by
The variable $is_text_stream does not exist. Did you mean $stream?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
1463
			
1464
				$OldLen=$stream["length"]["value"];
1465
				$lMin=$stream["start"];
1466
				$lMax=$stream["end"];
1467
				
1468
				$stream_content=$this->_set_text_value($stream_content,$value);
0 ignored issues
show
Bug introduced by
The variable $stream_content seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1469
				$NewLen=strlen($stream_content);
1470
			
1471
				for($l=$lMin;$l<=$lMax;$l++) {
1472
				
1473
					if($l==$lMin) {
1474
						$entries[$lMin]=$stream_content;
1475
						
1476
						//Update the length
1477
						$stream_def_line=$stream["length"]["line"];
1478
						$stream_def=$entries[$stream_def_line];
1479
						
1480
						$stream_def=preg_replace("/\/Length\s*(\d+)/",'/Length '.$NewLen,$stream_def);
1481
						
1482
						$entries[$stream_def_line]=$stream_def;
1483
						
1484
						//update the filter type...
1485
						$stream_def_line=$stream["filters"]["line"];
1486
						$stream_def=$entries[$stream_def_line];
1487
						if($verbose_parsing) {
1488
							echo "<pre>";
1489
							echo htmlentities(print_r($stream_def,true));
1490
							echo "</pre>";
1491
						}
1492
					
1493
						//...to filter Standard
1494
						$stream_def=preg_replace($this->streams_filter,'/Standard ',$stream_def);
1495
					
1496
						$entries[$stream_def_line]=$stream_def;
1497
						
1498
						//Update the shift
1499
						$size_shift=$NewLen-$OldLen;
1500
						$this->apply_offset_shift_from_object($obj,$size_shift);
0 ignored issues
show
Bug introduced by
The variable $obj does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
1501
						
1502
					}else if($lmin!=$lMax) {
0 ignored issues
show
Bug introduced by
The variable $lmin does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
1503
						unset($entries[$l]);
1504
					}
1505
				}
1506
				
1507
				if($verbose_parsing) {
1508
					var_dump($stream_content);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($stream_content); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
1509
				}
1510
			}
1511
		}
1512
	
1513
		/**
1514
         * Overrides value between  Td and TJ, ommiting <>
1515
         * 
1516
         * @note core method
1517
		 * @access private
1518
         * @param array $stream  the stream defintion retrieved during PDF parsing
1519
         * @param string $value the new text value 
1520
         */
1521
        function _set_text_value($stream,$value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1522
        //---------------------------------------
1523
			$chunks=preg_split("/(\s*Td\s+[\<\(])([^\>\)]+)([\>\)]\s+Tj)/",$stream,0,PREG_SPLIT_DELIM_CAPTURE);
1524
			$chunks[2]=$value;
1525
			$stream=implode($chunks,'');
1526
			return $stream;
1527
        }
1528
        
1529
	
1530
        //================================
1531
		
1532
		function _extract_pdf_definition_value($name,$line,&$match) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1533
		//-----------------------------------------------------------
1534
				$value=preg_match($this->FPDM_REGEXPS["$name"],$line,$match);
1535
				if(!$value) { //value is concatained with name: /name/value
1536
					$value=preg_match("/".preg_quote($name,'/')."\/(\w+)/",$line,$match);
1537
				}
1538
				return $value;
1539
		}
1540
1541
		function extract_pdf_definition_value($name,$line,&$match) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1542
		//-----------------------------------------------------------
1543
				
1544
				if(array_key_exists($name,$this->FPDM_REGEXPS)) {
1545
					$value=$this->_extract_pdf_definition_value($name,$line,$match);
1546
				}else
1547
					$this->Error("extract_pdf_definition_value() does not support definition '$name'");
1548
					
1549
				/*if($name=="/Type") {
1550
					if(preg_match("/\//",$line,$foo)) {
1551
					var_dump($match);
1552
					die("Decoding $name value in line ".htmlentities($line));
1553
					}
1554
				}*/
1555
				return $value;
0 ignored issues
show
Bug introduced by
The variable $value does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1556
		}
1557
1558
	
1559
		/**
1560
         * Parses the lines entries of a PDF 
1561
         * 
1562
		 * @access public
1563
         * @param array $lines  the FDF content as an array of lines
1564
		 * @return integer the number of lines the PDF has
1565
         */
1566
		function parsePDFEntries(&$lines){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1567
		//--------------------------------
1568
           
1569
           $entries=&$this->pdf_entries;
1570
           
1571
           $CountLines = count($entries);
1572
           
1573
            $Counter=0;
1574
            $obj=0; //this is an invalid object id, we use it to know if we are into an object
1575
			$type='';
1576
			$subtype='';
1577
			$name='';
1578
			$value='';
0 ignored issues
show
Unused Code introduced by
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1579
			$default_maxLen=0; //No limit
1580
			$default_tooltip_line=0; //Tooltip is optional as it may not be defined
1581
			$xref_table=0;
1582
			$trailer_table=0;
1583
			$n=0; //Position of an object, in the order it is declared in the pdf file
1584
			$stream=array();
1585
			$id_def=false; //true when parsing/decoding trailer ID
1586
			$id_single_line_def=false; //true when the two ID chunks are one the same line
1587
			$id_multi_line_def=false; //true or OpenOffice 3.2 
1588
			$creator='';
1589
			$producer='';
1590
			$creationDate='';
1591
			
1592
			$verbose_parsing=($this->verbose&&($this->verbose_level>3));
1593
			$verbose_decoding=($this->verbose&&($this->verbose_level>4));
1594
			
1595
            if($this->verbose) $this->dumpContent("Starting to parse $CountLines entries","PDF parse"); 
1596
            
1597
			while ( $Counter < $CountLines ){
1598
               
1599
                $CurLine = $entries[$Counter];
1600
                
1601
                if($verbose_parsing) $this->dumpContent($CurLine,"====Parsing Line($Counter)");
1602
				if(!$xref_table) {
1603
				
1604
					//Header of an object?
1605
					if(preg_match("/^(\d+) (\d+) obj/",$CurLine,$match)) {
1606
							$obj=intval($match[1]);
1607
							$this->offsets[$obj]=$this->pointer;
1608
							$this->positions[$obj]=$n;
1609
							$this->shifts[$n]=0;
1610
							$n++;
1611
							if($verbose_parsing) $this->dumpContent($CurLine,"====Opening object($obj) at line $Counter");
1612
							$object=array();
1613
							$object["values"]=array();
1614
							$object["constraints"]=array();
1615
							$object["constraints"]["maxlen"]=$default_maxLen;
1616
							$object["infos"]=array();
1617
							$object["infos"]["object"]=intval($obj);
1618
							$object["infos"]["tooltip"]=$default_tooltip_line; 
1619
							
1620
					} else { 
1621
					
1622
						//Object has been opened
1623
						if($obj) {
1624
						
1625
							//Footer of an object?
1626
							if(preg_match("/endobj/",$CurLine,$match)) {
1627
								if($verbose_parsing) $this->dumpContent("","====Closing object($obj) at line $Counter");
1628
								
1629
								//We process fields here, save only Annotations texts that are supported by now
1630
								if(($type=='Annot')&&($subtype=="Widget")) {
1631
								
1632
									if($name != '') {
1633
										$lines["$name"]=$object;
0 ignored issues
show
Bug introduced by
The variable $object does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1634
										if($verbose_parsing) $this->dumpContent("$type $subtype (obj id=$obj) is a text annotation of name '$name', saves it.");
1635
									}//else
1636
//										$this->Error("$type $subtype (obj id=$obj) is a text annotation without a name, this cannot be.");
1637
									
1638
									
1639
									$values=$object["values"];
1640
									
1641
									//Sanity values checks, watchdog.
1642
//									if(!array_key_exists("current",$values)) $this->Error("Cannot find value (/V) for field $name");
1643
//									if(!array_key_exists("default",$values)) $this->Error("Cannot find default value (/DV) for field $name");
1644
									
1645
								}else
1646
									if($verbose_parsing) $this->dumpContent("Object $type $subtype (obj id=$obj) is not supported");
1647
								
1648
								
1649
								$object=null;
1650
								$obj=0;
1651
								$type='';
1652
								$subtype='';
1653
								$name='';
1654
								$value='';
0 ignored issues
show
Unused Code introduced by
$value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1655
								$maxLen=0;
0 ignored issues
show
Unused Code introduced by
$maxLen is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1656
								
1657
							} else {
1658
							
1659
								if(preg_match("/\/Length\s*(\d+)/",$CurLine,$match)) {
1660
									$stream["length"]=array("line"=>$Counter,"value"=>$match[1]);
1661
									$stream["start"]=0;
1662
									$stream["end"]=0;
1663
									$stream["content"]='';
1664
									if($verbose_parsing) $this->dumpContent($CurLine,"->Stream filter length definition(<font color=\"darkorange\">{$match[1]}</font>) for object($obj) at line $Counter");
1665
								}
1666
								
1667
								//Handles single filter /Filter /filter_type as well as well as filter chains such as /Filter [/filter_type1 /filter_type2 .../filter_typeN]
1668
								if(preg_match_all($this->streams_filter,$CurLine,$matches)) {
1669
									
1670
									//$this->dumpContent($this->streams_filter);
1671
									/*$stream_filter=$match[1];
1672
									$stream_filter=trim(preg_replace('/(<<|\/Length\s*\d+|>>)/', '', $stream_filter),' ');
1673
									$stream_filters=preg_split('/\s*\//',$stream_filter);
1674
									array_shift($stream_filters);*/
1675
									$stream_filters=$matches[2];
1676
									$stream["filters"]=array("line"=>$Counter, "type"=>$stream_filters); 
1677
									if($verbose_parsing) {
1678
										//var_dump($stream_filters);
1679
										$stream_filter=implode(" ",$stream_filters);
1680
										$this->dumpContent($CurLine,"->Stream filter type definition(<font color=\"darkorange\">$stream_filter</font>) for object($obj) at line $Counter");
1681
									}
1682
								}	
1683
								
1684
								if(array_key_exists("length",$stream)) { //length is mandatory
1685
									
1686
									if(preg_match("/\b(stream|endstream)\b/",$CurLine,$match)) {
1687
									
1688
										if(!array_key_exists("filters",$stream))  {//filter type is optional, if none is given, its standard
1689
											
1690
											$stream["filters"]=array("type"=>array("Standard"));
1691
											if($verbose_parsing) {
1692
												var_dump($stream);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($stream); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
1693
												$this->dumpContent($CurLine,"->No stream filter type definition for object($obj) was found, setting it to '<font color=\"darkorange\">Standard</font>'");
1694
											}	
1695
										}
1696
										
1697
									
1698
										if($match[1] == "stream") {
1699
											if($verbose_parsing) $this->dumpContent($CurLine,"->Opening stream for object($obj) at line $Counter");
1700
											$stream["start"]=$Counter+1;
1701
										}else {
1702
											$stream["end"]=$Counter-1;
1703
											
1704
											$stream["content"]=implode("\n",array_slice($entries,$stream["start"],$stream["end"]-$stream["start"]+1));
1705
											
1706
											
1707
											
1708
											$filters=$stream["filters"]["type"];
1709
											$f=count($filters);
0 ignored issues
show
Unused Code introduced by
$f is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1710
											$stream_content=$stream["content"];
1711
											
1712
											//var_dump($filters);
1713
											
1714
											//$filters_type=$filters["type"];
1715
											
1716
											//now process the stream, ie unpack it if needed
1717
											//by decoding in the reverse order the streams have been encoded 
1718
											//This is done by applying decode using the filters in the order given by /Filter. 
1719
											foreach($filters as $filter_name) {
1720
												
1721
												$stream_filter=$this->getFilter($filter_name);
1722
												$stream_content=$stream_filter->decode($stream_content);
1723
												if($verbose_decoding) { 
1724
													echo "<br><font color=\"blue\"><u>Stream decoded using filter '<font color=\"darkorange\">$filter_name</font>'</u>:[<pre>";
1725
													var_dump($stream_content); //todo : manipulate this content and adjust offsets.
1726
													echo "</pre>]</font>";
1727
												}
1728
											}
1729
						
1730
											if($verbose_parsing) {
1731
												$this->dumpEntries($stream);
1732
												
1733
												echo "<font color=\"blue\">";
1734
												if($this->is_text_stream($stream_content)) {
1735
													echo "<u>Stream text unfiltered</u>:[<pre>";
1736
												} else {
1737
													echo "<u>Stream unfiltered</u>:[<pre>";
1738
												}
1739
												var_dump($stream_content); 
1740
												echo "</pre>]</font>";
1741
												$this->dumpContent($CurLine,"->Closing stream for object($obj) at line $Counter");
1742
											}
1743
											
1744
											$stream=array();
1745
										}
1746
									}else if($stream["start"]>0){ 
1747
										//stream content line that will be processed on endstream...
1748
									}
1749
									
1750
								} else {
1751
								
1752
									/*
1753
									Producer<FEFF004F00700065006E004F00660066006900630065002E006F0072006700200033002E0032>
1754
									/CreationDate (D:20101225151810+01'00')>>
1755
									*/
1756 View Code Duplication
									if(($creator=='')&&preg_match("/\/Creator\<([^\>]+)\>/",$CurLine,$values)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1757
										$creator=$this->decodeValue("hex",$values[1]);
1758
										if($verbose_parsing) echo("Creator read ($creator)");
1759
										$this->info["Creator"]=$creator;
1760
									}
1761
								
1762 View Code Duplication
									if(($producer=='')&&preg_match("/\/Producer\<([^\>]+)\>/",$CurLine,$values)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1763
										$producer=$this->decodeValue("hex",$values[1]);
1764
										if($verbose_parsing) echo("Producer read ($producer)");
1765
										$this->info["Producer"]=$producer;
1766
									}
1767
									
1768 View Code Duplication
									if(($creationDate=='')&&preg_match("/\/CreationDate\(([^\)]+)\)/",$CurLine,$values)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1769
										$creationDate=$values[1];
1770
										if($verbose_parsing) echo("Creation date read ($creationDate)");
1771
										$this->info["CreationDate"]=$creationDate;
1772
									}
1773
								
1774
									//=== DEFINITION ====
1775
									//preg_match("/^\/Type\s+\/(\w+)$/",$CurLine,$match)
1776
									$match=array();
1777
									if(($type=='')||($subtype=='')||($name=="")) {
1778
									
1779 View Code Duplication
										if(($type=='')&&$this->extract_pdf_definition_value("/Type",$CurLine,$match)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1780
										
1781
											if($match[1]!='Border') {
1782
												$type=$match[1];
1783
												if($verbose_parsing) echo("<br>Object's type is '<i>$type</i>'");
1784
											}
1785
											
1786
										}
1787 View Code Duplication
										if(($subtype=='')&&$this->extract_pdf_definition_value("/Subtype",$CurLine,$match)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1788
										
1789
											$subtype=$match[1];
1790
											if($verbose_parsing) echo("<br>Object's subType is '<i>$subtype</i>'");
1791
											
1792
										}
1793
										if(($name=="")&&preg_match("/^\/T\s?\((.+)\)\s*$/",$this->_protectContentValues($CurLine),$match)) {
1794
								
1795
											$name=$this->_unprotectContentValues($match[1]);
1796
											if($verbose_parsing) echo ("Object's name is '<i>$name</i>'");
1797
											
1798
											$object["infos"]["name"]=$name; //Keep a track
1799
											$object["infos"]["name_line"]=$Counter;
1800
											
1801
											//$this->dumpContent(" Name [$name]");
1802
										}
1803
										
1804
									}// else { 
1805
									
1806
										//=== CONTENT ====
1807
									
1808
										//$this->dumpContent($CurLine);
1809
										//=== Now, start the serious work , read DV, V Values and eventually TU
1810
										//note if(preg_match_all("/^\/(V|DV)\s+(\<|\))([^\)\>]+)(\)|\>)/",$CurLine,$matches)) {
1811
										//do not work as all is encoded on the same line...
1812
										if(preg_match("/^\/(V|DV|TU)\s+([\<\(])/",$CurLine,$def)) { 
1813
											
1814
											//get an human readable format of value type and encoding
1815
											
1816
											if($def[1] == "TU") {
1817
												$valuetype="info";
1818
												$object["infos"]["tooltip"]=$Counter;
1819
											} else {
1820
												$valuetype=($def[1] == "DV") ? "default" : "current";
1821
												$object["values"]["$valuetype"]=$Counter; //Set a marker to process lately
1822
											}
1823
											
1824
											$encoding=($def[2]=="<") ? "hex" : "plain";
1825
											
1826
											if(preg_match("/^\/(V|DV|TU)\s+(\<|\)|\()([^\)\>]*)(\)|\>\))/",$CurLine,$values)) {
1827
												$value=$values[3];
1828
												$value=$this->decodeValue($encoding,$value);
1829
											}else 
1830
												$value='';
1831
											
1832
											if($verbose_parsing) 
1833
												$this->dumpContent("$type $subtype (obj id=$obj) has $encoding $valuetype value [$value] at line $Counter");
1834
											
1835
											
1836
										}else if(preg_match("/^\/MaxLen\s+(\d+)/",$CurLine,$values)) {
1837
											$maxLen=$values[1];
1838
											$object["constraints"]["maxlen"]=intval($maxLen);
1839
										} else
1840
											if($verbose_parsing) echo("WARNING: definition ignored");
1841
										
1842
										if(substr($CurLine,0,7)=='/Fields' && !$this->needAppearancesTrue) {
1843
											$CurLine='/NeedAppearances true '.$CurLine;
1844
											$entries[$Counter]=$CurLine;
1845
										}
1846
										
1847
										//TODO: Fetch the XObject..and change Td <> Tj
1848
/*										if(preg_match("/^\/AP/",$CurLine,$values)) {
1849
											//die("stop");
1850
											$CurLine=''; //clear link to Xobject
1851
											$entries[$Counter]=$CurLine;
1852
										}*/
1853
										
1854
//									} 
1855
									
1856
								}
1857
							
1858
							
1859
							}
1860
						
1861
						}
1862
						 
1863
						//~~~~~Xref table header? ~~~~~~
1864
						if(preg_match("/\bxref\b/",$CurLine,$match)) {
1865
						
1866
							$xref_table=1;
1867
							if($verbose_parsing) $this->dumpContent("->Starting xref table at line $Counter:[$CurLine]");
1868
							$lines['$_XREF_$']=array();
1869
							$lines['$_XREF_$']["entries"]=array();
1870
							$lines['$_XREF_$']["infos"]=array();
1871
							$lines['$_XREF_$']["infos"]["line"]=$Counter;
1872
							$lines['$_XREF_$']["infos"]["start"]=array();
1873
							$start_pointer=$this->pointer+strpos($CurLine,"xref"); //HACK for PDFcreator 1.0.0
1874
							$lines['$_XREF_$']["infos"]["start"]["pointer"]=$start_pointer;
1875
						}
1876
			
1877
					}
1878
					$obj_header=false;
0 ignored issues
show
Unused Code introduced by
$obj_header is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1879
			} else { 
1880
					//We are inside the xref table
1881
					//$this->dumpContent($CurLine,"");
1882
					$xref_table=$xref_table+1;
1883
					switch($xref_table) {
1884
						case 2: 
1885 View Code Duplication
							if(preg_match("/^(\d+) (\d+)/",$CurLine,$match)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1886
								$refs_count=intval($match[2]);//xref_table length+1 (includes this line)
1887
								$lines['$_XREF_$']["infos"]["count"]=$refs_count-1; 
1888
								if($verbose_parsing) $this->dumpContent("Xref table length is $refs_count");
1889
							}else
1890
								if($verbose_parsing) $this->dumpContent("WARNING: Xref table length ignored!");
1891
						break;
1892
						case 3:
1893
							//Should be 0000000000 65535 f 
1894
							if($verbose_parsing) $this->dumpContent("this is Xref table header, should be 0000000000 65535 f ");
1895
						break;
1896
						default:
1897
							//xref entries
1898
							if($refs_count>0) {
1899
								$xref=$xref_table-3;
1900
								 
1901 View Code Duplication
								if($refs_count == 1) {//Last one , due to the shift, is the trailer
0 ignored issues
show
Bug introduced by
The variable $refs_count does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1902
									if(!preg_match("/^trailer/",$CurLine)) //if not, Houston we have a problem
1903
										$this->Error("xref_table length corrupted?: Trailer not found at expected!");			
1904
									else
1905
										$trailer_table=1;
1906
								}else {
1907
									$lines['$_XREF_$']["entries"][$xref]=$CurLine;
1908
									if($verbose_parsing) $this->dumpContent("Xref table entry for object $xref found.");
1909
								}
1910
								$refs_count--;	
1911
							} else { //We are inside the trailer
1912
							
1913
								if($trailer_table==1) { //should be <<
1914
									
1915
									if(trim($CurLine) != '') { //HACK: PDFCreator Version 1.0.0 has an extra CR after trailer
1916
										if(!preg_match("/<</",$CurLine,$match)) 
1917
											$this->Error("trailer_table corrupted?; missing start delimiter << ");
1918
										$trailer_table++;
1919
									}
1920
									
1921
				
1922
								}else if(($trailer_table>0)&&((!is_null($id_def))||preg_match("/^\/(Size|Root|Info|ID|DocChecksum)/",$CurLine,$match))) {
1923
								
1924
									//Value can be extracted using (\d+|\[[^\]]+\])
1925 View Code Duplication
									if(preg_match("/\/Size (\d+)/",$CurLine,$match)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1926
										//Seems to match with xref entries count..
1927
										$size_read=$match[1];
1928
										$this->info["size"]=$size_read;
1929
										if($verbose_parsing) $this->dumpContent("Size read ($size_read) for pdf found.");
1930
									}  
1931
1932
									if(preg_match("/^\/ID\s*\[\s*<([\da-fA-F]+)/",$CurLine,$match)) {
1933
										$oid=$match[1];
1934
										$id_def=true;
1935
										if($verbose_parsing) $this->dumpContent("ID chunk one ($oid) for pdf found.");
1936
										
1937
										//Determines if the ID definition is one line...
1938
										if(preg_match("/\>\s?\</",$CurLine,$match))
1939
											$id_single_line_def=true;
1940
							
1941
									}  
1942
									
1943
									if($id_def) {//we are inside the ID definition
1944
										if($id_single_line_def||$id_multi_line_def) {
1945
											//decode the second ID chunk
1946
											if(preg_match("/([\da-fA-F]+)>.*$/",$CurLine,$match)) {
1947
												$tid=$match[1];
1948
												$this->info["ID"]=array($oid,$tid);
0 ignored issues
show
Bug introduced by
The variable $oid does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1949
												if($verbose_parsing) $this->dumpContent("ID chunk two ($tid) for pdf found.");
1950
												$id_def=false;
1951
											}else
1952
												$this->Error("trailer_table corrupted?; ID chunk two can not be decoded ");
1953
										} else
1954
											$id_multi_line_def=true;
1955
									}
1956
									
1957 View Code Duplication
									if(preg_match("/^\/DocChecksum \/([\da-fA-F]+)/",$CurLine,$match)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1958
										$checksum=$match[1];
1959
										$this->info["checksum"]=$checksum;
1960
										if($verbose_parsing) $this->dumpContent("Checksum read ($checksum) for pdf found.");
1961
									}  
1962
									
1963
									if(preg_match("/>>/",$CurLine,$match)) 
1964
										$trailer_table=-1;//negative value: expects startxref to follow
1965
									
1966
									
1967
								} else {
1968
	
1969
									switch($trailer_table) {
1970
										case -1://startxref
1971
										if(!preg_match("/^startxref/",$CurLine,$match)) 
1972
											$this->Error("startxref tag expected, read $CurLine");
1973
										break;
1974
										case -2://startxref's value
1975
											if(preg_match("/^(\d+)/",$CurLine,$match)) {
1976
												$lines['$_XREF_$']["infos"]["start"]["value"]=intval($match[1]);
1977
												$lines['$_XREF_$']["infos"]["start"]["line"]=$Counter;
1978
											}else
1979
												$this->Error("startxref value expected, read $CurLine");
1980
										break;
1981
										default://%%EOF
1982
									}
1983
									$trailer_table--;
1984
											
1985
								}
1986
								
1987
							}
1988
					}
1989
					
1990
				}
1991
				
1992
                $this->pointer=$this->pointer+strlen($CurLine)+1; //+1 due to \n
1993
                $Counter++;
1994
            }
1995
       
1996
			if($this->verbose) {
1997
			
1998
				$refs=(array_key_exists('$_XREF_$',$lines)) ? $lines['$_XREF_$']["infos"]["count"] : 0; 
1999
				if($refs) {
2000
					$this->dumpContent("PDF parse retrieved $refs refs");
2001
				}else {
2002
					$this->dumpContent("PDF parse retrieved no refs, seems the xref table is broken or inacessible, this is bad!");
2003
				}
2004
			}
2005
			
2006
			return count($lines);
2007
        }
2008
		
2009
		 /**
2010
         * Protect ( ) that may be in value or names
2011
         * 
2012
		 * @access protected
2013
         * @param string $content  the FDF content to protect values
2014
		 * @return string the content protected
2015
         */
2016
		function _protectContentValues($content) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
2017
		//-------------------------------------------------
2018
		   $content=str_replace("\\(","$@#",$content);
2019
		   $content=str_replace("\\)","#@$",$content);
2020
		   return $content;
2021
		}
2022
		
2023
		 /**
2024
         * Unprotect ( ) that may be in value or names
2025
         *
2026
		 * @access protected
2027
         * @param string $content  the FDF content with protected values
2028
		 * @return string the content unprotected
2029
         */
2030
		function _unprotectContentValues($content) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
2031
		//--------------------------------------------------	
2032
		   $content=str_replace("$@#","\\(",$content);
2033
		   $content=str_replace("#@$","\\)",$content);
2034
		   $content=stripcslashes($content);
2035
		   return $content;
2036
		}
2037
		
2038
		 /**
2039
         * Parses the content of a FDF file and saved extracted field data 
2040
         *
2041
		 *@access public
2042
		 *@return array $fields the data of the fields parsed
2043
         */
2044
		function parseFDFContent(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
2045
		//-------------------------
2046
	   
2047
		   $content=$this->fdf_content;
2048
		   $content=$this->_protectContentValues($content);//protect ( ) that may be in value or names...
2049
		  
2050
		   if($this->verbose) $this->dumpEntries($content,"FDF parse");
2051
		   
2052
		   //..so that this regexp can do its job without annoyances 
2053
			if(preg_match_all("/(T|V)\s*\(([^\)]+)\)\s*\/(T|V)\s*\(([^\)]+)\)/", $content,$matches, PREG_PATTERN_ORDER)) {
2054
	   
2055
				$fMax=count($matches[0]);
2056
				$fields=array();
2057
				for($f=0;$f<$fMax;$f++) {
2058
					$value='';
2059
					$name='';
2060
					if($matches[1][$f]=="V") {
2061
						$value=$matches[2][$f];
2062
						if($matches[3][$f]=="T") 
2063
							$name=$matches[4][$f];
2064
						else 
2065
							$this->Error("Field $f ignored , incomplete field declaration, name is expected");
2066
					} else {
2067
						if($matches[1][$f]=="T") {
2068
							$name=$matches[2][$f];
2069
							if($matches[3][$f]=="V") 
2070
								$value=$matches[4][$f];
2071
							else 
2072
								$this->Error("Field $f ignored , incomplete field declaration, value is expected");
2073
						} else 
2074
							$this->Error("Field $f ignored , Invalid field keys ({$matches[0][$f]})");
2075
					}
2076
					if($name!='') {
2077
						if(array_key_exists($name,$fields)) 
2078
							 $this->Error("Field $f ignored , already defined");
2079
						else {
2080
							$name=$this->_unprotectContentValues($name);
2081
							$value=$this->_unprotectContentValues($value);
2082
							if($this->verbose) 
2083
								$this->dumpContent("FDF field [$name] has its value set to \"$value\"");
2084
							$fields[$name]=$value;
2085
						}
2086
					} else 
2087
						$this->Error("Field $f ignored , no name");
2088
					
2089
				}
2090
			} else
2091
				if($this->verbose) $this->dumpContent($fields,"FDF has no fields",false);
0 ignored issues
show
Bug introduced by
The variable $fields seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
2092
			
2093
			if($this->verbose) $this->dumpContent($fields,"FDF parsed",false);
0 ignored issues
show
Bug introduced by
The variable $fields does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2094
			
2095
			return $fields;
2096
		}
2097
		
2098
		
2099
        /**
2100
         * Close the opened file
2101
         */
2102
        function closeFile() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
2103
        //--------------------
2104
        	if (isset($this->f) && is_resource($this->f)) {
2105
        	    fclose($this->f);	
0 ignored issues
show
Bug introduced by
The property f does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
2106
        		unset($this->f);
2107
        	}	
2108
        }
2109
        
2110
        /**
2111
         * Print Error and die
2112
         *
2113
         * @param string $msg  Error-Message
2114
         */
2115
        function Error($msg) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
2116
        //--------------------
2117
        	die('<b>FPDF-Merge Error:</b> '.$msg);	
2118
        }
2119
		
2120
		
2121
	}
2122
	
2123
}
2124
2125
unset($__tmp);
2126
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...