Passed
Push — master ( b3b7d5...a3dae3 )
by Richard
06:43 queued 11s
created

htdocs/class/captcha/image/scripts/image.php (11 issues)

1
<?php
2
/**
3
 * CAPTCHA class For XOOPS
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13
 * @license             GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
14
 * @since               2.3.0
15
 * @author              Taiwen Jiang <[email protected]>
16
 * @package             class
17
 * @subpackage          CAPTCHA
18
 */
19
20
include __DIR__  . '/../../../../mainfile.php';
21
22
error_reporting(0);
23
$xoopsLogger->activated = false;
24
25
/*
26
if (empty($_SERVER['HTTP_REFERER']) || !preg_match("/^" . preg_quote(XOOPS_URL, '/') . "/", $_SERVER['HTTP_REFERER'])) {
27
    exit();
28
}
29
*/
30
31
/**
32
 * Class XoopsCaptchaImageHandler
33
 */
34
class XoopsCaptchaImageHandler
35
{
36
    public $config  = array();
37
    public $code;
38
    public $mode    = 'gd';
39
    public $invalid = false;
40
41
    public $oImage;
42
    public $font;
43
    public $spacing;
44
    public $width;
45
    public $height;
46
47
    public $captchaHandler;
48
49
    /**
50
     *
51
     */
52
    public function __construct()
53
    {
54
        xoops_load('XoopsCaptcha');
55
        $this->captchaHandler = XoopsCaptcha::getInstance();
56
        $this->config          = $this->captchaHandler->loadConfig('image');
57
    }
58
59
    public function loadImage()
60
    {
61
        $this->generateCode();
62
        $this->createImage();
63
    }
64
65
    /**
66
     * Create Code
67
     */
68
    public function generateCode()
69
    {
70
        if ($this->invalid) {
71
            return false;
72
        }
73
74
        if ($this->mode === 'bmp') {
75
            $this->config['num_chars'] = 4;
76
            $this->code                = mt_rand(pow(10, $this->config['num_chars'] - 1), (int)str_pad('9', $this->config['num_chars'], '9'));
77
        } else {
78
            $raw_code = md5(uniqid(mt_rand(), 1));
79
            if (!empty($this->config['skip_characters'])) {
80
                $valid_code = str_replace($this->config['skip_characters'], '', $raw_code);
81
                $this->code = substr($valid_code, 0, $this->config['num_chars']);
82
            } else {
83
                $this->code = substr($raw_code, 0, $this->config['num_chars']);
84
            }
85
            if (!$this->config['casesensitive']) {
86
                $this->code = strtoupper($this->code);
87
            }
88
        }
89
        $this->captchaHandler->setCode($this->code);
90
91
        return true;
92
    }
93
94
    /**
95
     * @return string|void
96
     */
97
    public function createImage()
98
    {
99
        if ($this->invalid) {
100
            header('Content-type: image/gif');
101
            readfile(XOOPS_ROOT_PATH . '/images/subject/icon2.gif');
102
103
            return null;
104
        }
105
106
        if ($this->mode === 'bmp') {
107
            return $this->createImageBmp();
108
        } else {
109
            return $this->createImageGd();
110
        }
111
    }
112
113
    /**
114
     * @param string $name
115
     * @param string $extension
116
     *
117
     * @return array|mixed
118
     */
119
    public function getList($name, $extension = '')
120
    {
121
        $items = array();
122
        xoops_load('XoopsCache');
123
        if ($items = XoopsCache::read("captcha_captcha_{$name}")) {
124
            return $items;
125
        }
126
127
        require_once XOOPS_ROOT_PATH . '/class/xoopslists.php';
128
        $file_path = XOOPS_ROOT_PATH . "/class/captcha/image/{$name}";
129
        $files     = XoopsLists::getFileListAsArray($file_path);
130
        foreach ($files as $item) {
131
            if (empty($extension) || preg_match("/(\.{$extension})$/i", $item)) {
132
                $items[] = $item;
133
            }
134
        }
135
        XoopsCache::write("captcha_captcha_{$name}", $items);
136
137
        return $items;
138
    }
139
140
    /**#@+
141
     *  Create CAPTCHA iamge with GD
142
     *  Originated by DuGris' SecurityImage
143
     */
144
    //  --------------------------------------------------------------------------- //
145
    // Class : SecurityImage 1.5                                                    //
146
    // Author: DuGris aka L. Jen <http://www.dugris.info>                            //
147
    // Email : [email protected]                                                    //
148
    // Licence: GNU                                                                    //
149
    // Project: The XOOPS Project                                                    //
150
    //  --------------------------------------------------------------------------- //
151
    public function createImageGd()
152
    {
153
        $this->loadFont();
154
        $this->setImageSize();
155
156
        $this->oImage = imagecreatetruecolor($this->width, $this->height);
157
        $background   = imagecolorallocate($this->oImage, 255, 255, 255);
0 ignored issues
show
It seems like $this->oImage can also be of type false; however, parameter $image of imagecolorallocate() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

157
        $background   = imagecolorallocate(/** @scrutinizer ignore-type */ $this->oImage, 255, 255, 255);
Loading history...
158
        imagefilledrectangle($this->oImage, 0, 0, $this->width, $this->height, $background);
159
160
        switch ($this->config['background_type']) {
161
            default:
162
            case 0:
163
                $this->drawBars();
164
                break;
165
166
            case 1:
167
                $this->drawCircles();
168
                break;
169
170
            case 2:
171
                $this->drawLines();
172
                break;
173
174
            case 3:
175
                $this->drawRectangles();
176
                break;
177
178
            case 4:
179
                $this->drawEllipses();
180
                break;
181
182
            case 5:
183
                $this->drawPolygons();
184
                break;
185
186
            case 100:
187
                $this->createFromFile();
188
                break;
189
        }
190
        $this->drawBorder();
191
        $this->drawCode();
192
193
        header('Content-type: image/jpeg');
194
        imagejpeg($this->oImage);
0 ignored issues
show
It seems like $this->oImage can also be of type false; however, parameter $image of imagejpeg() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

194
        imagejpeg(/** @scrutinizer ignore-type */ $this->oImage);
Loading history...
195
        imagedestroy($this->oImage);
196
    }
197
198
    public function loadFont()
199
    {
200
        $fonts      = $this->getList('fonts', 'ttf');
201
        $this->font = XOOPS_ROOT_PATH . '/class/captcha/image/fonts/' . $fonts[array_rand($fonts)];
202
    }
203
204
    public function setImageSize()
205
    {
206
        $MaxCharWidth  = 0;
207
        $MaxCharHeight = 0;
208
        $oImage        = imagecreatetruecolor(100, 100);
209
        $text_color    = imagecolorallocate($oImage, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
0 ignored issues
show
It seems like $oImage can also be of type false; however, parameter $image of imagecolorallocate() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

209
        $text_color    = imagecolorallocate(/** @scrutinizer ignore-type */ $oImage, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
Loading history...
The assignment to $text_color is dead and can be removed.
Loading history...
210
        $FontSize      = $this->config['fontsize_max'];
211
        for ($Angle = -30; $Angle <= 30; ++$Angle) {
212
            for ($i = 65; $i <= 90; ++$i) {
213
                $CharDetails   = imageftbbox($FontSize, $Angle, $this->font, chr($i), array());
214
                $_MaxCharWidth = abs($CharDetails[0] + $CharDetails[2]);
215
                if ($_MaxCharWidth > $MaxCharWidth) {
216
                    $MaxCharWidth = $_MaxCharWidth;
217
                }
218
                $_MaxCharHeight = abs($CharDetails[1] + $CharDetails[5]);
219
                if ($_MaxCharHeight > $MaxCharHeight) {
220
                    $MaxCharHeight = $_MaxCharHeight;
221
                }
222
            }
223
        }
224
        imagedestroy($oImage);
225
226
        $this->height  = $MaxCharHeight + 2;
227
        $this->spacing = (int)(($this->config['num_chars'] * $MaxCharWidth) / $this->config['num_chars']);
228
        $this->width   = ($this->config['num_chars'] * $MaxCharWidth) + ($this->spacing / 2);
229
    }
230
231
    /**
232
     * Return random background
233
     *
234
     * @return array
235
     */
236
    public function loadBackground()
237
    {
238
        $RandBackground = null;
239
        if ($backgrounds = $this->getList('backgrounds', '(gif|jpg|png)')) {
240
            $RandBackground = XOOPS_ROOT_PATH . '/class/captcha/image/backgrounds/' . $backgrounds[array_rand($backgrounds)];
241
        }
242
243
        return $RandBackground;
244
    }
245
246
    /**
247
     * Draw Image background
248
     */
249
    public function createFromFile()
250
    {
251
        if ($RandImage = $this->loadBackground()) {
252
            $ImageType = @getimagesize($RandImage);
253
            switch (@$ImageType[2]) {
254
                case 1:
255
                    $BackgroundImage = imagecreatefromgif($RandImage);
0 ignored issues
show
$RandImage of type array is incompatible with the type string expected by parameter $filename of imagecreatefromgif(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

255
                    $BackgroundImage = imagecreatefromgif(/** @scrutinizer ignore-type */ $RandImage);
Loading history...
256
                    break;
257
258
                case 2:
259
                    $BackgroundImage = imagecreatefromjpeg($RandImage);
0 ignored issues
show
$RandImage of type array is incompatible with the type string expected by parameter $filename of imagecreatefromjpeg(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

259
                    $BackgroundImage = imagecreatefromjpeg(/** @scrutinizer ignore-type */ $RandImage);
Loading history...
260
                    break;
261
262
                case 3:
263
                    $BackgroundImage = imagecreatefrompng($RandImage);
0 ignored issues
show
$RandImage of type array is incompatible with the type string expected by parameter $filename of imagecreatefrompng(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

263
                    $BackgroundImage = imagecreatefrompng(/** @scrutinizer ignore-type */ $RandImage);
Loading history...
264
                    break;
265
            }
266
        }
267
        if (!empty($BackgroundImage)) {
268
            imagecopyresized($this->oImage, $BackgroundImage, 0, 0, 0, 0, imagesx($this->oImage), imagesy($this->oImage), imagesx($BackgroundImage), imagesy($BackgroundImage));
269
            imagedestroy($BackgroundImage);
270
        } else {
271
            $this->drawBars();
272
        }
273
    }
274
275
    /**
276
     * Draw Code
277
     */
278
    public function drawCode()
279
    {
280
        for ($i = 0; $i < $this->config['num_chars']; ++$i) {
281
            // select random greyscale colour
282
            $text_color = imagecolorallocate($this->oImage, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100));
283
284
            // write text to image
285
            $Angle = mt_rand(10, 30);
286
            if ($i % 2) {
287
                $Angle = mt_rand(-10, -30);
288
            }
289
290
            // select random font size
291
            $FontSize = mt_rand($this->config['fontsize_min'], $this->config['fontsize_max']);
292
293
            $CharDetails = imageftbbox($FontSize, $Angle, $this->font, $this->code[$i], array());
294
            $CharHeight  = abs($CharDetails[1] + $CharDetails[5]);
295
296
            // calculate character starting coordinates
297
            $posX = ($this->spacing / 2) + ($i * $this->spacing);
298
            $posY = 2 + ($this->height / 2) + ($CharHeight / 4);
299
300
            imagefttext($this->oImage, $FontSize, $Angle, $posX, $posY, $text_color, $this->font, $this->code[$i], array());
301
        }
302
    }
303
304
    /**
305
     * Draw Border
306
     */
307
    public function drawBorder()
308
    {
309
        $rgb          = mt_rand(50, 150);
310
        $border_color = imagecolorallocate($this->oImage, $rgb, $rgb, $rgb);
311
        imagerectangle($this->oImage, 0, 0, $this->width - 1, $this->height - 1, $border_color);
312
    }
313
314
    /**
315
     * Draw Circles background
316
     */
317
    public function drawCircles()
318
    {
319
        for ($i = 1; $i <= $this->config['background_num']; ++$i) {
320
            $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
321
            imagefilledellipse($this->oImage, mt_rand(0, $this->width - 10), mt_rand(0, $this->height - 3), mt_rand(10, 20), mt_rand(20, 30), $randomcolor);
322
        }
323
    }
324
325
    /**
326
     * Draw Lines background
327
     */
328
    public function drawLines()
329
    {
330
        for ($i = 0; $i < $this->config['background_num']; ++$i) {
331
            $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
332
            imageline($this->oImage, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $randomcolor);
333
        }
334
    }
335
336
    /**
337
     * Draw Rectangles background
338
     */
339
    public function drawRectangles()
340
    {
341
        for ($i = 1; $i <= $this->config['background_num']; ++$i) {
342
            $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
343
            imagefilledrectangle($this->oImage, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $randomcolor);
344
        }
345
    }
346
347
    /**
348
     * Draw Bars background
349
     */
350
    public function drawBars()
351
    {
352
        for ($i = 0; $i <= $this->height;) {
353
            $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
354
            imageline($this->oImage, 0, $i, $this->width, $i, $randomcolor);
0 ignored issues
show
It seems like $i can also be of type double; however, parameter $y1 of imageline() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

354
            imageline($this->oImage, 0, /** @scrutinizer ignore-type */ $i, $this->width, $i, $randomcolor);
Loading history...
It seems like $i can also be of type double; however, parameter $y2 of imageline() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

354
            imageline($this->oImage, 0, $i, $this->width, /** @scrutinizer ignore-type */ $i, $randomcolor);
Loading history...
355
            $i += 2.5;
356
        }
357
        for ($i = 0; $i <= $this->width;) {
358
            $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
359
            imageline($this->oImage, $i, 0, $i, $this->height, $randomcolor);
0 ignored issues
show
It seems like $i can also be of type double; however, parameter $x1 of imageline() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

359
            imageline($this->oImage, /** @scrutinizer ignore-type */ $i, 0, $i, $this->height, $randomcolor);
Loading history...
It seems like $i can also be of type double; however, parameter $x2 of imageline() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

359
            imageline($this->oImage, $i, 0, /** @scrutinizer ignore-type */ $i, $this->height, $randomcolor);
Loading history...
360
            $i += 2.5;
361
        }
362
    }
363
364
    /**
365
     * Draw Ellipses background
366
     */
367
    public function drawEllipses()
368
    {
369
        for ($i = 1; $i <= $this->config['background_num']; ++$i) {
370
            $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
371
            imageellipse($this->oImage, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $randomcolor);
372
        }
373
    }
374
375
    /**
376
     * Draw polygons background
377
     */
378
    public function drawPolygons()
379
    {
380
        for ($i = 1; $i <= $this->config['background_num']; ++$i) {
381
            $randomcolor = imagecolorallocate($this->oImage, mt_rand(190, 255), mt_rand(190, 255), mt_rand(190, 255));
382
            $coords      = array();
383
            for ($j = 1; $j <= $this->config['polygon_point']; ++$j) {
384
                $coords[] = mt_rand(0, $this->width);
385
                $coords[] = mt_rand(0, $this->height);
386
            }
387
            imagefilledpolygon($this->oImage, $coords, $this->config['polygon_point'], $randomcolor);
388
        }
389
    }
390
    /**#@-*/
391
392
    /**
393
     *  Create CAPTCHA image with BMP
394
     *
395
     *  TODO
396
     * @param  string $file
397
     * @return string
398
     */
399
    public function createImageBmp($file = '')
400
    {
401
        $image = '';
402
403
        if (empty($file)) {
404
            header('Content-type: image/bmp');
405
            echo $image;
406
        } else {
407
            return $image;
408
        }
409
        return null;
410
    }
411
}
412
413
$imageHandler = new XoopsCaptchaImageHandler();
414
$imageHandler->loadImage();
415