Completed
Push — development ( 813154...a4b5b1 )
by Nils
07:28
created

tFPDF::_putimage()   D

Complexity

Conditions 13
Paths 480

Size

Total Lines 56
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 39
nc 480
nop 1
dl 0
loc 56
rs 4.5342
c 0
b 0
f 0

How to fix   Long Method    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
* tFPDF (based on FPDF 1.7)                                                    *
4
*                                                                              *
5
* Version:  1.24                                                               *
6
* Date:     2011-09-24                                                         *
7
* Author:   Ian Back <[email protected]>                                           *
8
* License:  LGPL                                                               *
9
*******************************************************************************/
10
11
define('tFPDF_VERSION', '1.24');
12
13
class tFPDF
14
{
15
16
var $unifontSubset;
17
var $page; // current page number
18
var $n; // current object number
19
var $offsets; // array of object offsets
20
var $buffer; // buffer holding in-memory PDF
21
var $pages; // array containing pages
22
var $state; // current document state
23
var $compress; // compression flag
24
var $k; // scale factor (number of points in user unit)
25
var $DefOrientation; // default orientation
26
var $CurOrientation; // current orientation
27
var $StdPageSizes; // standard page sizes
28
var $DefPageSize; // default page size
29
var $CurPageSize; // current page size
30
var $PageSizes; // used for pages with non default sizes or orientations
31
var $wPt, $hPt; // dimensions of current page in points
32
var $w, $h; // dimensions of current page in user unit
33
var $lMargin; // left margin
34
var $tMargin; // top margin
35
var $rMargin; // right margin
36
var $bMargin; // page break margin
37
var $cMargin; // cell margin
38
var $x, $y; // current position in user unit
39
var $lasth; // height of last printed cell
40
var $LineWidth; // line width in user unit
41
var $fontpath; // path containing fonts
42
var $CoreFonts; // array of core font names
43
var $fonts; // array of used fonts
44
var $FontFiles; // array of font files
45
var $diffs; // array of encoding differences
46
var $FontFamily; // current font family
47
var $FontStyle; // current font style
48
var $underline; // underlining flag
49
var $CurrentFont; // current font info
50
var $FontSizePt; // current font size in points
51
var $FontSize; // current font size in user unit
52
var $DrawColor; // commands for drawing color
53
var $FillColor; // commands for filling color
54
var $TextColor; // commands for text color
55
var $ColorFlag; // indicates whether fill and text colors are different
56
var $ws; // word spacing
57
var $images; // array of used images
58
var $PageLinks; // array of links in pages
59
var $links; // array of internal links
60
var $AutoPageBreak; // automatic page breaking
61
var $PageBreakTrigger; // threshold used to trigger page breaks
62
var $InHeader; // flag set when processing header
63
var $InFooter; // flag set when processing footer
64
var $ZoomMode; // zoom display mode
65
var $LayoutMode; // layout display mode
66
var $title; // title
67
var $subject; // subject
68
var $author; // author
69
var $keywords; // keywords
70
var $creator; // creator
71
var $AliasNbPages; // alias for total number of pages
72
var $PDFVersion; // PDF version number
73
74
/*******************************************************************************
75
*                                                                              *
76
*                               Public methods                                 *
77
*                                                                              *
78
*******************************************************************************/
79
function __construct($orientation = 'P', $unit = 'mm', $size = 'A4', $footer_text_1 = "Page")
0 ignored issues
show
Unused Code introduced by
The parameter $footer_text_1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
80
{
81
    // Some checks
82
    $this->_dochecks();
83
    // Initialization of properties
84
    $this->page = 0;
85
    $this->n = 2;
86
    $this->buffer = '';
87
    $this->pages = array();
88
    $this->PageSizes = array();
89
    $this->state = 0;
90
    $this->fonts = array();
91
    $this->FontFiles = array();
92
    $this->diffs = array();
93
    $this->images = array();
94
    $this->links = array();
95
    $this->InHeader = false;
96
    $this->InFooter = false;
97
    $this->lasth = 0;
98
    $this->FontFamily = '';
99
    $this->FontStyle = '';
100
    $this->FontSizePt = 12;
101
    $this->underline = false;
102
    $this->DrawColor = '0 G';
103
    $this->FillColor = '0 g';
104
    $this->TextColor = '0 g';
105
    $this->ColorFlag = false;
106
    $this->ws = 0;
107
    // Font path
108
    if (defined('FPDF_FONTPATH'))
109
    {
110
        $this->fontpath = FPDF_FONTPATH;
111
        if (substr($this->fontpath, -1) != '/' && substr($this->fontpath, -1) != '\\') {
112
                    $this->fontpath .= '/';
113
        }
114
    } elseif (is_dir(dirname(__FILE__).'/font')) {
115
            $this->fontpath = dirname(__FILE__).'/font/';
116
    } else {
117
            $this->fontpath = '';
118
    }
119
    // Core fonts
120
    $this->CoreFonts = array('courier', 'helvetica', 'times', 'symbol', 'zapfdingbats');
121
    // Scale factor
122
    if ($unit == 'pt') {
123
            $this->k = 1;
124
    } elseif ($unit == 'mm') {
125
            $this->k = 72 / 25.4;
126
    } elseif ($unit == 'cm') {
127
            $this->k = 72 / 2.54;
128
    } elseif ($unit == 'in') {
129
            $this->k = 72;
130
    } else {
131
            $this->Error('Incorrect unit: '.$unit);
132
    }
133
    // Page sizes
134
    $this->StdPageSizes = array('a3'=>array(841.89, 1190.55), 'a4'=>array(595.28, 841.89), 'a5'=>array(420.94, 595.28),
135
        'letter'=>array(612, 792), 'legal'=>array(612, 1008));
136
    $size = $this->_getpagesize($size);
137
    $this->DefPageSize = $size;
138
    $this->CurPageSize = $size;
139
    // Page orientation
140
    $orientation = strtolower($orientation);
141
    if ($orientation == 'p' || $orientation == 'portrait')
142
    {
143
        $this->DefOrientation = 'P';
144
        $this->w = $size[0];
145
        $this->h = $size[1];
146
    } elseif ($orientation == 'l' || $orientation == 'landscape')
147
    {
148
        $this->DefOrientation = 'L';
149
        $this->w = $size[1];
150
        $this->h = $size[0];
151
    } else {
152
            $this->Error('Incorrect orientation: '.$orientation);
153
    }
154
    $this->CurOrientation = $this->DefOrientation;
155
    $this->wPt = $this->w * $this->k;
156
    $this->hPt = $this->h * $this->k;
157
    // Page margins (1 cm)
158
    $margin = 28.35 / $this->k;
159
    $this->SetMargins($margin, $margin);
160
    // Interior cell margin (1 mm)
161
    $this->cMargin = $margin / 10;
162
    // Line width (0.2 mm)
163
    $this->LineWidth = .567 / $this->k;
164
    // Automatic page break
165
    $this->SetAutoPageBreak(true, 2 * $margin);
166
    // Default display mode
167
    $this->SetDisplayMode('default');
168
    // Enable compression
169
    $this->SetCompression(true);
170
    // Set default PDF version number
171
    $this->PDFVersion = '1.3';
172
}
173
174
/**
175
 * @param double $left
176
 * @param double $top
177
 */
178
function SetMargins($left, $top, $right = null)
179
{
180
    // Set left, top and right margins
181
    $this->lMargin = $left;
182
    $this->tMargin = $top;
183
    if ($right === null) {
184
            $right = $left;
185
    }
186
    $this->rMargin = $right;
187
}
188
189
function SetLeftMargin($margin)
190
{
191
    // Set left margin
192
    $this->lMargin = $margin;
193
    if ($this->page > 0 && $this->x < $margin) {
194
            $this->x = $margin;
195
    }
196
    }
197
198
function SetTopMargin($margin)
199
{
200
    // Set top margin
201
    $this->tMargin = $margin;
202
}
203
204
function SetRightMargin($margin)
205
{
206
    // Set right margin
207
    $this->rMargin = $margin;
208
}
209
210
/**
211
 * @param boolean $auto
212
 */
213
function SetAutoPageBreak($auto, $margin = 0)
214
{
215
    // Set auto page break mode and triggering margin
216
    $this->AutoPageBreak = $auto;
217
    $this->bMargin = $margin;
218
    $this->PageBreakTrigger = $this->h - $margin;
219
}
220
221
/**
222
 * @param string $zoom
223
 */
224
function SetDisplayMode($zoom, $layout = 'default')
225
{
226
    // Set display mode in viewer
227
    if ($zoom == 'fullpage' || $zoom == 'fullwidth' || $zoom == 'real' || $zoom == 'default' || !is_string($zoom))
228
        $this->ZoomMode = $zoom;
229
    else
230
        $this->Error('Incorrect zoom display mode: '.$zoom);
231
    if ($layout == 'single' || $layout == 'continuous' || $layout == 'two' || $layout == 'default')
232
        $this->LayoutMode = $layout;
233
    else
234
        $this->Error('Incorrect layout display mode: '.$layout);
235
}
236
237
/**
238
 * @param boolean $compress
239
 */
240
function SetCompression($compress)
241
{
242
    // Set page compression
243
    if (function_exists('gzcompress')) {
244
            $this->compress = $compress;
245
    } else {
246
            $this->compress = false;
247
    }
248
    }
249
250
function SetTitle($title, $isUTF8 = false)
251
{
252
    // Title of document
253
    if ($isUTF8) {
254
            $title = $this->_UTF8toUTF16($title);
255
    }
256
    $this->title = $title;
257
}
258
259
function SetSubject($subject, $isUTF8 = false)
260
{
261
    // Subject of document
262
    if ($isUTF8) {
263
            $subject = $this->_UTF8toUTF16($subject);
264
    }
265
    $this->subject = $subject;
266
}
267
268
function SetAuthor($author, $isUTF8 = false)
269
{
270
    // Author of document
271
    if ($isUTF8) {
272
            $author = $this->_UTF8toUTF16($author);
273
    }
274
    $this->author = $author;
275
}
276
277
function SetKeywords($keywords, $isUTF8 = false)
278
{
279
    // Keywords of document
280
    if ($isUTF8) {
281
            $keywords = $this->_UTF8toUTF16($keywords);
282
    }
283
    $this->keywords = $keywords;
284
}
285
286
function SetCreator($creator, $isUTF8 = false)
287
{
288
    // Creator of document
289
    if ($isUTF8) {
290
            $creator = $this->_UTF8toUTF16($creator);
291
    }
292
    $this->creator = $creator;
293
}
294
295
function AliasNbPages($alias = '{nb}')
296
{
297
    // Define an alias for total number of pages
298
    $this->AliasNbPages = $alias;
299
}
300
301
function Error($msg)
302
{
303
    // Fatal error
304
    die('<b>FPDF error:</b> '.$msg);
305
}
306
307
function Open()
308
{
309
    // Begin document
310
    $this->state = 1;
311
}
312
313
function Close()
314
{
315
    // Terminate document
316
    if ($this->state == 3) {
317
            return;
318
    }
319
    if ($this->page == 0) {
320
            $this->AddPage();
321
    }
322
    // Page footer
323
    $this->InFooter = true;
324
    $this->Footer();
325
    $this->InFooter = false;
326
    // Close page
327
    $this->_endpage();
328
    // Close document
329
    $this->_enddoc();
330
}
331
332
function AddPage($orientation = '', $size = '')
333
{
334
    // Start a new page
335
    if ($this->state == 0) {
336
            $this->Open();
337
    }
338
    $family = $this->FontFamily;
339
    $style = $this->FontStyle.($this->underline ? 'U' : '');
340
    $fontsize = $this->FontSizePt;
341
    $lw = $this->LineWidth;
342
    $dc = $this->DrawColor;
343
    $fc = $this->FillColor;
344
    $tc = $this->TextColor;
345
    $cf = $this->ColorFlag;
346
    if ($this->page > 0)
347
    {
348
        // Page footer
349
        $this->InFooter = true;
350
        $this->Footer();
351
        $this->InFooter = false;
352
        // Close page
353
        $this->_endpage();
354
    }
355
    // Start new page
356
    $this->_beginpage($orientation, $size);
357
    // Set line cap style to square
358
    $this->_out('2 J');
359
    // Set line width
360
    $this->LineWidth = $lw;
361
    $this->_out(sprintf('%.2F w', $lw * $this->k));
362
    // Set font
363
    if ($family) {
364
            $this->SetFont($family, $style, $fontsize);
365
    }
366
    // Set colors
367
    $this->DrawColor = $dc;
368
    if ($dc != '0 G') {
369
            $this->_out($dc);
370
    }
371
    $this->FillColor = $fc;
372
    if ($fc != '0 g') {
373
            $this->_out($fc);
374
    }
375
    $this->TextColor = $tc;
376
    $this->ColorFlag = $cf;
377
    // Page header
378
    $this->InHeader = true;
379
    $this->Header();
380
    $this->InHeader = false;
381
    // Restore line width
382
    if ($this->LineWidth != $lw)
383
    {
384
        $this->LineWidth = $lw;
385
        $this->_out(sprintf('%.2F w', $lw * $this->k));
386
    }
387
    // Restore font
388
    if ($family) {
389
            $this->SetFont($family, $style, $fontsize);
390
    }
391
    // Restore colors
392
    if ($this->DrawColor != $dc)
393
    {
394
        $this->DrawColor = $dc;
395
        $this->_out($dc);
396
    }
397
    if ($this->FillColor != $fc)
398
    {
399
        $this->FillColor = $fc;
400
        $this->_out($fc);
401
    }
402
    $this->TextColor = $tc;
403
    $this->ColorFlag = $cf;
404
}
405
406
function Header()
407
{
408
    // To be implemented in your own inherited class
409
}
410
411
function Footer()
412
{
413
    // To be implemented in your own inherited class
414
}
415
416
function PageNo()
417
{
418
    // Get current page number
419
    return $this->page;
420
}
421
422 View Code Duplication
function SetDrawColor($r, $g = null, $b = null)
0 ignored issues
show
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...
423
{
424
    // Set color for all stroking operations
425
    if (($r == 0 && $g == 0 && $b == 0) || $g === null) {
426
            $this->DrawColor = sprintf('%.3F G', $r / 255);
427
    } else {
428
            $this->DrawColor = sprintf('%.3F %.3F %.3F RG', $r / 255, $g / 255, $b / 255);
429
    }
430
    if ($this->page > 0) {
431
            $this->_out($this->DrawColor);
432
    }
433
    }
434
435
function SetFillColor($r, $g = null, $b = null)
436
{
437
    // Set color for all filling operations
438
    if (($r == 0 && $g == 0 && $b == 0) || $g === null) {
439
            $this->FillColor = sprintf('%.3F g', $r / 255);
440
    } else {
441
            $this->FillColor = sprintf('%.3F %.3F %.3F rg', $r / 255, $g / 255, $b / 255);
442
    }
443
    $this->ColorFlag = ($this->FillColor != $this->TextColor);
444
    if ($this->page > 0) {
445
            $this->_out($this->FillColor);
446
    }
447
    }
448
449 View Code Duplication
function SetTextColor($r, $g = null, $b = null)
0 ignored issues
show
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...
450
{
451
    // Set color for text
452
    if (($r == 0 && $g == 0 && $b == 0) || $g === null) {
453
            $this->TextColor = sprintf('%.3F g', $r / 255);
454
    } else {
455
            $this->TextColor = sprintf('%.3F %.3F %.3F rg', $r / 255, $g / 255, $b / 255);
456
    }
457
    $this->ColorFlag = ($this->FillColor != $this->TextColor);
458
}
459
460
function GetStringWidth($s)
461
{
462
    // Get width of a string in the current font
463
    $s = (string) $s;
464
    $cw = &$this->CurrentFont['cw'];
465
    $w = 0;
466
    if ($this->unifontSubset) {
467
        $unicode = $this->UTF8StringToArray($s);
468
        foreach ($unicode as $char) {
469
            if (isset($cw[$char])) { $w += (ord($cw[2 * $char]) << 8) + ord($cw[2 * $char + 1]); } else if ($char > 0 && $char < 128 && isset($cw[chr($char)])) { $w += $cw[chr($char)]; } else if (isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; } else if (isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; } else { $w += 500; }
470
        }
471
    } else {
472
        $l = strlen($s);
473
        for ($i = 0; $i < $l; $i++) {
474
                    $w += $cw[$s[$i]];
475
        }
476
    }
477
    return $w * $this->FontSize / 1000;
478
}
479
480
function SetLineWidth($width)
481
{
482
    // Set line width
483
    $this->LineWidth = $width;
484
    if ($this->page > 0) {
485
            $this->_out(sprintf('%.2F w', $width * $this->k));
486
    }
487
    }
488
489
function Line($x1, $y1, $x2, $y2)
490
{
491
    // Draw a line
492
    $this->_out(sprintf('%.2F %.2F m %.2F %.2F l S', $x1 * $this->k, ($this->h - $y1) * $this->k, $x2 * $this->k, ($this->h - $y2) * $this->k));
493
}
494
495
function Rect($x, $y, $w, $h, $style = '')
496
{
497
    // Draw a rectangle
498
    if ($style == 'F') {
499
            $op = 'f';
500
    } elseif ($style == 'FD' || $style == 'DF') {
501
            $op = 'B';
502
    } else {
503
            $op = 'S';
504
    }
505
    $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s', $x * $this->k, ($this->h - $y) * $this->k, $w * $this->k, -$h * $this->k, $op));
506
}
507
508
/**
509
 * @param string $family
510
 */
511
function AddFont($family, $style = '', $file = '', $uni = false)
512
{
513
    // Add a TrueType, OpenType or Type1 font
514
    $family = strtolower($family);
515
    $style = strtoupper($style);
516
    if ($style == 'IB')
517
        $style = 'BI';
518
    if ($file == '') {
519
        if ($uni) {
520
        $file = str_replace(' ', '', $family).strtolower($style).'.ttf';
521
        }
522
        else {
523
        $file = str_replace(' ', '', $family).strtolower($style).'.php';
524
        }
525
    }
526
    $fontkey = $family.$style;
527
    if (isset($this->fonts[$fontkey]))
528
        return;
529
530
    if ($uni) {
531
        if (defined("_SYSTEM_TTFONTS") && file_exists(_SYSTEM_TTFONTS.$file)) { $ttffilename = _SYSTEM_TTFONTS.$file; }
532
        else { $ttffilename = $this->_getfontpath().'unifont/'.$file; }
533
        $unifilename = $this->_getfontpath().'unifont/'.strtolower(substr($file, 0, (strpos($file, '.'))));
534
        $name = '';
535
        $originalsize = 0;
536
        $ttfstat = stat($ttffilename);
537
        if (file_exists($unifilename.'.mtx.php')) {
538
            include($unifilename.'.mtx.php');
539
        }
540
        if (!isset($type) || !isset($name) || $originalsize != $ttfstat['size']) {
0 ignored issues
show
Bug introduced by
The variable $type seems only to be defined at a later point. As such the call to isset() seems to always evaluate to false.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
541
            $ttffile = $ttffilename;
542
            require_once($this->_getfontpath().'unifont/ttfonts.php');
543
            $ttf = new TTFontFile();
544
            $ttf->getMetrics($ttffile);
545
            $cw = $ttf->charWidths;
546
            $name = preg_replace('/[ ()]/', '', $ttf->fullName);
547
548
            $desc = array('Ascent'=>round($ttf->ascent),
549
            'Descent'=>round($ttf->descent),
550
            'CapHeight'=>round($ttf->capHeight),
551
            'Flags'=>$ttf->flags,
552
            'FontBBox'=>'['.round($ttf->bbox[0])." ".round($ttf->bbox[1])." ".round($ttf->bbox[2])." ".round($ttf->bbox[3]).']',
553
            'ItalicAngle'=>$ttf->italicAngle,
554
            'StemV'=>round($ttf->stemV),
555
            'MissingWidth'=>round($ttf->defaultWidth));
556
            $up = round($ttf->underlinePosition);
557
            $ut = round($ttf->underlineThickness);
558
            $originalsize = $ttfstat['size'] + 0;
559
            $type = 'TTF';
560
            // Generate metrics .php file
561
            $s = '<?php'."\n";
562
            $s .= '$name=\''.$name."';\n";
563
            $s .= '$type=\''.$type."';\n";
564
            $s .= '$desc='.var_export($desc, true).";\n";
565
            $s .= '$up='.$up.";\n";
566
            $s .= '$ut='.$ut.";\n";
567
            $s .= '$ttffile=\''.$ttffile."';\n";
568
            $s .= '$originalsize='.$originalsize.";\n";
569
            $s .= '$fontkey=\''.$fontkey."';\n";
570
            $s .= "?>";
571
            if (is_writable(dirname($this->_getfontpath().'unifont/'.'x'))) {
572
                $fh = fopen($unifilename.'.mtx.php', "w");
573
                fwrite($fh, $s, strlen($s));
574
                fclose($fh);
575
                $fh = fopen($unifilename.'.cw.dat', "wb");
576
                fwrite($fh, $cw, strlen($cw));
577
                fclose($fh);
578
                @unlink($unifilename.'.cw127.php');
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...
579
            }
580
            unset($ttf);
581
        } else {
582
            $cw = @file_get_contents($unifilename.'.cw.dat');
583
        }
584
        $i = count($this->fonts) + 1;
585
        if (!empty($this->AliasNbPages)) {
586
                    $sbarr = range(0, 57);
587
        } else {
588
                    $sbarr = range(0, 32);
589
        }
590
        $this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subset'=>$sbarr, 'unifilename'=>$unifilename);
0 ignored issues
show
Bug introduced by
The variable $desc 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 $up 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 $ut 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 $ttffile 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...
591
592
        $this->FontFiles[$fontkey] = array('length1'=>$originalsize, 'type'=>"TTF", 'ttffile'=>$ttffile);
593
        $this->FontFiles[$file] = array('type'=>"TTF");
594
        unset($cw);
595
    } else {
596
        $info = $this->_loadfont($file);
597
        $info['i'] = count($this->fonts) + 1;
598
        if (!empty($info['diff']))
599
        {
600
            // Search existing encodings
601
            $n = array_search($info['diff'], $this->diffs);
602
            if (!$n)
603
            {
604
                $n = count($this->diffs) + 1;
605
                $this->diffs[$n] = $info['diff'];
606
            }
607
            $info['diffn'] = $n;
608
        }
609
        if (!empty($info['file']))
610
        {
611
            // Embedded font
612
            if ($info['type'] == 'TrueType') {
613
                            $this->FontFiles[$info['file']] = array('length1'=>$info['originalsize']);
614
            } else {
615
                            $this->FontFiles[$info['file']] = array('length1'=>$info['size1'], 'length2'=>$info['size2']);
616
            }
617
        }
618
        $this->fonts[$fontkey] = $info;
619
    }
620
}
621
622
/**
623
 * @param string $family
624
 */
625
function SetFont($family, $style = '', $size = 0)
626
{
627
    // Select a font; size given in points
628
    if ($family == '') {
629
            $family = $this->FontFamily;
630
    } else {
631
            $family = strtolower($family);
632
    }
633
    $style = strtoupper($style);
634
    if (strpos($style, 'U') !== false)
635
    {
636
        $this->underline = true;
637
        $style = str_replace('U', '', $style);
638
    } else {
639
            $this->underline = false;
640
    }
641
    if ($style == 'IB') {
642
            $style = 'BI';
643
    }
644
    if ($size == 0) {
645
            $size = $this->FontSizePt;
646
    }
647
    // Test if font is already selected
648
    if ($this->FontFamily == $family && $this->FontStyle == $style && $this->FontSizePt == $size) {
649
            return;
650
    }
651
    // Test if font is already loaded
652
    $fontkey = $family.$style;
653
    if (!isset($this->fonts[$fontkey]))
654
    {
655
        // Test if one of the core fonts
656
        if ($family == 'arial') {
657
                    $family = 'helvetica';
658
        }
659
        if (in_array($family, $this->CoreFonts))
660
        {
661
            if ($family == 'symbol' || $family == 'zapfdingbats') {
662
                            $style = '';
663
            }
664
            $fontkey = $family.$style;
665
            if (!isset($this->fonts[$fontkey])) {
666
                            $this->AddFont($family, $style);
667
            }
668
        } else {
669
                    $this->Error('Undefined font: '.$family.' '.$style);
670
        }
671
    }
672
    // Select it
673
    $this->FontFamily = $family;
674
    $this->FontStyle = $style;
675
    $this->FontSizePt = $size;
676
    $this->FontSize = $size / $this->k;
677
    $this->CurrentFont = &$this->fonts[$fontkey];
678
    if ($this->fonts[$fontkey]['type'] == 'TTF') { $this->unifontSubset = true; } else { $this->unifontSubset = false; }
679 View Code Duplication
    if ($this->page > 0) {
680
            $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
681
    }
682
    }
683
684
function SetFontSize($size)
685
{
686
    // Set font size in points
687
    if ($this->FontSizePt == $size) {
688
            return;
689
    }
690
    $this->FontSizePt = $size;
691
    $this->FontSize = $size / $this->k;
692 View Code Duplication
    if ($this->page > 0) {
693
            $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
694
    }
695
    }
696
697
function AddLink()
698
{
699
    // Create a new internal link
700
    $n = count($this->links) + 1;
701
    $this->links[$n] = array(0, 0);
702
    return $n;
703
}
704
705
function SetLink($link, $y = 0, $page = -1)
706
{
707
    // Set destination of internal link
708
    if ($y == -1) {
709
            $y = $this->y;
710
    }
711
    if ($page == -1) {
712
            $page = $this->page;
713
    }
714
    $this->links[$link] = array($page, $y);
715
}
716
717
/**
718
 * @param double $y
719
 * @param string $link
720
 */
721
function Link($x, $y, $w, $h, $link)
722
{
723
    // Put a link on the page
724
    $this->PageLinks[$this->page][] = array($x * $this->k, $this->hPt - $y * $this->k, $w * $this->k, $h * $this->k, $link);
725
}
726
727
function Text($x, $y, $txt)
728
{
729
    // Output a string
730
    if ($this->unifontSubset)
731
    {
732
        $txt2 = '('.$this->_escape($this->UTF8ToUTF16BE($txt, false)).')';
733
        foreach ($this->UTF8StringToArray($txt) as $uni) {
734
                    $this->CurrentFont['subset'][$uni] = $uni;
735
        }
736
    } else {
737
            $txt2 = '('.$this->_escape($txt).')';
738
    }
739
    $s = sprintf('BT %.2F %.2F Td %s Tj ET', $x * $this->k, ($this->h - $y) * $this->k, $txt2);
740
    if ($this->underline && $txt != '') {
741
            $s .= ' '.$this->_dounderline($x, $y, $txt);
742
    }
743
    if ($this->ColorFlag) {
744
            $s = 'q '.$this->TextColor.' '.$s.' Q';
745
    }
746
    $this->_out($s);
747
}
748
749
function AcceptPageBreak()
750
{
751
    // Accept automatic page break or not
752
    return $this->AutoPageBreak;
753
}
754
755
function Cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = false, $link = '')
756
{
757
    // Output a cell
758
    $k = $this->k;
759
    if ($this->y + $h > $this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
760
    {
761
        // Automatic page break
762
        $x = $this->x;
763
        $ws = $this->ws;
764
        if ($ws > 0)
765
        {
766
            $this->ws = 0;
767
            $this->_out('0 Tw');
768
        }
769
        $this->AddPage($this->CurOrientation, $this->CurPageSize);
0 ignored issues
show
Documentation introduced by
$this->CurPageSize is of type array<integer,integer|double>, but the function expects a string.

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...
770
        $this->x = $x;
771
        if ($ws > 0)
772
        {
773
            $this->ws = $ws;
774
            $this->_out(sprintf('%.3F Tw', $ws * $k));
775
        }
776
    }
777
    if ($w == 0) {
778
            $w = $this->w - $this->rMargin - $this->x;
779
    }
780
    $s = '';
781
    if ($fill || $border == 1)
782
    {
783
        if ($fill) {
784
                    $op = ($border == 1) ? 'B' : 'f';
785
        } else {
786
                    $op = 'S';
787
        }
788
        $s = sprintf('%.2F %.2F %.2F %.2F re %s ', $this->x * $k, ($this->h - $this->y) * $k, $w * $k, -$h * $k, $op);
789
    }
790
    if (is_string($border))
791
    {
792
        $x = $this->x;
793
        $y = $this->y;
794 View Code Duplication
        if (strpos($border, 'L') !== false) {
795
                    $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $x * $k, ($this->h - $y) * $k, $x * $k, ($this->h - ($y + $h)) * $k);
796
        }
797 View Code Duplication
        if (strpos($border, 'T') !== false) {
798
                    $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $x * $k, ($this->h - $y) * $k, ($x + $w) * $k, ($this->h - $y) * $k);
799
        }
800 View Code Duplication
        if (strpos($border, 'R') !== false) {
801
                    $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', ($x + $w) * $k, ($this->h - $y) * $k, ($x + $w) * $k, ($this->h - ($y + $h)) * $k);
802
        }
803 View Code Duplication
        if (strpos($border, 'B') !== false) {
804
                    $s .= sprintf('%.2F %.2F m %.2F %.2F l S ', $x * $k, ($this->h - ($y + $h)) * $k, ($x + $w) * $k, ($this->h - ($y + $h)) * $k);
805
        }
806
    }
807
    if ($txt !== '')
808
    {
809
        if ($align == 'R') {
810
                    $dx = $w - $this->cMargin - $this->GetStringWidth($txt);
811
        } elseif ($align == 'C') {
812
                    $dx = ($w - $this->GetStringWidth($txt)) / 2;
813
        } else {
814
                    $dx = $this->cMargin;
815
        }
816
        if ($this->ColorFlag) {
817
                    $s .= 'q '.$this->TextColor.' ';
818
        }
819
820
        // If multibyte, Tw has no effect - do word spacing using an adjustment before each space
821
        if ($this->ws && $this->unifontSubset) {
822
            foreach ($this->UTF8StringToArray($txt) as $uni) {
823
                            $this->CurrentFont['subset'][$uni] = $uni;
824
            }
825
            $space = $this->_escape($this->UTF8ToUTF16BE(' ', false));
826
            $s .= sprintf('BT 0 Tw %.2F %.2F Td [', ($this->x + $dx) * $k, ($this->h - ($this->y + .5 * $h + .3 * $this->FontSize)) * $k);
827
            $t = explode(' ', $txt);
828
            $numt = count($t);
829
            for ($i = 0; $i < $numt; $i++) {
830
                $tx = $t[$i];
831
                $tx = '('.$this->_escape($this->UTF8ToUTF16BE($tx, false)).')';
832
                $s .= sprintf('%s ', $tx);
833
                if (($i + 1) < $numt) {
834
                    $adj = -($this->ws * $this->k) * 1000 / $this->FontSizePt;
835
                    $s .= sprintf('%d(%s) ', $adj, $space);
836
                }
837
            }
838
            $s .= '] TJ';
839
            $s .= ' ET';
840
        } else {
841
            if ($this->unifontSubset)
842
            {
843
                $txt2 = '('.$this->_escape($this->UTF8ToUTF16BE($txt, false)).')';
844
                foreach ($this->UTF8StringToArray($txt) as $uni) {
845
                                    $this->CurrentFont['subset'][$uni] = $uni;
846
                }
847
            } else {
848
                            $txt2 = '('.str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt))).')';
849
            }
850
            $s .= sprintf('BT %.2F %.2F Td %s Tj ET', ($this->x + $dx) * $k, ($this->h - ($this->y + .5 * $h + .3 * $this->FontSize)) * $k, $txt2);
851
        }
852
        if ($this->underline) {
853
                    $s .= ' '.$this->_dounderline($this->x + $dx, $this->y + .5 * $h + .3 * $this->FontSize, $txt);
854
        }
855
        if ($this->ColorFlag) {
856
                    $s .= ' Q';
857
        }
858
        if ($link) {
859
                    $this->Link($this->x + $dx, $this->y + .5 * $h - .5 * $this->FontSize, $this->GetStringWidth($txt), $this->FontSize, $link);
860
        }
861
    }
862
    if ($s) {
863
            $this->_out($s);
864
    }
865
    $this->lasth = $h;
866
    if ($ln > 0)
867
    {
868
        // Go to next line
869
        $this->y += $h;
870
        if ($ln == 1) {
871
                    $this->x = $this->lMargin;
872
        }
873
    } else {
874
            $this->x += $w;
875
    }
876
    }
877
878
function MultiCell($w, $h, $txt, $border = 0, $align = 'J', $fill = false)
879
{
880
    // Output text with automatic or explicit line breaks
881
    $cw = &$this->CurrentFont['cw'];
882
    if ($w == 0) {
883
            $w = $this->w - $this->rMargin - $this->x;
884
    }
885
    $wmax = ($w - 2 * $this->cMargin);
886
    $s = str_replace("\r", '', $txt);
887
    if ($this->unifontSubset) {
888
        $nb = mb_strlen($s, 'utf-8');
889
        while ($nb > 0 && mb_substr($s, $nb - 1, 1, 'utf-8') == "\n") {
890
            $nb--;
891
        }
892
    } else {
893
        $nb = strlen($s);
894
        if ($nb > 0 && $s[$nb - 1] == "\n") {
895
                    $nb--;
896
        }
897
    }
898
    $b = 0;
899
    if ($border)
900
    {
901
        if ($border == 1)
902
        {
903
            $border = 'LTRB';
904
            $b = 'LRT';
905
            $b2 = 'LR';
906
        } else
907
        {
908
            $b2 = '';
909
            if (strpos($border, 'L') !== false) {
910
                            $b2 .= 'L';
911
            }
912
            if (strpos($border, 'R') !== false) {
913
                            $b2 .= 'R';
914
            }
915
            $b = (strpos($border, 'T') !== false) ? $b2.'T' : $b2;
916
        }
917
    }
918
    $sep = -1;
919
    $i = 0;
920
    $j = 0;
921
    $l = 0;
922
    $ns = 0;
923
    $nl = 1;
924
    while ($i < $nb)
925
    {
926
        // Get next character
927 View Code Duplication
        if ($this->unifontSubset) {
928
            $c = mb_substr($s, $i, 1, 'UTF-8');
929
        } else {
930
            $c = $s[$i];
931
        }
932
        if ($c == "\n")
933
        {
934
            // Explicit line break
935
            if ($this->ws > 0)
936
            {
937
                $this->ws = 0;
938
                $this->_out('0 Tw');
939
            }
940 View Code Duplication
            if ($this->unifontSubset) {
941
                $this->Cell($w, $h, mb_substr($s, $j, $i - $j, 'UTF-8'), $b, 2, $align, $fill);
942
            } else {
943
                $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
944
            }
945
            $i++;
946
            $sep = -1;
947
            $j = $i;
948
            $l = 0;
949
            $ns = 0;
950
            $nl++;
951
            if ($border && $nl == 2) {
952
                            $b = $b2;
0 ignored issues
show
Bug introduced by
The variable $b2 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...
953
            }
954
            continue;
955
        }
956
        if ($c == ' ')
957
        {
958
            $sep = $i;
959
            $ls = $l;
960
            $ns++;
961
        }
962
963 View Code Duplication
        if ($this->unifontSubset) { $l += $this->GetStringWidth($c); } else { $l += $cw[$c] * $this->FontSize / 1000; }
964
965
        if ($l > $wmax)
966
        {
967
            // Automatic line break
968
            if ($sep == -1)
969
            {
970
                if ($i == $j) {
971
                                    $i++;
972
                }
973
                if ($this->ws > 0)
974
                {
975
                    $this->ws = 0;
976
                    $this->_out('0 Tw');
977
                }
978 View Code Duplication
                if ($this->unifontSubset) {
979
                    $this->Cell($w, $h, mb_substr($s, $j, $i - $j, 'UTF-8'), $b, 2, $align, $fill);
980
                } else {
981
                    $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
982
                }
983
            } else
984
            {
985
                if ($align == 'J')
986
                {
987
                    $this->ws = ($ns > 1) ? ($wmax - $ls) / ($ns - 1) : 0;
0 ignored issues
show
Bug introduced by
The variable $ls 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...
988
                    $this->_out(sprintf('%.3F Tw', $this->ws * $this->k));
989
                }
990 View Code Duplication
                if ($this->unifontSubset) {
991
                    $this->Cell($w, $h, mb_substr($s, $j, $sep - $j, 'UTF-8'), $b, 2, $align, $fill);
992
                } else {
993
                    $this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill);
994
                }
995
                $i = $sep + 1;
996
            }
997
            $sep = -1;
998
            $j = $i;
999
            $l = 0;
1000
            $ns = 0;
1001
            $nl++;
1002
            if ($border && $nl == 2) {
1003
                            $b = $b2;
1004
            }
1005
        } else {
1006
                    $i++;
1007
        }
1008
    }
1009
    // Last chunk
1010
    if ($this->ws > 0)
1011
    {
1012
        $this->ws = 0;
1013
        $this->_out('0 Tw');
1014
    }
1015
    if ($border && strpos($border, 'B') !== false) {
1016
            $b .= 'B';
1017
    }
1018 View Code Duplication
    if ($this->unifontSubset) {
1019
        $this->Cell($w, $h, mb_substr($s, $j, $i - $j, 'UTF-8'), $b, 2, $align, $fill);
1020
    } else {
1021
        $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
1022
    }
1023
    $this->x = $this->lMargin;
1024
}
1025
1026
function Write($h, $txt, $link = '')
1027
{
1028
    // Output text in flowing mode
1029
    $cw = &$this->CurrentFont['cw'];
1030
    $w = $this->w - $this->rMargin - $this->x;
1031
1032
    $wmax = ($w - 2 * $this->cMargin);
1033
    $s = str_replace("\r", '', $txt);
1034
    if ($this->unifontSubset) {
1035
        $nb = mb_strlen($s, 'UTF-8');
1036
        if ($nb == 1 && $s == " ") {
1037
            $this->x += $this->GetStringWidth($s);
1038
            return;
1039
        }
1040
    } else {
1041
        $nb = strlen($s);
1042
    }
1043
    $sep = -1;
1044
    $i = 0;
1045
    $j = 0;
1046
    $l = 0;
1047
    $nl = 1;
1048
    while ($i < $nb)
1049
    {
1050
        // Get next character
1051 View Code Duplication
        if ($this->unifontSubset) {
1052
            $c = mb_substr($s, $i, 1, 'UTF-8');
1053
        } else {
1054
            $c = $s[$i];
1055
        }
1056
        if ($c == "\n")
1057
        {
1058
            // Explicit line break
1059 View Code Duplication
            if ($this->unifontSubset) {
1060
                $this->Cell($w, $h, mb_substr($s, $j, $i - $j, 'UTF-8'), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
1061
            } else {
1062
                $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
1063
            }
1064
            $i++;
1065
            $sep = -1;
1066
            $j = $i;
1067
            $l = 0;
1068 View Code Duplication
            if ($nl == 1)
1069
            {
1070
                $this->x = $this->lMargin;
1071
                $w = $this->w - $this->rMargin - $this->x;
1072
                $wmax = ($w - 2 * $this->cMargin);
1073
            }
1074
            $nl++;
1075
            continue;
1076
        }
1077
        if ($c == ' ') {
1078
                    $sep = $i;
1079
        }
1080
1081 View Code Duplication
        if ($this->unifontSubset) { $l += $this->GetStringWidth($c); } else { $l += $cw[$c] * $this->FontSize / 1000; }
1082
1083
        if ($l > $wmax)
1084
        {
1085
            // Automatic line break
1086
            if ($sep == -1)
1087
            {
1088
                if ($this->x > $this->lMargin)
1089
                {
1090
                    // Move to next line
1091
                    $this->x = $this->lMargin;
1092
                    $this->y += $h;
1093
                    $w = $this->w - $this->rMargin - $this->x;
1094
                    $wmax = ($w - 2 * $this->cMargin);
1095
                    $i++;
1096
                    $nl++;
1097
                    continue;
1098
                }
1099
                if ($i == $j) {
1100
                                    $i++;
1101
                }
1102 View Code Duplication
                if ($this->unifontSubset) {
1103
                    $this->Cell($w, $h, mb_substr($s, $j, $i - $j, 'UTF-8'), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
1104
                } else {
1105
                    $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
1106
                }
1107 View Code Duplication
            } else
1108
            {
1109
                if ($this->unifontSubset) {
1110
                    $this->Cell($w, $h, mb_substr($s, $j, $sep - $j, 'UTF-8'), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
1111
                } else {
1112
                    $this->Cell($w, $h, substr($s, $j, $sep - $j), 0, 2, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
1113
                }
1114
                $i = $sep + 1;
1115
            }
1116
            $sep = -1;
1117
            $j = $i;
1118
            $l = 0;
1119 View Code Duplication
            if ($nl == 1)
1120
            {
1121
                $this->x = $this->lMargin;
1122
                $w = $this->w - $this->rMargin - $this->x;
1123
                $wmax = ($w - 2 * $this->cMargin);
1124
            }
1125
            $nl++;
1126
        } else {
1127
                    $i++;
1128
        }
1129
    }
1130
    // Last chunk
1131 View Code Duplication
    if ($i != $j) {
1132
        if ($this->unifontSubset) {
1133
            $this->Cell($l, $h, mb_substr($s, $j, $i - $j, 'UTF-8'), 0, 0, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
1134
        } else {
1135
            $this->Cell($l, $h, substr($s, $j), 0, 0, '', 0, $link);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

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...
1136
        }
1137
    }
1138
}
1139
1140
/**
1141
 * @param integer $h
1142
 */
1143
function Ln($h = null)
1144
{
1145
    // Line feed; default value is last cell height
1146
    $this->x = $this->lMargin;
1147
    if ($h === null) {
1148
            $this->y += $this->lasth;
1149
    } else {
1150
            $this->y += $h;
1151
    }
1152
    }
1153
1154
function Image($file, $x = null, $y = null, $w = 0, $h = 0, $type = '', $link = '')
1155
{
1156
    // Put an image on the page
1157
    if (!isset($this->images[$file]))
1158
    {
1159
        // First use of this image, get info
1160
        if ($type == '')
1161
        {
1162
            $pos = strrpos($file, '.');
1163
            if (!$pos) {
1164
                            $this->Error('Image file has no extension and no type was specified: '.$file);
1165
            }
1166
            $type = substr($file, $pos + 1);
1167
        }
1168
        $type = strtolower($type);
1169
        if ($type == 'jpeg') {
1170
                    $type = 'jpg';
1171
        }
1172
        $mtd = '_parse'.$type;
1173
        if (!method_exists($this, $mtd)) {
1174
                    $this->Error('Unsupported image type: '.$type);
1175
        }
1176
        $info = $this->$mtd($file);
1177
        $info['i'] = count($this->images) + 1;
1178
        $this->images[$file] = $info;
1179
    } else {
1180
            $info = $this->images[$file];
1181
    }
1182
1183
    // Automatic width and height calculation if needed
1184
    if ($w == 0 && $h == 0)
1185
    {
1186
        // Put image at 96 dpi
1187
        $w = -96;
1188
        $h = -96;
1189
    }
1190
    if ($w < 0) {
1191
            $w = -$info['w'] * 72 / $w / $this->k;
1192
    }
1193
    if ($h < 0) {
1194
            $h = -$info['h'] * 72 / $h / $this->k;
1195
    }
1196
    if ($w == 0) {
1197
            $w = $h * $info['w'] / $info['h'];
1198
    }
1199
    if ($h == 0) {
1200
            $h = $w * $info['h'] / $info['w'];
1201
    }
1202
1203
    // Flowing mode
1204
    if ($y === null)
1205
    {
1206
        if ($this->y + $h > $this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
1207
        {
1208
            // Automatic page break
1209
            $x2 = $this->x;
1210
            $this->AddPage($this->CurOrientation, $this->CurPageSize);
0 ignored issues
show
Documentation introduced by
$this->CurPageSize is of type array<integer,integer|double>, but the function expects a string.

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...
1211
            $this->x = $x2;
1212
        }
1213
        $y = $this->y;
1214
        $this->y += $h;
1215
    }
1216
1217
    if ($x === null) {
1218
            $x = $this->x;
1219
    }
1220
    $this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%d Do Q', $w * $this->k, $h * $this->k, $x * $this->k, ($this->h - ($y + $h)) * $this->k, $info['i']));
1221
    if ($link) {
1222
            $this->Link($x, $y, $w, $h, $link);
1223
    }
1224
    }
1225
1226
function GetX()
1227
{
1228
    // Get x position
1229
    return $this->x;
1230
}
1231
1232
function SetX($x)
1233
{
1234
    // Set x position
1235
    if ($x >= 0) {
1236
            $this->x = $x;
1237
    } else {
1238
            $this->x = $this->w + $x;
1239
    }
1240
    }
1241
1242
function GetY()
1243
{
1244
    // Get y position
1245
    return $this->y;
1246
}
1247
1248
function SetY($y)
1249
{
1250
    // Set y position and reset x
1251
    $this->x = $this->lMargin;
1252
    if ($y >= 0) {
1253
            $this->y = $y;
1254
    } else {
1255
            $this->y = $this->h + $y;
1256
    }
1257
    }
1258
1259
function SetXY($x, $y)
1260
{
1261
    // Set x and y positions
1262
    $this->SetY($y);
1263
    $this->SetX($x);
1264
}
1265
1266
function Output($name = '', $dest = '')
1267
{
1268
    // Output PDF to some destination
1269
    if ($this->state < 3) {
1270
            $this->Close();
1271
    }
1272
    $dest = strtoupper($dest);
1273
    if ($dest == '')
1274
    {
1275
        if ($name == '')
1276
        {
1277
            $name = 'doc.pdf';
1278
            $dest = 'I';
1279
        } else {
1280
                    $dest = 'F';
1281
        }
1282
    }
1283
    switch ($dest)
1284
    {
1285 View Code Duplication
        case 'I':
1286
            // Send to standard output
1287
            $this->_checkoutput();
1288
            if (PHP_SAPI != 'cli')
1289
            {
1290
                // We send to a browser
1291
                header('Content-Type: application/pdf');
1292
                header('Content-Disposition: inline; filename="'.$name.'"');
1293
                header('Cache-Control: private, max-age=0, must-revalidate');
1294
                header('Pragma: public');
1295
            }
1296
            echo $this->buffer;
0 ignored issues
show
Security Cross-Site Scripting introduced by
$this->buffer can contain request data and is used in output context(s) leading to a potential security vulnerability.

3 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['pdf_password'] is passed to FPDF_Protection::SetProtection() in sources/export.queries.php on line 210
  1. Read from $_POST, and $_POST['pdf_password'] is passed to FPDF_Protection::SetProtection()
    in sources/export.queries.php on line 210
  2. $user_pass is passed to FPDF_Protection::_generateencryptionkey()
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 97
  3. $user_pass . $this->padding is passed through substr(), and $user_pass is assigned
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 202
  4. Data is passed through mcrypt_encrypt()
    in vendor/includes/libraries/Pdf/Tfpdf/fpdf.php on line 20
  5. FPDF_Protection::$Ovalue is assigned
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 205
  6. Tainted property FPDF_Protection::$Ovalue is read
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 151
  7. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1467
  8. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1468
  9. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1469
  10. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1470
  11. '/O (' . $this->_escape($this->Ovalue) . ')' is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 151
  12. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  13. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1296
  2. Path: Read from $_POST, and $_POST['date'] is passed to tFPDF::Cell() in sources/views.queries.php on line 108
  1. Read from $_POST, and $_POST['date'] is passed to tFPDF::Cell()
    in sources/views.queries.php on line 108
  2. $txt is passed through str_replace(), and str_replace('\\', '\\\\', $txt) is passed through str_replace(), and str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)) is passed through str_replace(), and $txt2 is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 848
  3. $txt2 is passed through sprintf(), and $s is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 850
  4. $s is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 863
  5. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  6. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1296
  3. Path: Read from $_POST, and $_POST['text'] is escaped by addslashes() for sql, xpath context(s), and addslashes($_POST['text']) is passed through explode(), and $line is assigned in sources/views.queries.php on line 724
  1. Read from $_POST, and $_POST['text'] is escaped by addslashes() for sql, xpath context(s), and addslashes($_POST['text']) is passed through explode(), and $line is assigned
    in sources/views.queries.php on line 724
  2. $line is passed through explode(), and $elem is assigned
    in sources/views.queries.php on line 725
  3. $elem[0] is passed to tFPDF::Cell()
    in sources/views.queries.php on line 727
  4. $txt is passed through str_replace(), and str_replace('\\', '\\\\', $txt) is passed through str_replace(), and str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)) is passed through str_replace(), and $txt2 is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 848
  5. $txt2 is passed through sprintf(), and $s is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 850
  6. $s is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 863
  7. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  8. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1296

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
1297
            break;
1298 View Code Duplication
        case 'D':
1299
            // Download file
1300
            $this->_checkoutput();
1301
            header('Content-Type: application/x-download');
1302
            header('Content-Disposition: attachment; filename="'.$name.'"');
1303
            header('Cache-Control: private, max-age=0, must-revalidate');
1304
            header('Pragma: public');
1305
            echo $this->buffer;
0 ignored issues
show
Security Cross-Site Scripting introduced by
$this->buffer can contain request data and is used in output context(s) leading to a potential security vulnerability.

3 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['pdf_password'] is passed to FPDF_Protection::SetProtection() in sources/export.queries.php on line 210
  1. Read from $_POST, and $_POST['pdf_password'] is passed to FPDF_Protection::SetProtection()
    in sources/export.queries.php on line 210
  2. $user_pass is passed to FPDF_Protection::_generateencryptionkey()
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 97
  3. $user_pass . $this->padding is passed through substr(), and $user_pass is assigned
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 202
  4. Data is passed through mcrypt_encrypt()
    in vendor/includes/libraries/Pdf/Tfpdf/fpdf.php on line 20
  5. FPDF_Protection::$Ovalue is assigned
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 205
  6. Tainted property FPDF_Protection::$Ovalue is read
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 151
  7. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1467
  8. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1468
  9. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1469
  10. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1470
  11. '/O (' . $this->_escape($this->Ovalue) . ')' is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 151
  12. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  13. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1305
  2. Path: Read from $_POST, and $_POST['date'] is passed to tFPDF::Cell() in sources/views.queries.php on line 108
  1. Read from $_POST, and $_POST['date'] is passed to tFPDF::Cell()
    in sources/views.queries.php on line 108
  2. $txt is passed through str_replace(), and str_replace('\\', '\\\\', $txt) is passed through str_replace(), and str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)) is passed through str_replace(), and $txt2 is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 848
  3. $txt2 is passed through sprintf(), and $s is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 850
  4. $s is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 863
  5. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  6. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1305
  3. Path: Read from $_POST, and $_POST['text'] is escaped by addslashes() for sql, xpath context(s), and addslashes($_POST['text']) is passed through explode(), and $line is assigned in sources/views.queries.php on line 724
  1. Read from $_POST, and $_POST['text'] is escaped by addslashes() for sql, xpath context(s), and addslashes($_POST['text']) is passed through explode(), and $line is assigned
    in sources/views.queries.php on line 724
  2. $line is passed through explode(), and $elem is assigned
    in sources/views.queries.php on line 725
  3. $elem[0] is passed to tFPDF::Cell()
    in sources/views.queries.php on line 727
  4. $txt is passed through str_replace(), and str_replace('\\', '\\\\', $txt) is passed through str_replace(), and str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)) is passed through str_replace(), and $txt2 is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 848
  5. $txt2 is passed through sprintf(), and $s is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 850
  6. $s is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 863
  7. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  8. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1305

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
1306
            break;
1307
        case 'F':
1308
            // Save to local file
1309
            $f = fopen($name, 'wb');
1310
            if (!$f) {
1311
                            $this->Error('Unable to create output file: '.$name);
1312
            }
1313
            fwrite($f, $this->buffer, strlen($this->buffer));
0 ignored issues
show
Security File Manipulation introduced by
$this->buffer can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

3 paths for user data to reach this point

  1. Path: Read from $_POST, and $_POST['pdf_password'] is passed to FPDF_Protection::SetProtection() in sources/export.queries.php on line 210
  1. Read from $_POST, and $_POST['pdf_password'] is passed to FPDF_Protection::SetProtection()
    in sources/export.queries.php on line 210
  2. $user_pass is passed to FPDF_Protection::_generateencryptionkey()
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 97
  3. $user_pass . $this->padding is passed through substr(), and $user_pass is assigned
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 202
  4. Data is passed through mcrypt_encrypt()
    in vendor/includes/libraries/Pdf/Tfpdf/fpdf.php on line 20
  5. FPDF_Protection::$Ovalue is assigned
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 205
  6. Tainted property FPDF_Protection::$Ovalue is read
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 151
  7. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1467
  8. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1468
  9. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1469
  10. Data is passed through str_replace()
    in vendor/includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1470
  11. '/O (' . $this->_escape($this->Ovalue) . ')' is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/fpdf.php on line 151
  12. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  13. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1313
  2. Path: Read from $_POST, and $_POST['date'] is passed to tFPDF::Cell() in sources/views.queries.php on line 108
  1. Read from $_POST, and $_POST['date'] is passed to tFPDF::Cell()
    in sources/views.queries.php on line 108
  2. $txt is passed through str_replace(), and str_replace('\\', '\\\\', $txt) is passed through str_replace(), and str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)) is passed through str_replace(), and $txt2 is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 848
  3. $txt2 is passed through sprintf(), and $s is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 850
  4. $s is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 863
  5. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  6. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1313
  3. Path: Read from $_POST, and $_POST['text'] is escaped by addslashes() for sql, xpath context(s), and addslashes($_POST['text']) is passed through explode(), and $line is assigned in sources/views.queries.php on line 724
  1. Read from $_POST, and $_POST['text'] is escaped by addslashes() for sql, xpath context(s), and addslashes($_POST['text']) is passed through explode(), and $line is assigned
    in sources/views.queries.php on line 724
  2. $line is passed through explode(), and $elem is assigned
    in sources/views.queries.php on line 725
  3. $elem[0] is passed to tFPDF::Cell()
    in sources/views.queries.php on line 727
  4. $txt is passed through str_replace(), and str_replace('\\', '\\\\', $txt) is passed through str_replace(), and str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)) is passed through str_replace(), and $txt2 is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 848
  5. $txt2 is passed through sprintf(), and $s is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 850
  6. $s is passed to tFPDF::_out()
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 863
  7. tFPDF::$buffer is assigned
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1780
  8. Tainted property tFPDF::$buffer is read
    in includes/libraries/Pdf/Tfpdf/tfpdf.class.php on line 1313

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
1314
            fclose($f);
1315
            break;
1316
        case 'S':
1317
            // Return as a string
1318
            return $this->buffer;
1319
        default:
1320
            $this->Error('Incorrect output destination: '.$dest);
1321
    }
1322
    return '';
1323
}
1324
1325
/*******************************************************************************
1326
*                                                                              *
1327
*                              Protected methods                               *
1328
*                                                                              *
1329
*******************************************************************************/
1330
function _dochecks()
1331
{
1332
    // Check availability of %F
1333
    if (sprintf('%.1F', 1.0) != '1.0') {
1334
            $this->Error('This version of PHP is not supported');
1335
    }
1336
    // Check availability of mbstring
1337
    if (!function_exists('mb_strlen')) {
1338
            $this->Error('mbstring extension is not available');
1339
    }
1340
    // Check mbstring overloading
1341
    if (ini_get('mbstring.func_overload') & 2) {
1342
            $this->Error('mbstring overloading must be disabled');
1343
    }
1344
    // Ensure runtime magic quotes are disabled
1345
    if (get_magic_quotes_runtime()) {
1346
            @set_magic_quotes_runtime(0);
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...
1347
    }
1348
    }
1349
1350
function _getfontpath()
1351
{
1352
    return $this->fontpath;
1353
}
1354
1355
function _checkoutput()
1356
{
1357
    if (PHP_SAPI != 'cli')
1358
    {
1359
        if (headers_sent($file, $line)) {
1360
                    $this->Error("Some data has already been output, can't send PDF file (output started at $file:$line)");
1361
        }
1362
    }
1363
    if (ob_get_length())
1364
    {
1365
        // The output buffer is not empty
1366
        if (preg_match('/^(\xEF\xBB\xBF)?\s*$/', ob_get_contents()))
1367
        {
1368
            // It contains only a UTF-8 BOM and/or whitespace, let's clean it
1369
            ob_clean();
1370
        } else {
1371
                    $this->Error("Some data has already been output, can't send PDF file");
1372
        }
1373
    }
1374
}
1375
1376
/**
1377
 * @param string $size
1378
 */
1379
function _getpagesize($size)
1380
{
1381
    if (is_string($size))
1382
    {
1383
        $size = strtolower($size);
1384
        if (!isset($this->StdPageSizes[$size])) {
1385
                    $this->Error('Unknown page size: '.$size);
1386
        }
1387
        $a = $this->StdPageSizes[$size];
1388
        return array($a[0] / $this->k, $a[1] / $this->k);
1389
    } else
1390
    {
1391
        if ($size[0] > $size[1]) {
1392
                    return array($size[1], $size[0]);
1393
        } else {
1394
                    return $size;
1395
        }
1396
    }
1397
}
1398
1399
/**
1400
 * @param string $orientation
1401
 * @param string $size
1402
 */
1403
function _beginpage($orientation, $size)
1404
{
1405
    $this->page++;
1406
    $this->pages[$this->page] = '';
1407
    $this->state = 2;
1408
    $this->x = $this->lMargin;
1409
    $this->y = $this->tMargin;
1410
    $this->FontFamily = '';
1411
    // Check page size and orientation
1412
    if ($orientation == '') {
1413
            $orientation = $this->DefOrientation;
1414
    } else {
1415
            $orientation = strtoupper($orientation[0]);
1416
    }
1417
    if ($size == '') {
1418
            $size = $this->DefPageSize;
1419
    } else {
1420
            $size = $this->_getpagesize($size);
1421
    }
1422
    if ($orientation != $this->CurOrientation || $size[0] != $this->CurPageSize[0] || $size[1] != $this->CurPageSize[1])
1423
    {
1424
        // New size or orientation
1425
        if ($orientation == 'P')
1426
        {
1427
            $this->w = $size[0];
1428
            $this->h = $size[1];
1429
        } else
1430
        {
1431
            $this->w = $size[1];
1432
            $this->h = $size[0];
1433
        }
1434
        $this->wPt = $this->w * $this->k;
1435
        $this->hPt = $this->h * $this->k;
1436
        $this->PageBreakTrigger = $this->h - $this->bMargin;
1437
        $this->CurOrientation = $orientation;
1438
        $this->CurPageSize = $size;
1439
    }
1440
    if ($orientation != $this->DefOrientation || $size[0] != $this->DefPageSize[0] || $size[1] != $this->DefPageSize[1]) {
1441
            $this->PageSizes[$this->page] = array($this->wPt, $this->hPt);
1442
    }
1443
    }
1444
1445
function _endpage()
1446
{
1447
    $this->state = 1;
1448
}
1449
1450
/**
1451
 * @param string $font
1452
 */
1453
function _loadfont($font)
1454
{
1455
    // Load a font definition file from the font directory
1456
    include($this->fontpath.$font);
1457
    $a = get_defined_vars();
1458
    if (!isset($a['name'])) {
1459
            $this->Error('Could not include font definition file');
1460
    }
1461
    return $a;
1462
}
1463
1464
function _escape($s)
1465
{
1466
    // Escape special characters in strings
1467
    $s = str_replace('\\', '\\\\', $s);
1468
    $s = str_replace('(', '\\(', $s);
1469
    $s = str_replace(')', '\\)', $s);
1470
    $s = str_replace("\r", '\\r', $s);
1471
    return $s;
1472
}
1473
1474
function _textstring($s)
1475
{
1476
    // Format a text string
1477
    return '('.$this->_escape($s).')';
1478
}
1479
1480
function _UTF8toUTF16($s)
1481
{
1482
    // Convert UTF-8 to UTF-16BE with BOM
1483
    $res = "\xFE\xFF";
1484
    $nb = strlen($s);
1485
    $i = 0;
1486
    while ($i < $nb)
1487
    {
1488
        $c1 = ord($s[$i++]);
1489
        if ($c1 >= 224)
1490
        {
1491
            // 3-byte character
1492
            $c2 = ord($s[$i++]);
1493
            $c3 = ord($s[$i++]);
1494
            $res .= chr((($c1 & 0x0F) << 4) + (($c2 & 0x3C) >> 2));
1495
            $res .= chr((($c2 & 0x03) << 6) + ($c3 & 0x3F));
1496
        } elseif ($c1 >= 192)
1497
        {
1498
            // 2-byte character
1499
            $c2 = ord($s[$i++]);
1500
            $res .= chr(($c1 & 0x1C) >> 2);
1501
            $res .= chr((($c1 & 0x03) << 6) + ($c2 & 0x3F));
1502
        } else
1503
        {
1504
            // Single-byte character
1505
            $res .= "\0".chr($c1);
1506
        }
1507
    }
1508
    return $res;
1509
}
1510
1511
function _dounderline($x, $y, $txt)
1512
{
1513
    // Underline text
1514
    $up = $this->CurrentFont['up'];
1515
    $ut = $this->CurrentFont['ut'];
1516
    $w = $this->GetStringWidth($txt) + $this->ws * substr_count($txt, ' ');
1517
    return sprintf('%.2F %.2F %.2F %.2F re f', $x * $this->k, ($this->h - ($y - $up / 1000 * $this->FontSize)) * $this->k, $w * $this->k, -$ut / 1000 * $this->FontSizePt);
1518
}
1519
1520
function _parsejpg($file)
1521
{
1522
    // Extract info from a JPEG file
1523
    $a = getimagesize($file);
1524
    if (!$a) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $a 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...
1525
            $this->Error('Missing or incorrect image file: '.$file);
1526
    }
1527
    if ($a[2] != 2) {
1528
            $this->Error('Not a JPEG file: '.$file);
1529
    }
1530
    if (!isset($a['channels']) || $a['channels'] == 3) {
1531
            $colspace = 'DeviceRGB';
1532
    } elseif ($a['channels'] == 4) {
1533
            $colspace = 'DeviceCMYK';
1534
    } else {
1535
            $colspace = 'DeviceGray';
1536
    }
1537
    $bpc = isset($a['bits']) ? $a['bits'] : 8;
1538
    $data = file_get_contents($file);
1539
    return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data);
1540
}
1541
1542
/**
1543
 * @param string $file
1544
 */
1545
function _parsepng($file)
1546
{
1547
    // Extract info from a PNG file
1548
    $f = fopen($file, 'rb');
1549
    if (!$f) {
1550
            $this->Error('Can\'t open image file: '.$file);
1551
    }
1552
    $info = $this->_parsepngstream($f, $file);
1553
    fclose($f);
1554
    return $info;
1555
}
1556
1557
function _parsepngstream($f, $file)
1558
{
1559
    // Check signature
1560
    if ($this->_readstream($f, 8) != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
1561
            $this->Error('Not a PNG file: '.$file);
1562
    }
1563
1564
    // Read header chunk
1565
    $this->_readstream($f, 4);
1566
    if ($this->_readstream($f, 4) != 'IHDR') {
1567
            $this->Error('Incorrect PNG file: '.$file);
1568
    }
1569
    $w = $this->_readint($f);
1570
    $h = $this->_readint($f);
1571
    $bpc = ord($this->_readstream($f, 1));
1572
    if ($bpc > 8) {
1573
            $this->Error('16-bit depth not supported: '.$file);
1574
    }
1575
    $ct = ord($this->_readstream($f, 1));
1576
    if ($ct == 0 || $ct == 4) {
1577
            $colspace = 'DeviceGray';
1578
    } elseif ($ct == 2 || $ct == 6) {
1579
            $colspace = 'DeviceRGB';
1580
    } elseif ($ct == 3) {
1581
            $colspace = 'Indexed';
1582
    } else {
1583
            $this->Error('Unknown color type: '.$file);
1584
    }
1585
    if (ord($this->_readstream($f, 1)) != 0) {
1586
            $this->Error('Unknown compression method: '.$file);
1587
    }
1588
    if (ord($this->_readstream($f, 1)) != 0) {
1589
            $this->Error('Unknown filter method: '.$file);
1590
    }
1591
    if (ord($this->_readstream($f, 1)) != 0) {
1592
            $this->Error('Interlacing not supported: '.$file);
1593
    }
1594
    $this->_readstream($f, 4);
1595
    $dp = '/Predictor 15 /Colors '.($colspace == 'DeviceRGB' ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w;
0 ignored issues
show
Bug introduced by
The variable $colspace 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...
1596
1597
    // Scan chunks looking for palette, transparency and image data
1598
    $pal = '';
1599
    $trns = '';
1600
    $data = '';
1601
    do
1602
    {
1603
        $n = $this->_readint($f);
1604
        $type = $this->_readstream($f, 4);
1605
        if ($type == 'PLTE')
1606
        {
1607
            // Read palette
1608
            $pal = $this->_readstream($f, $n);
1609
            $this->_readstream($f, 4);
1610
        } elseif ($type == 'tRNS')
1611
        {
1612
            // Read transparency info
1613
            $t = $this->_readstream($f, $n);
1614
            if ($ct == 0) {
1615
                            $trns = array(ord(substr($t, 1, 1)));
1616
            } elseif ($ct == 2) {
1617
                            $trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1)));
1618
            } else
1619
            {
1620
                $pos = strpos($t, chr(0));
1621
                if ($pos !== false) {
1622
                                    $trns = array($pos);
1623
                }
1624
            }
1625
            $this->_readstream($f, 4);
1626
        } elseif ($type == 'IDAT')
1627
        {
1628
            // Read image data block
1629
            $data .= $this->_readstream($f, $n);
1630
            $this->_readstream($f, 4);
1631
        } elseif ($type == 'IEND') {
1632
                    break;
1633
        } else {
1634
                    $this->_readstream($f, $n + 4);
1635
        }
1636
    }
1637
    while ($n);
1638
1639
    if ($colspace == 'Indexed' && empty($pal)) {
1640
            $this->Error('Missing palette in '.$file);
1641
    }
1642
    $info = array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'dp'=>$dp, 'pal'=>$pal, 'trns'=>$trns);
1643
    if ($ct >= 4)
1644
    {
1645
        // Extract alpha channel
1646
        if (!function_exists('gzuncompress')) {
1647
                    $this->Error('Zlib not available, can\'t handle alpha channel: '.$file);
1648
        }
1649
        $data = gzuncompress($data);
1650
        $color = '';
1651
        $alpha = '';
1652
        if ($ct == 4)
1653
        {
1654
            // Gray image
1655
            $len = 2 * $w;
1656 View Code Duplication
            for ($i = 0; $i < $h; $i++)
1657
            {
1658
                $pos = (1 + $len) * $i;
1659
                $color .= $data[$pos];
1660
                $alpha .= $data[$pos];
1661
                $line = substr($data, $pos + 1, $len);
1662
                $color .= preg_replace('/(.)./s', '$1', $line);
1663
                $alpha .= preg_replace('/.(.)/s', '$1', $line);
1664
            }
1665
        } else
1666
        {
1667
            // RGB image
1668
            $len = 4 * $w;
1669 View Code Duplication
            for ($i = 0; $i < $h; $i++)
1670
            {
1671
                $pos = (1 + $len) * $i;
1672
                $color .= $data[$pos];
1673
                $alpha .= $data[$pos];
1674
                $line = substr($data, $pos + 1, $len);
1675
                $color .= preg_replace('/(.{3})./s', '$1', $line);
1676
                $alpha .= preg_replace('/.{3}(.)/s', '$1', $line);
1677
            }
1678
        }
1679
        unset($data);
1680
        $data = gzcompress($color);
1681
        $info['smask'] = gzcompress($alpha);
1682
        if ($this->PDFVersion < '1.4') {
1683
                    $this->PDFVersion = '1.4';
1684
        }
1685
    }
1686
    $info['data'] = $data;
1687
    return $info;
1688
}
1689
1690
function _readstream($f, $n)
1691
{
1692
    // Read n bytes from stream
1693
    $res = '';
1694
    while ($n > 0 && !feof($f))
1695
    {
1696
        $s = fread($f, $n);
1697
        if ($s === false) {
1698
                    $this->Error('Error while reading stream');
1699
        }
1700
        $n -= strlen($s);
1701
        $res .= $s;
1702
    }
1703
    if ($n > 0) {
1704
            $this->Error('Unexpected end of stream');
1705
    }
1706
    return $res;
1707
}
1708
1709
function _readint($f)
1710
{
1711
    // Read a 4-byte integer from stream
1712
    $a = unpack('Ni', $this->_readstream($f, 4));
1713
    return $a['i'];
1714
}
1715
1716
function _parsegif($file)
1717
{
1718
    // Extract info from a GIF file (via PNG conversion)
1719
    if (!function_exists('imagepng')) {
1720
            $this->Error('GD extension is required for GIF support');
1721
    }
1722
    if (!function_exists('imagecreatefromgif')) {
1723
            $this->Error('GD has no GIF read support');
1724
    }
1725
    $im = imagecreatefromgif($file);
1726
    if (!$im) {
1727
            $this->Error('Missing or incorrect image file: '.$file);
1728
    }
1729
    imageinterlace($im, 0);
1730
    $f = @fopen('php://temp', 'rb+');
1731
    if ($f)
1732
    {
1733
        // Perform conversion in memory
1734
        ob_start();
1735
        imagepng($im);
1736
        $data = ob_get_clean();
1737
        imagedestroy($im);
1738
        fwrite($f, $data);
1739
        rewind($f);
1740
        $info = $this->_parsepngstream($f, $file);
1741
        fclose($f);
1742
    } else
1743
    {
1744
        // Use temporary file
1745
        $tmp = tempnam('.', 'gif');
1746
        if (!$tmp) {
1747
                    $this->Error('Unable to create a temporary file');
1748
        }
1749
        if (!imagepng($im, $tmp)) {
1750
                    $this->Error('Error while saving to temporary file');
1751
        }
1752
        imagedestroy($im);
1753
        $info = $this->_parsepng($tmp);
1754
        unlink($tmp);
1755
    }
1756
    return $info;
1757
}
1758
1759
function _newobj()
1760
{
1761
    // Begin a new object
1762
    $this->n++;
1763
    $this->offsets[$this->n] = strlen($this->buffer);
1764
    $this->_out($this->n.' 0 obj');
1765
}
1766
1767
function _putstream($s)
1768
{
1769
    $this->_out('stream');
1770
    $this->_out($s);
1771
    $this->_out('endstream');
1772
}
1773
1774
function _out($s)
1775
{
1776
    // Add a line to the document
1777
    if ($this->state == 2) {
1778
            $this->pages[$this->page] .= $s."\n";
1779
    } else {
1780
            $this->buffer .= $s."\n";
1781
    }
1782
    }
1783
1784
function _putpages()
1785
{
1786
    $nb = $this->page;
1787
    if (!empty($this->AliasNbPages))
1788
    {
1789
        // Replace number of pages in fonts using subsets
1790
        $alias = $this->UTF8ToUTF16BE($this->AliasNbPages, false);
1791
        $r = $this->UTF8ToUTF16BE("$nb", false);
1792 View Code Duplication
        for ($n = 1; $n <= $nb; $n++) {
1793
                    $this->pages[$n] = str_replace($alias, $r, $this->pages[$n]);
1794
        }
1795
        // Now repeat for no pages in non-subset fonts
1796 View Code Duplication
        for ($n = 1; $n <= $nb; $n++) {
1797
                    $this->pages[$n] = str_replace($this->AliasNbPages, $nb, $this->pages[$n]);
1798
        }
1799
    }
1800
    if ($this->DefOrientation == 'P')
1801
    {
1802
        $wPt = $this->DefPageSize[0] * $this->k;
1803
        $hPt = $this->DefPageSize[1] * $this->k;
1804
    } else
1805
    {
1806
        $wPt = $this->DefPageSize[1] * $this->k;
1807
        $hPt = $this->DefPageSize[0] * $this->k;
1808
    }
1809
    $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
1810
    for ($n = 1; $n <= $nb; $n++)
1811
    {
1812
        // Page
1813
        $this->_newobj();
1814
        $this->_out('<</Type /Page');
1815
        $this->_out('/Parent 1 0 R');
1816
        if (isset($this->PageSizes[$n])) {
1817
                    $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]', $this->PageSizes[$n][0], $this->PageSizes[$n][1]));
1818
        }
1819
        $this->_out('/Resources 2 0 R');
1820
        if (isset($this->PageLinks[$n]))
1821
        {
1822
            // Links
1823
            $annots = '/Annots [';
1824
            foreach ($this->PageLinks[$n] as $pl)
1825
            {
1826
                $rect = sprintf('%.2F %.2F %.2F %.2F', $pl[0], $pl[1], $pl[0] + $pl[2], $pl[1] - $pl[3]);
1827
                $annots .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
1828
                if (is_string($pl[4])) {
1829
                                    $annots .= '/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
1830
                } else
1831
                {
1832
                    $l = $this->links[$pl[4]];
1833
                    $h = isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt;
1834
                    $annots .= sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>', 1 + 2 * $l[0], $h - $l[1] * $this->k);
1835
                }
1836
            }
1837
            $this->_out($annots.']');
1838
        }
1839
        if ($this->PDFVersion > '1.3') {
1840
                    $this->_out('/Group <</Type /Group /S /Transparency /CS /DeviceRGB>>');
1841
        }
1842
        $this->_out('/Contents '.($this->n + 1).' 0 R>>');
1843
        $this->_out('endobj');
1844
        // Page content
1845
        $p = ($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
1846
        $this->_newobj();
1847
        $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
1848
        $this->_putstream($p);
1849
        $this->_out('endobj');
1850
    }
1851
    // Pages root
1852
    $this->offsets[1] = strlen($this->buffer);
1853
    $this->_out('1 0 obj');
1854
    $this->_out('<</Type /Pages');
1855
    $kids = '/Kids [';
1856
    for ($i = 0; $i < $nb; $i++) {
1857
            $kids .= (3 + 2 * $i).' 0 R ';
1858
    }
1859
    $this->_out($kids.']');
1860
    $this->_out('/Count '.$nb);
1861
    $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]', $wPt, $hPt));
1862
    $this->_out('>>');
1863
    $this->_out('endobj');
1864
}
1865
1866
function _putfonts()
1867
{
1868
    $nf = $this->n;
1869
    foreach ($this->diffs as $diff)
1870
    {
1871
        // Encodings
1872
        $this->_newobj();
1873
        $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
1874
        $this->_out('endobj');
1875
    }
1876
    foreach ($this->FontFiles as $file=>$info)
1877
    {
1878
        if (!isset($info['type']) || $info['type'] != 'TTF') {
1879
        // Font file embedding
1880
        $this->_newobj();
1881
        $this->FontFiles[$file]['n'] = $this->n;
1882
        $font = '';
1883
        $f = fopen($this->_getfontpath().$file, 'rb', 1);
1884
        if (!$f) {
1885
                    $this->Error('Font file not found');
1886
        }
1887
        while (!feof($f)) {
1888
                    $font .= fread($f, 8192);
1889
        }
1890
        fclose($f);
1891
        $compressed = (substr($file, -2) == '.z');
1892
        if (!$compressed && isset($info['length2']))
1893
        {
1894
            $header = (ord($font[0]) == 128);
1895
            if ($header)
1896
            {
1897
                // Strip first binary header
1898
                $font = substr($font, 6);
1899
            }
1900
            if ($header && ord($font[$info['length1']]) == 128)
1901
            {
1902
                // Strip second binary header
1903
                $font = substr($font, 0, $info['length1']).substr($font, $info['length1'] + 6);
1904
            }
1905
        }
1906
        $this->_out('<</Length '.strlen($font));
1907
        if ($compressed) {
1908
                    $this->_out('/Filter /FlateDecode');
1909
        }
1910
        $this->_out('/Length1 '.$info['length1']);
1911
        if (isset($info['length2'])) {
1912
                    $this->_out('/Length2 '.$info['length2'].' /Length3 0');
1913
        }
1914
        $this->_out('>>');
1915
        $this->_putstream($font);
1916
        $this->_out('endobj');
1917
        }
1918
    }
1919
    foreach ($this->fonts as $k=>$font)
1920
    {
1921
        // Font objects
1922
        //$this->fonts[$k]['n']=$this->n+1;
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1923
        $type = $font['type'];
1924
        $name = $font['name'];
1925
        if ($type == 'Core')
1926
        {
1927
            // Standard font
1928
            $this->fonts[$k]['n'] = $this->n + 1;
1929
            $this->_newobj();
1930
            $this->_out('<</Type /Font');
1931
            $this->_out('/BaseFont /'.$name);
1932
            $this->_out('/Subtype /Type1');
1933
            if ($name != 'Symbol' && $name != 'ZapfDingbats') {
1934
                            $this->_out('/Encoding /WinAnsiEncoding');
1935
            }
1936
            $this->_out('>>');
1937
            $this->_out('endobj');
1938
        } elseif ($type == 'Type1' || $type == 'TrueType')
1939
        {
1940
            // Additional Type1 or TrueType font
1941
            $this->fonts[$k]['n'] = $this->n + 1;
1942
            $this->_newobj();
1943
            $this->_out('<</Type /Font');
1944
            $this->_out('/BaseFont /'.$name);
1945
            $this->_out('/Subtype /'.$type);
1946
            $this->_out('/FirstChar 32 /LastChar 255');
1947
            $this->_out('/Widths '.($this->n + 1).' 0 R');
1948
            $this->_out('/FontDescriptor '.($this->n + 2).' 0 R');
1949
            if ($font['enc'])
1950
            {
1951
                if (isset($font['diff'])) {
1952
                                    $this->_out('/Encoding '.($nf + $font['diff']).' 0 R');
1953
                } else {
1954
                                    $this->_out('/Encoding /WinAnsiEncoding');
1955
                }
1956
            }
1957
            $this->_out('>>');
1958
            $this->_out('endobj');
1959
            // Widths
1960
            $this->_newobj();
1961
            $cw = &$font['cw'];
1962
            $s = '[';
1963 View Code Duplication
            for ($i = 32; $i <= 255; $i++) {
1964
                            $s .= $cw[chr($i)].' ';
1965
            }
1966
            $this->_out($s.']');
1967
            $this->_out('endobj');
1968
            // Descriptor
1969
            $this->_newobj();
1970
            $s = '<</Type /FontDescriptor /FontName /'.$name;
1971
            foreach ($font['desc'] as $k=>$v) {
1972
                            $s .= ' /'.$k.' '.$v;
1973
            }
1974
            $file = $font['file'];
1975
            if ($file) {
1976
                            $s .= ' /FontFile'.($type == 'Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
1977
            }
1978
            $this->_out($s.'>>');
1979
            $this->_out('endobj');
1980
        }
1981
        // TrueType embedded SUBSETS or FULL
1982
        else if ($type == 'TTF') {
1983
            $this->fonts[$k]['n'] = $this->n + 1;
1984
            require_once($this->_getfontpath().'unifont/ttfonts.php');
1985
            $ttf = new TTFontFile();
1986
            $fontname = 'MPDFAA'.'+'.$font['name'];
1987
            $subset = $font['subset'];
1988
            unset($subset[0]);
1989
            $ttfontstream = $ttf->makeSubset($font['ttffile'], $subset);
1990
            $ttfontsize = strlen($ttfontstream);
1991
            $fontstream = gzcompress($ttfontstream);
1992
            $codeToGlyph = $ttf->codeToGlyph;
1993
            unset($codeToGlyph[0]);
1994
1995
            // Type0 Font
1996
            // A composite font - a font composed of other fonts, organized hierarchically
1997
            $this->_newobj();
1998
            $this->_out('<</Type /Font');
1999
            $this->_out('/Subtype /Type0');
2000
            $this->_out('/BaseFont /'.$fontname.'');
2001
            $this->_out('/Encoding /Identity-H');
2002
            $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
2003
            $this->_out('/ToUnicode '.($this->n + 2).' 0 R');
2004
            $this->_out('>>');
2005
            $this->_out('endobj');
2006
2007
            // CIDFontType2
2008
            // A CIDFont whose glyph descriptions are based on TrueType font technology
2009
            $this->_newobj();
2010
            $this->_out('<</Type /Font');
2011
            $this->_out('/Subtype /CIDFontType2');
2012
            $this->_out('/BaseFont /'.$fontname.'');
2013
            $this->_out('/CIDSystemInfo '.($this->n + 2).' 0 R');
2014
            $this->_out('/FontDescriptor '.($this->n + 3).' 0 R');
2015
            if (isset($font['desc']['MissingWidth'])) {
2016
                $this->_out('/DW '.$font['desc']['MissingWidth'].'');
2017
            }
2018
2019
            $this->_putTTfontwidths($font, $ttf->maxUni);
2020
2021
            $this->_out('/CIDToGIDMap '.($this->n + 4).' 0 R');
2022
            $this->_out('>>');
2023
            $this->_out('endobj');
2024
2025
            // ToUnicode
2026
            $this->_newobj();
2027
            $toUni = "/CIDInit /ProcSet findresource begin\n";
2028
            $toUni .= "12 dict begin\n";
2029
            $toUni .= "begincmap\n";
2030
            $toUni .= "/CIDSystemInfo\n";
2031
            $toUni .= "<</Registry (Adobe)\n";
2032
            $toUni .= "/Ordering (UCS)\n";
2033
            $toUni .= "/Supplement 0\n";
2034
            $toUni .= ">> def\n";
2035
            $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
2036
            $toUni .= "/CMapType 2 def\n";
2037
            $toUni .= "1 begincodespacerange\n";
2038
            $toUni .= "<0000> <FFFF>\n";
2039
            $toUni .= "endcodespacerange\n";
2040
            $toUni .= "1 beginbfrange\n";
2041
            $toUni .= "<0000> <FFFF> <0000>\n";
2042
            $toUni .= "endbfrange\n";
2043
            $toUni .= "endcmap\n";
2044
            $toUni .= "CMapName currentdict /CMap defineresource pop\n";
2045
            $toUni .= "end\n";
2046
            $toUni .= "end";
2047
            $this->_out('<</Length '.(strlen($toUni)).'>>');
2048
            $this->_putstream($toUni);
2049
            $this->_out('endobj');
2050
2051
            // CIDSystemInfo dictionary
2052
            $this->_newobj();
2053
            $this->_out('<</Registry (Adobe)');
2054
            $this->_out('/Ordering (UCS)');
2055
            $this->_out('/Supplement 0');
2056
            $this->_out('>>');
2057
            $this->_out('endobj');
2058
2059
            // Font descriptor
2060
            $this->_newobj();
2061
            $this->_out('<</Type /FontDescriptor');
2062
            $this->_out('/FontName /'.$fontname);
2063
            foreach ($font['desc'] as $kd=>$v) {
2064
                if ($kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
2065
                $this->_out(' /'.$kd.' '.$v);
2066
            }
2067
            $this->_out('/FontFile2 '.($this->n + 2).' 0 R');
2068
            $this->_out('>>');
2069
            $this->_out('endobj');
2070
2071
            // Embed CIDToGIDMap
2072
            // A specification of the mapping from CIDs to glyph indices
2073
            $cidtogidmap = '';
0 ignored issues
show
Unused Code introduced by
$cidtogidmap 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...
2074
            $cidtogidmap = str_pad('', 256 * 256 * 2, "\x00");
2075
            foreach ($codeToGlyph as $cc=>$glyph) {
2076
                $cidtogidmap[$cc * 2] = chr($glyph >> 8);
2077
                $cidtogidmap[$cc * 2 + 1] = chr($glyph & 0xFF);
2078
            }
2079
            $cidtogidmap = gzcompress($cidtogidmap);
2080
            $this->_newobj();
2081
            $this->_out('<</Length '.strlen($cidtogidmap).'');
2082
            $this->_out('/Filter /FlateDecode');
2083
            $this->_out('>>');
2084
            $this->_putstream($cidtogidmap);
2085
            $this->_out('endobj');
2086
2087
            //Font file
2088
            $this->_newobj();
2089
            $this->_out('<</Length '.strlen($fontstream));
2090
            $this->_out('/Filter /FlateDecode');
2091
            $this->_out('/Length1 '.$ttfontsize);
2092
            $this->_out('>>');
2093
            $this->_putstream($fontstream);
2094
            $this->_out('endobj');
2095
            unset($ttf);
2096
        } else
2097
        {
2098
            // Allow for additional types
2099
            $this->fonts[$k]['n'] = $this->n + 1;
2100
            $mtd = '_put'.strtolower($type);
2101
            if (!method_exists($this, $mtd)) {
2102
                            $this->Error('Unsupported font type: '.$type);
2103
            }
2104
            $this->$mtd($font);
2105
        }
2106
    }
2107
}
2108
2109
/**
2110
 * @param integer $maxUni
2111
 */
2112
function _putTTfontwidths(&$font, $maxUni) {
2113
    if (file_exists($font['unifilename'].'.cw127.php')) {
2114
        include($font['unifilename'].'.cw127.php');
2115
        $startcid = 128;
2116
    } else {
2117
        $rangeid = 0;
2118
        $range = array();
2119
        $prevcid = -2;
2120
        $prevwidth = -1;
2121
        $interval = false;
2122
        $startcid = 1;
2123
    }
2124
    $cwlen = $maxUni + 1;
2125
2126
    // for each character
2127
    for ($cid = $startcid; $cid < $cwlen; $cid++) {
2128
        if ($cid == 128 && (!file_exists($font['unifilename'].'.cw127.php'))) {
2129
            if (is_writable(dirname($this->_getfontpath().'unifont/x'))) {
2130
                $fh = fopen($font['unifilename'].'.cw127.php', "wb");
2131
                $cw127 = '<?php'."\n";
2132
                $cw127 .= '$rangeid='.$rangeid.";\n";
0 ignored issues
show
Bug introduced by
The variable $rangeid 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...
2133
                $cw127 .= '$prevcid='.$prevcid.";\n";
0 ignored issues
show
Bug introduced by
The variable $prevcid 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...
2134
                $cw127 .= '$prevwidth='.$prevwidth.";\n";
0 ignored issues
show
Bug introduced by
The variable $prevwidth 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...
2135
                if ($interval) { $cw127 .= '$interval=true'.";\n"; } else { $cw127 .= '$interval=false'.";\n"; }
0 ignored issues
show
Bug introduced by
The variable $interval 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...
2136
                $cw127 .= '$range='.var_export($range, true).";\n";
0 ignored issues
show
Bug introduced by
The variable $range 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...
2137
                $cw127 .= "?>";
2138
                fwrite($fh, $cw127, strlen($cw127));
2139
                fclose($fh);
2140
            }
2141
        }
2142
        if ($font['cw'][$cid * 2] == "\00" && $font['cw'][$cid * 2 + 1] == "\00") { continue; }
2143
        $width = (ord($font['cw'][$cid * 2]) << 8) + ord($font['cw'][$cid * 2 + 1]);
2144
        if ($width == 65535) { $width = 0; }
2145
        if ($cid > 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) { continue; }
2146
        if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
2147
            if ($cid == ($prevcid + 1)) {
2148
                if ($width == $prevwidth) {
2149
                    if ($width == $range[$rangeid][0]) {
2150
                        $range[$rangeid][] = $width;
2151 View Code Duplication
                    } else {
2152
                        array_pop($range[$rangeid]);
2153
                        // new range
2154
                        $rangeid = $prevcid;
2155
                        $range[$rangeid] = array();
2156
                        $range[$rangeid][] = $prevwidth;
2157
                        $range[$rangeid][] = $width;
2158
                    }
2159
                    $interval = true;
2160
                    $range[$rangeid]['interval'] = true;
2161 View Code Duplication
                } else {
2162
                    if ($interval) {
2163
                        // new range
2164
                        $rangeid = $cid;
2165
                        $range[$rangeid] = array();
2166
                        $range[$rangeid][] = $width;
2167
                    } else { $range[$rangeid][] = $width; }
2168
                    $interval = false;
2169
                }
2170
            } else {
2171
                $rangeid = $cid;
2172
                $range[$rangeid] = array();
2173
                $range[$rangeid][] = $width;
2174
                $interval = false;
2175
            }
2176
            $prevcid = $cid;
2177
            $prevwidth = $width;
2178
        }
2179
    }
2180
    $prevk = -1;
2181
    $nextk = -1;
2182
    $prevint = false;
2183
    foreach ($range as $k => $ws) {
2184
        $cws = count($ws);
2185
        if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
2186
            if (isset($range[$k]['interval'])) { unset($range[$k]['interval']); }
2187
            $range[$prevk] = array_merge($range[$prevk], $range[$k]);
2188
            unset($range[$k]);
2189
        } else { $prevk = $k; }
2190
        $nextk = $k + $cws;
2191
        if (isset($ws['interval'])) {
2192
            if ($cws > 3) { $prevint = true; } else { $prevint = false; }
2193
            unset($range[$k]['interval']);
2194
            --$nextk;
2195
        } else { $prevint = false; }
2196
    }
2197
    $w = '';
2198
    foreach ($range as $k => $ws) {
2199
        if (count(array_count_values($ws)) == 1) { $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0]; } else { $w .= ' '.$k.' [ '.implode(' ', $ws).' ]'."\n"; }
2200
    }
2201
    $this->_out('/W ['.$w.' ]');
2202
}
2203
2204
function _putimages()
2205
{
2206
    foreach (array_keys($this->images) as $file)
2207
    {
2208
        $this->_putimage($this->images[$file]);
2209
        unset($this->images[$file]['data']);
2210
        unset($this->images[$file]['smask']);
2211
    }
2212
}
2213
2214
function _putimage(&$info)
2215
{
2216
    $this->_newobj();
2217
    $info['n'] = $this->n;
2218
    $this->_out('<</Type /XObject');
2219
    $this->_out('/Subtype /Image');
2220
    $this->_out('/Width '.$info['w']);
2221
    $this->_out('/Height '.$info['h']);
2222
    if ($info['cs'] == 'Indexed') {
2223
            $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal']) / 3 - 1).' '.($this->n + 1).' 0 R]');
2224
    } else
2225
    {
2226
        $this->_out('/ColorSpace /'.$info['cs']);
2227
        if ($info['cs'] == 'DeviceCMYK') {
2228
                    $this->_out('/Decode [1 0 1 0 1 0 1 0]');
2229
        }
2230
    }
2231
    $this->_out('/BitsPerComponent '.$info['bpc']);
2232
    if (isset($info['f'])) {
2233
            $this->_out('/Filter /'.$info['f']);
2234
    }
2235
    if (isset($info['dp'])) {
2236
            $this->_out('/DecodeParms <<'.$info['dp'].'>>');
2237
    }
2238
    if (isset($info['trns']) && is_array($info['trns']))
2239
    {
2240
        $trns = '';
2241
        for ($i = 0; $i < count($info['trns']); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
2242
                    $trns .= $info['trns'][$i].' '.$info['trns'][$i].' ';
2243
        }
2244
        $this->_out('/Mask ['.$trns.']');
2245
    }
2246
    if (isset($info['smask'])) {
2247
            $this->_out('/SMask '.($this->n + 1).' 0 R');
2248
    }
2249
    $this->_out('/Length '.strlen($info['data']).'>>');
2250
    $this->_putstream($info['data']);
2251
    $this->_out('endobj');
2252
    // Soft mask
2253
    if (isset($info['smask']))
2254
    {
2255
        $dp = '/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns '.$info['w'];
2256
        $smask = array('w'=>$info['w'], 'h'=>$info['h'], 'cs'=>'DeviceGray', 'bpc'=>8, 'f'=>$info['f'], 'dp'=>$dp, 'data'=>$info['smask']);
2257
        $this->_putimage($smask);
2258
    }
2259
    // Palette
2260
    if ($info['cs'] == 'Indexed')
2261
    {
2262
        $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
2263
        $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal'];
2264
        $this->_newobj();
2265
        $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
2266
        $this->_putstream($pal);
2267
        $this->_out('endobj');
2268
    }
2269
}
2270
2271
function _putxobjectdict()
2272
{
2273
    foreach ($this->images as $image) {
2274
            $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
2275
    }
2276
    }
2277
2278
function _putresourcedict()
2279
{
2280
    $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
2281
    $this->_out('/Font <<');
2282
    foreach ($this->fonts as $font) {
2283
        $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
2284
    }
2285
    $this->_out('>>');
2286
    $this->_out('/XObject <<');
2287
    $this->_putxobjectdict();
2288
    $this->_out('>>');
2289
}
2290
2291
function _putresources()
2292
{
2293
    $this->_putfonts();
2294
    $this->_putimages();
2295
    // Resource dictionary
2296
    $this->offsets[2] = strlen($this->buffer);
2297
    $this->_out('2 0 obj');
2298
    $this->_out('<<');
2299
    $this->_putresourcedict();
2300
    $this->_out('>>');
2301
    $this->_out('endobj');
2302
}
2303
2304
function _putinfo()
2305
{
2306
    $this->_out('/Producer '.$this->_textstring('tFPDF '.tFPDF_VERSION));
2307
    if (!empty($this->title)) {
2308
            $this->_out('/Title '.$this->_textstring($this->title));
2309
    }
2310
    if (!empty($this->subject)) {
2311
            $this->_out('/Subject '.$this->_textstring($this->subject));
2312
    }
2313
    if (!empty($this->author)) {
2314
            $this->_out('/Author '.$this->_textstring($this->author));
2315
    }
2316
    if (!empty($this->keywords)) {
2317
            $this->_out('/Keywords '.$this->_textstring($this->keywords));
2318
    }
2319
    if (!empty($this->creator)) {
2320
            $this->_out('/Creator '.$this->_textstring($this->creator));
2321
    }
2322
    $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis')));
2323
}
2324
2325
function _putcatalog()
2326
{
2327
    $this->_out('/Type /Catalog');
2328
    $this->_out('/Pages 1 0 R');
2329
    if ($this->ZoomMode == 'fullpage') {
2330
            $this->_out('/OpenAction [3 0 R /Fit]');
2331
    } elseif ($this->ZoomMode == 'fullwidth') {
2332
            $this->_out('/OpenAction [3 0 R /FitH null]');
2333
    } elseif ($this->ZoomMode == 'real') {
2334
            $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
2335
    } elseif (!is_string($this->ZoomMode)) {
2336
            $this->_out('/OpenAction [3 0 R /XYZ null null '.sprintf('%.2F', $this->ZoomMode / 100).']');
2337
    }
2338
    if ($this->LayoutMode == 'single') {
2339
            $this->_out('/PageLayout /SinglePage');
2340
    } elseif ($this->LayoutMode == 'continuous') {
2341
            $this->_out('/PageLayout /OneColumn');
2342
    } elseif ($this->LayoutMode == 'two') {
2343
            $this->_out('/PageLayout /TwoColumnLeft');
2344
    }
2345
    }
2346
2347
function _putheader()
2348
{
2349
    $this->_out('%PDF-'.$this->PDFVersion);
2350
}
2351
2352
function _puttrailer()
2353
{
2354
    $this->_out('/Size '.($this->n + 1));
2355
    $this->_out('/Root '.$this->n.' 0 R');
2356
    $this->_out('/Info '.($this->n - 1).' 0 R');
2357
}
2358
2359
function _enddoc()
2360
{
2361
    $this->_putheader();
2362
    $this->_putpages();
2363
    $this->_putresources();
2364
    // Info
2365
    $this->_newobj();
2366
    $this->_out('<<');
2367
    $this->_putinfo();
2368
    $this->_out('>>');
2369
    $this->_out('endobj');
2370
    // Catalog
2371
    $this->_newobj();
2372
    $this->_out('<<');
2373
    $this->_putcatalog();
2374
    $this->_out('>>');
2375
    $this->_out('endobj');
2376
    // Cross-ref
2377
    $o = strlen($this->buffer);
2378
    $this->_out('xref');
2379
    $this->_out('0 '.($this->n + 1));
2380
    $this->_out('0000000000 65535 f ');
2381
    for ($i = 1; $i <= $this->n; $i++) {
2382
            $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
2383
    }
2384
    // Trailer
2385
    $this->_out('trailer');
2386
    $this->_out('<<');
2387
    $this->_puttrailer();
2388
    $this->_out('>>');
2389
    $this->_out('startxref');
2390
    $this->_out($o);
2391
    $this->_out('%%EOF');
2392
    $this->state = 3;
2393
}
2394
2395
// ********* NEW FUNCTIONS *********
2396
// Converts UTF-8 strings to UTF16-BE.
2397
function UTF8ToUTF16BE($str, $setbom = true) {
2398
    $outstr = "";
2399
    if ($setbom) {
2400
        $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
2401
    }
2402
    $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8');
2403
    return $outstr;
2404
}
2405
2406
// Converts UTF-8 strings to codepoints array
2407
function UTF8StringToArray($str) {
2408
    $out = array();
2409
    $len = strlen($str);
2410
    for ($i = 0; $i < $len; $i++) {
2411
    $uni = -1;
2412
        $h = ord($str[$i]);
2413
        if ($h <= 0x7F)
2414
            $uni = $h;
2415
        elseif ($h >= 0xC2) {
2416
            if (($h <= 0xDF) && ($i < $len - 1))
2417
            $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F);
2418
            elseif (($h <= 0xEF) && ($i < $len - 2))
2419
            $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6
2420
                                        | (ord($str[++$i]) & 0x3F);
2421
            elseif (($h <= 0xF4) && ($i < $len - 3))
2422
            $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12
2423
                                        | (ord($str[++$i]) & 0x3F) << 6
2424
                                        | (ord($str[++$i]) & 0x3F);
2425
        }
2426
    if ($uni >= 0) {
2427
        $out[] = $uni;
2428
    }
2429
    }
2430
    return $out;
2431
}
2432
2433
2434
// End of class
2435
}
2436
2437
// Handle special IE contype request
2438
if (isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] == 'contype')
2439
{
2440
    header('Content-Type: application/pdf');
2441
    exit;
2442
}