card-mod-script 0.13.2 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/assets/script/decko/components.js.coffee +3 -0
- data/assets/script/decko/decko.js.coffee +0 -15
- data/assets/script/decko/editor.js.coffee +3 -1
- data/assets/script/decko/filter.js.coffee +14 -7
- data/assets/script/decko/filter_links.js.coffee +2 -2
- data/assets/script/decko/mod.js.coffee +2 -8
- data/assets/script/decko/name_editor.js.coffee +0 -18
- data/assets/script/decko/overlay.js.coffee +0 -3
- data/assets/script/{script_pointer_config.js.coffee → decko/pointer_config.js.coffee} +1 -2
- data/assets/script/{script_pointer_list_editor.js.coffee → decko/pointer_list_editor.js.coffee} +0 -0
- data/assets/script/decko/slot.js.coffee +3 -3
- data/assets/script/decko/slot_ready.js.coffee +1 -0
- data/assets/script/decko/slotter.js.coffee +23 -31
- data/assets/script/decko/type_editor.js.coffee +21 -0
- data/assets/script/decko/upload.js.coffee +12 -5
- data/assets/script/jquery-ui.min.js +13 -0
- data/assets/script/manifest.yml +16 -3
- data/init/early/init_execjs.rb +3 -0
- data/set/abstract/00_script.rb +30 -31
- data/set/abstract/01_asset_script.rb +0 -16
- data/set/abstract/{script_asset_list.rb → script_group.rb} +12 -13
- data/set/all/head_javascript.rb +12 -8
- data/set/right/script.rb +1 -14
- data/set/type/local_script_folder_group.rb +2 -2
- data/set/type/local_script_manifest_group.rb +1 -1
- data/set/type_plus_right/mod/script.rb +56 -0
- data/set/type_plus_right/set/script.rb +7 -0
- data/vendor/jquery_file_upload/LICENSE.txt +11 -12
- data/vendor/jquery_file_upload/README.md +189 -72
- data/vendor/jquery_file_upload/SECURITY.md +227 -0
- data/vendor/jquery_file_upload/VULNERABILITIES.md +118 -0
- data/vendor/jquery_file_upload/cors/postmessage.html +68 -58
- data/vendor/jquery_file_upload/cors/result.html +12 -10
- data/vendor/jquery_file_upload/css/jquery.fileupload-ui.css +24 -13
- data/vendor/jquery_file_upload/css/jquery.fileupload.css +3 -4
- data/vendor/jquery_file_upload/docker-compose.yml +55 -0
- data/vendor/jquery_file_upload/index.html +332 -230
- data/vendor/jquery_file_upload/js/cors/jquery.postmessage-transport.js +109 -109
- data/vendor/jquery_file_upload/js/cors/jquery.xdr-transport.js +81 -73
- data/vendor/jquery_file_upload/js/demo.js +75 -0
- data/vendor/jquery_file_upload/js/jquery.fileupload-audio.js +82 -94
- data/vendor/jquery_file_upload/js/jquery.fileupload-image.js +321 -300
- data/vendor/jquery_file_upload/js/jquery.fileupload-process.js +138 -146
- data/vendor/jquery_file_upload/js/jquery.fileupload-ui.js +737 -692
- data/vendor/jquery_file_upload/js/jquery.fileupload-validate.js +91 -97
- data/vendor/jquery_file_upload/js/jquery.fileupload-video.js +82 -94
- data/vendor/jquery_file_upload/js/jquery.fileupload.js +1569 -1451
- data/vendor/jquery_file_upload/js/jquery.iframe-transport.js +208 -205
- data/vendor/jquery_file_upload/js/vendor/jquery.ui.widget.js +397 -340
- data/vendor/jquery_file_upload/package-lock.json +6853 -0
- data/vendor/jquery_file_upload/package.json +71 -10
- data/vendor/jquery_file_upload/server/gae-python/app.yaml +11 -10
- data/vendor/jquery_file_upload/server/php/Dockerfile +23 -17
- data/vendor/jquery_file_upload/server/php/UploadHandler.php +206 -137
- data/vendor/jquery_file_upload/server/php/php.ini +5 -0
- data/vendor/jquery_file_upload/test/index.html +36 -159
- data/vendor/jquery_file_upload/test/unit.js +989 -0
- data/vendor/jquery_file_upload/test/vendor/chai.js +10854 -0
- data/vendor/jquery_file_upload/test/vendor/mocha.css +325 -0
- data/vendor/jquery_file_upload/test/vendor/mocha.js +18178 -0
- data/vendor/jquery_file_upload/wdio/LICENSE.txt +20 -0
- data/vendor/jquery_file_upload/wdio/assets/black+white-3x2.jpg +0 -0
- data/vendor/jquery_file_upload/wdio/assets/black+white-60x40.gif +0 -0
- data/vendor/jquery_file_upload/wdio/conf/chrome.js +40 -0
- data/vendor/jquery_file_upload/wdio/conf/firefox.js +25 -0
- data/vendor/jquery_file_upload/wdio/hooks/index.js +36 -0
- data/vendor/jquery_file_upload/wdio/test/pages/file-upload.js +79 -0
- data/vendor/jquery_file_upload/wdio/test/specs/01-file-upload.js +25 -0
- data/vendor/jquery_file_upload/wdio/wdio.conf.js +4 -0
- metadata +36 -53
- data/assets/script/jquery-ui.js +0 -10
- data/file/mod_script_script_decko_machine_output/file.js +0 -2710
- data/file/mod_script_script_jquery_machine_output/file.js +0 -12924
- data/lib/javascript/script_html5shiv_printshiv.js +0 -1
- data/set/self/script_html5shiv_printshiv.rb +0 -11
- data/set/self/script_mods.rb +0 -1
- data/set/type/mod_script_assets.rb +0 -21
- data/vendor/jquery_file_upload/CONTRIBUTING.md +0 -15
- data/vendor/jquery_file_upload/angularjs.html +0 -211
- data/vendor/jquery_file_upload/basic-plus.html +0 -226
- data/vendor/jquery_file_upload/basic.html +0 -136
- data/vendor/jquery_file_upload/bower-version-update.js +0 -16
- data/vendor/jquery_file_upload/bower.json +0 -64
- data/vendor/jquery_file_upload/css/jquery-ui-demo-ie8.css +0 -21
- data/vendor/jquery_file_upload/css/jquery-ui-demo.css +0 -67
- data/vendor/jquery_file_upload/css/style.css +0 -15
- data/vendor/jquery_file_upload/jquery-ui.html +0 -252
- data/vendor/jquery_file_upload/js/app.js +0 -101
- data/vendor/jquery_file_upload/js/jquery.fileupload-angular.js +0 -437
- data/vendor/jquery_file_upload/js/jquery.fileupload-jquery-ui.js +0 -161
- data/vendor/jquery_file_upload/js/main.js +0 -75
- data/vendor/jquery_file_upload/server/gae-go/app/main.go +0 -361
- data/vendor/jquery_file_upload/server/gae-go/app.yaml +0 -12
- data/vendor/jquery_file_upload/server/gae-go/static/favicon.ico +0 -0
- data/vendor/jquery_file_upload/server/gae-go/static/robots.txt +0 -2
- data/vendor/jquery_file_upload/server/php/docker-compose.yml +0 -9
- data/vendor/jquery_file_upload/test/test.js +0 -1292
|
@@ -16,7 +16,7 @@ class UploadHandler
|
|
|
16
16
|
protected $options;
|
|
17
17
|
|
|
18
18
|
// PHP File Upload error message codes:
|
|
19
|
-
//
|
|
19
|
+
// https://php.net/manual/en/features.file-upload.errors.php
|
|
20
20
|
protected $error_messages = array(
|
|
21
21
|
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
|
|
22
22
|
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
|
|
@@ -30,6 +30,7 @@ class UploadHandler
|
|
|
30
30
|
'min_file_size' => 'File is too small',
|
|
31
31
|
'accept_file_types' => 'Filetype not allowed',
|
|
32
32
|
'max_number_of_files' => 'Maximum number of files exceeded',
|
|
33
|
+
'invalid_file_type' => 'Invalid file type',
|
|
33
34
|
'max_width' => 'Image exceeds maximum width',
|
|
34
35
|
'min_width' => 'Image requires a minimum width',
|
|
35
36
|
'max_height' => 'Image exceeds maximum height',
|
|
@@ -38,10 +39,14 @@ class UploadHandler
|
|
|
38
39
|
'image_resize' => 'Failed to resize image'
|
|
39
40
|
);
|
|
40
41
|
|
|
42
|
+
const IMAGETYPE_GIF = 'image/gif';
|
|
43
|
+
const IMAGETYPE_JPEG = 'image/jpeg';
|
|
44
|
+
const IMAGETYPE_PNG = 'image/png';
|
|
45
|
+
|
|
41
46
|
protected $image_objects = array();
|
|
47
|
+
protected $response = array();
|
|
42
48
|
|
|
43
49
|
public function __construct($options = null, $initialize = true, $error_messages = null) {
|
|
44
|
-
$this->response = array();
|
|
45
50
|
$this->options = array(
|
|
46
51
|
'script_url' => $this->get_full_url().'/'.$this->basename($this->get_server_var('SCRIPT_NAME')),
|
|
47
52
|
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',
|
|
@@ -71,12 +76,12 @@ class UploadHandler
|
|
|
71
76
|
),
|
|
72
77
|
// By default, allow redirects to the referer protocol+host:
|
|
73
78
|
'redirect_allow_target' => '/^'.preg_quote(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_SCHEME)
|
|
80
|
+
.'://'
|
|
81
|
+
.parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_HOST)
|
|
82
|
+
.'/', // Trailing slash to not match subdomains by mistake
|
|
83
|
+
'/' // preg_quote delimiter param
|
|
84
|
+
).'/',
|
|
80
85
|
// Enable to provide file downloads via GET requests to the PHP script:
|
|
81
86
|
// 1. Set to 1 to download files via readfile method through PHP
|
|
82
87
|
// 2. Set to 2 to send a X-Sendfile header for lighttpd/Apache
|
|
@@ -89,17 +94,32 @@ class UploadHandler
|
|
|
89
94
|
'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB
|
|
90
95
|
// Defines which files can be displayed inline when downloaded:
|
|
91
96
|
'inline_file_types' => '/\.(gif|jpe?g|png)$/i',
|
|
92
|
-
// Defines which files (based on their names) are accepted for upload
|
|
93
|
-
|
|
97
|
+
// Defines which files (based on their names) are accepted for upload.
|
|
98
|
+
// By default, only allows file uploads with image file extensions.
|
|
99
|
+
// Only change this setting after making sure that any allowed file
|
|
100
|
+
// types cannot be executed by the webserver in the files directory,
|
|
101
|
+
// e.g. PHP scripts, nor executed by the browser when downloaded,
|
|
102
|
+
// e.g. HTML files with embedded JavaScript code.
|
|
103
|
+
// Please also read the SECURITY.md document in this repository.
|
|
104
|
+
'accept_file_types' => '/\.(gif|jpe?g|png)$/i',
|
|
105
|
+
// Replaces dots in filenames with the given string.
|
|
106
|
+
// Can be disabled by setting it to false or an empty string.
|
|
107
|
+
// Note that this is a security feature for servers that support
|
|
108
|
+
// multiple file extensions, e.g. the Apache AddHandler Directive:
|
|
109
|
+
// https://httpd.apache.org/docs/current/mod/mod_mime.html#addhandler
|
|
110
|
+
// Before disabling it, make sure that files uploaded with multiple
|
|
111
|
+
// extensions cannot be executed by the webserver, e.g.
|
|
112
|
+
// "example.php.png" with embedded PHP code, nor executed by the
|
|
113
|
+
// browser when downloaded, e.g. "example.html.gif" with embedded
|
|
114
|
+
// JavaScript code.
|
|
115
|
+
'replace_dots_in_filenames' => '-',
|
|
94
116
|
// The php.ini settings upload_max_filesize and post_max_size
|
|
95
117
|
// take precedence over the following max_file_size setting:
|
|
96
118
|
'max_file_size' => null,
|
|
97
119
|
'min_file_size' => 1,
|
|
98
120
|
// The maximum number of files for the upload directory:
|
|
99
121
|
'max_number_of_files' => null,
|
|
100
|
-
//
|
|
101
|
-
'image_file_types' => '/\.(gif|jpe?g|png)$/i',
|
|
102
|
-
// Use exif_imagetype on all files to correct file extensions:
|
|
122
|
+
// Reads first file bytes to identify and correct file extensions:
|
|
103
123
|
'correct_image_extensions' => false,
|
|
104
124
|
// Image resolution restrictions:
|
|
105
125
|
'max_width' => null,
|
|
@@ -132,21 +152,21 @@ class UploadHandler
|
|
|
132
152
|
'identify_bin' => 'identify',
|
|
133
153
|
'image_versions' => array(
|
|
134
154
|
// The empty image version key defines options for the original image.
|
|
135
|
-
// Keep in mind: these image manipulations are inherited by all other image versions from this point onwards.
|
|
155
|
+
// Keep in mind: these image manipulations are inherited by all other image versions from this point onwards.
|
|
136
156
|
// Also note that the property 'no_cache' is not inherited, since it's not a manipulation.
|
|
137
157
|
'' => array(
|
|
138
158
|
// Automatically rotate images based on EXIF meta data:
|
|
139
159
|
'auto_orient' => true
|
|
140
160
|
),
|
|
141
161
|
// You can add arrays to generate different versions.
|
|
142
|
-
// The name of the key is the name of the version (example: 'medium').
|
|
162
|
+
// The name of the key is the name of the version (example: 'medium').
|
|
143
163
|
// the array contains the options to apply.
|
|
144
164
|
/*
|
|
145
165
|
'medium' => array(
|
|
146
166
|
'max_width' => 800,
|
|
147
167
|
'max_height' => 600
|
|
148
168
|
),
|
|
149
|
-
|
|
169
|
+
*/
|
|
150
170
|
'thumbnail' => array(
|
|
151
171
|
// Uncomment the following to use a defined directory for the thumbnails
|
|
152
172
|
// instead of a subdirectory based on the version identifier.
|
|
@@ -204,13 +224,13 @@ class UploadHandler
|
|
|
204
224
|
protected function get_full_url() {
|
|
205
225
|
$https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0 ||
|
|
206
226
|
!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
|
|
207
|
-
|
|
227
|
+
strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0;
|
|
208
228
|
return
|
|
209
229
|
($https ? 'https://' : 'http://').
|
|
210
230
|
(!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
|
|
211
231
|
(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
|
|
212
|
-
|
|
213
|
-
|
|
232
|
+
($https && $_SERVER['SERVER_PORT'] === 443 ||
|
|
233
|
+
$_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
|
|
214
234
|
substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
|
|
215
235
|
}
|
|
216
236
|
|
|
@@ -305,7 +325,7 @@ class UploadHandler
|
|
|
305
325
|
|
|
306
326
|
protected function is_valid_file_object($file_name) {
|
|
307
327
|
$file_path = $this->get_upload_path($file_name);
|
|
308
|
-
if (
|
|
328
|
+
if (strlen($file_name) > 0 && $file_name[0] !== '.' && is_file($file_path)) {
|
|
309
329
|
return true;
|
|
310
330
|
}
|
|
311
331
|
return false;
|
|
@@ -358,7 +378,11 @@ class UploadHandler
|
|
|
358
378
|
public function get_config_bytes($val) {
|
|
359
379
|
$val = trim($val);
|
|
360
380
|
$last = strtolower($val[strlen($val)-1]);
|
|
361
|
-
|
|
381
|
+
if (is_numeric($val)) {
|
|
382
|
+
$val = (int)$val;
|
|
383
|
+
} else {
|
|
384
|
+
$val = (int)substr($val, 0, -1);
|
|
385
|
+
}
|
|
362
386
|
switch ($last) {
|
|
363
387
|
case 'g':
|
|
364
388
|
$val *= 1024;
|
|
@@ -370,7 +394,53 @@ class UploadHandler
|
|
|
370
394
|
return $this->fix_integer_overflow($val);
|
|
371
395
|
}
|
|
372
396
|
|
|
373
|
-
protected function
|
|
397
|
+
protected function validate_image_file($uploaded_file, $file, $error, $index) {
|
|
398
|
+
if ($this->imagetype($uploaded_file) !== $this->get_file_type($file->name)) {
|
|
399
|
+
$file->error = $this->get_error_message('invalid_file_type');
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
$max_width = @$this->options['max_width'];
|
|
403
|
+
$max_height = @$this->options['max_height'];
|
|
404
|
+
$min_width = @$this->options['min_width'];
|
|
405
|
+
$min_height = @$this->options['min_height'];
|
|
406
|
+
if ($max_width || $max_height || $min_width || $min_height) {
|
|
407
|
+
list($img_width, $img_height) = $this->get_image_size($uploaded_file);
|
|
408
|
+
// If we are auto rotating the image by default, do the checks on
|
|
409
|
+
// the correct orientation
|
|
410
|
+
if (
|
|
411
|
+
@$this->options['image_versions']['']['auto_orient'] &&
|
|
412
|
+
function_exists('exif_read_data') &&
|
|
413
|
+
($exif = @exif_read_data($uploaded_file)) &&
|
|
414
|
+
(((int) @$exif['Orientation']) >= 5)
|
|
415
|
+
) {
|
|
416
|
+
$tmp = $img_width;
|
|
417
|
+
$img_width = $img_height;
|
|
418
|
+
$img_height = $tmp;
|
|
419
|
+
unset($tmp);
|
|
420
|
+
}
|
|
421
|
+
if (!empty($img_width) && !empty($img_height)) {
|
|
422
|
+
if ($max_width && $img_width > $max_width) {
|
|
423
|
+
$file->error = $this->get_error_message('max_width');
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
if ($max_height && $img_height > $max_height) {
|
|
427
|
+
$file->error = $this->get_error_message('max_height');
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
if ($min_width && $img_width < $min_width) {
|
|
431
|
+
$file->error = $this->get_error_message('min_width');
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
if ($min_height && $img_height < $min_height) {
|
|
435
|
+
$file->error = $this->get_error_message('min_height');
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return true;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
protected function validate($uploaded_file, $file, $error, $index, $content_range) {
|
|
374
444
|
if ($error) {
|
|
375
445
|
$file->error = $this->get_error_message($error);
|
|
376
446
|
return false;
|
|
@@ -395,7 +465,7 @@ class UploadHandler
|
|
|
395
465
|
if ($this->options['max_file_size'] && (
|
|
396
466
|
$file_size > $this->options['max_file_size'] ||
|
|
397
467
|
$file->size > $this->options['max_file_size'])
|
|
398
|
-
|
|
468
|
+
) {
|
|
399
469
|
$file->error = $this->get_error_message('max_file_size');
|
|
400
470
|
return false;
|
|
401
471
|
}
|
|
@@ -405,52 +475,14 @@ class UploadHandler
|
|
|
405
475
|
return false;
|
|
406
476
|
}
|
|
407
477
|
if (is_int($this->options['max_number_of_files']) &&
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
478
|
+
($this->count_file_objects() >= $this->options['max_number_of_files']) &&
|
|
479
|
+
// Ignore additional chunks of existing files:
|
|
480
|
+
!is_file($this->get_upload_path($file->name))) {
|
|
411
481
|
$file->error = $this->get_error_message('max_number_of_files');
|
|
412
482
|
return false;
|
|
413
483
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
$min_width = @$this->options['min_width'];
|
|
417
|
-
$min_height = @$this->options['min_height'];
|
|
418
|
-
if (($max_width || $max_height || $min_width || $min_height)
|
|
419
|
-
&& preg_match($this->options['image_file_types'], $file->name)) {
|
|
420
|
-
list($img_width, $img_height) = $this->get_image_size($uploaded_file);
|
|
421
|
-
|
|
422
|
-
// If we are auto rotating the image by default, do the checks on
|
|
423
|
-
// the correct orientation
|
|
424
|
-
if (
|
|
425
|
-
@$this->options['image_versions']['']['auto_orient'] &&
|
|
426
|
-
function_exists('exif_read_data') &&
|
|
427
|
-
($exif = @exif_read_data($uploaded_file)) &&
|
|
428
|
-
(((int) @$exif['Orientation']) >= 5)
|
|
429
|
-
) {
|
|
430
|
-
$tmp = $img_width;
|
|
431
|
-
$img_width = $img_height;
|
|
432
|
-
$img_height = $tmp;
|
|
433
|
-
unset($tmp);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
}
|
|
437
|
-
if (!empty($img_width)) {
|
|
438
|
-
if ($max_width && $img_width > $max_width) {
|
|
439
|
-
$file->error = $this->get_error_message('max_width');
|
|
440
|
-
return false;
|
|
441
|
-
}
|
|
442
|
-
if ($max_height && $img_height > $max_height) {
|
|
443
|
-
$file->error = $this->get_error_message('max_height');
|
|
444
|
-
return false;
|
|
445
|
-
}
|
|
446
|
-
if ($min_width && $img_width < $min_width) {
|
|
447
|
-
$file->error = $this->get_error_message('min_width');
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
450
|
-
if ($min_height && $img_height < $min_height) {
|
|
451
|
-
$file->error = $this->get_error_message('min_height');
|
|
452
|
-
return false;
|
|
453
|
-
}
|
|
484
|
+
if (!$content_range && $this->has_image_file_extension($file->name)) {
|
|
485
|
+
return $this->validate_image_file($uploaded_file, $file, $error, $index);
|
|
454
486
|
}
|
|
455
487
|
return true;
|
|
456
488
|
}
|
|
@@ -471,12 +503,12 @@ class UploadHandler
|
|
|
471
503
|
}
|
|
472
504
|
|
|
473
505
|
protected function get_unique_filename($file_path, $name, $size, $type, $error,
|
|
474
|
-
|
|
506
|
+
$index, $content_range) {
|
|
475
507
|
while(is_dir($this->get_upload_path($name))) {
|
|
476
508
|
$name = $this->upcount_name($name);
|
|
477
509
|
}
|
|
478
510
|
// Keep an existing filename if this is part of a chunked upload:
|
|
479
|
-
$uploaded_bytes = $this->fix_integer_overflow((int)
|
|
511
|
+
$uploaded_bytes = $this->fix_integer_overflow((int)@$content_range[1]);
|
|
480
512
|
while (is_file($this->get_upload_path($name))) {
|
|
481
513
|
if ($uploaded_bytes === $this->get_file_size(
|
|
482
514
|
$this->get_upload_path($name))) {
|
|
@@ -487,26 +519,26 @@ class UploadHandler
|
|
|
487
519
|
return $name;
|
|
488
520
|
}
|
|
489
521
|
|
|
522
|
+
protected function get_valid_image_extensions($file_path) {
|
|
523
|
+
switch ($this->imagetype($file_path)) {
|
|
524
|
+
case self::IMAGETYPE_JPEG:
|
|
525
|
+
return array('jpg', 'jpeg');
|
|
526
|
+
case self::IMAGETYPE_PNG:
|
|
527
|
+
return array('png');
|
|
528
|
+
case self::IMAGETYPE_GIF:
|
|
529
|
+
return array('gif');
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
490
533
|
protected function fix_file_extension($file_path, $name, $size, $type, $error,
|
|
491
|
-
|
|
534
|
+
$index, $content_range) {
|
|
492
535
|
// Add missing file extension for known image types:
|
|
493
536
|
if (strpos($name, '.') === false &&
|
|
494
|
-
|
|
537
|
+
preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
|
|
495
538
|
$name .= '.'.$matches[1];
|
|
496
539
|
}
|
|
497
|
-
if ($this->options['correct_image_extensions']
|
|
498
|
-
|
|
499
|
-
switch (@exif_imagetype($file_path)){
|
|
500
|
-
case IMAGETYPE_JPEG:
|
|
501
|
-
$extensions = array('jpg', 'jpeg');
|
|
502
|
-
break;
|
|
503
|
-
case IMAGETYPE_PNG:
|
|
504
|
-
$extensions = array('png');
|
|
505
|
-
break;
|
|
506
|
-
case IMAGETYPE_GIF:
|
|
507
|
-
$extensions = array('gif');
|
|
508
|
-
break;
|
|
509
|
-
}
|
|
540
|
+
if ($this->options['correct_image_extensions']) {
|
|
541
|
+
$extensions = $this->get_valid_image_extensions($file_path);
|
|
510
542
|
// Adjust incorrect image file extensions:
|
|
511
543
|
if (!empty($extensions)) {
|
|
512
544
|
$parts = explode('.', $name);
|
|
@@ -522,11 +554,21 @@ class UploadHandler
|
|
|
522
554
|
}
|
|
523
555
|
|
|
524
556
|
protected function trim_file_name($file_path, $name, $size, $type, $error,
|
|
525
|
-
|
|
557
|
+
$index, $content_range) {
|
|
526
558
|
// Remove path information and dots around the filename, to prevent uploading
|
|
527
559
|
// into different directories or replacing hidden system files.
|
|
528
560
|
// Also remove control characters and spaces (\x00..\x20) around the filename:
|
|
529
561
|
$name = trim($this->basename(stripslashes($name)), ".\x00..\x20");
|
|
562
|
+
// Replace dots in filenames to avoid security issues with servers
|
|
563
|
+
// that interpret multiple file extensions, e.g. "example.php.png":
|
|
564
|
+
$replacement = $this->options['replace_dots_in_filenames'];
|
|
565
|
+
if (!empty($replacement)) {
|
|
566
|
+
$parts = explode('.', $name);
|
|
567
|
+
if (count($parts) > 2) {
|
|
568
|
+
$ext = array_pop($parts);
|
|
569
|
+
$name = implode($replacement, $parts).'.'.$ext;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
530
572
|
// Use a timestamp for empty filenames:
|
|
531
573
|
if (!$name) {
|
|
532
574
|
$name = str_replace('.', '-', microtime(true));
|
|
@@ -535,7 +577,7 @@ class UploadHandler
|
|
|
535
577
|
}
|
|
536
578
|
|
|
537
579
|
protected function get_file_name($file_path, $name, $size, $type, $error,
|
|
538
|
-
|
|
580
|
+
$index, $content_range) {
|
|
539
581
|
$name = $this->trim_file_name($file_path, $name, $size, $type, $error,
|
|
540
582
|
$index, $content_range);
|
|
541
583
|
return $this->get_unique_filename(
|
|
@@ -769,25 +811,26 @@ class UploadHandler
|
|
|
769
811
|
// Handle transparency in GIF and PNG images:
|
|
770
812
|
switch ($type) {
|
|
771
813
|
case 'gif':
|
|
772
|
-
case 'png':
|
|
773
814
|
imagecolortransparent($new_img, imagecolorallocate($new_img, 0, 0, 0));
|
|
815
|
+
break;
|
|
774
816
|
case 'png':
|
|
817
|
+
imagecolortransparent($new_img, imagecolorallocate($new_img, 0, 0, 0));
|
|
775
818
|
imagealphablending($new_img, false);
|
|
776
819
|
imagesavealpha($new_img, true);
|
|
777
820
|
break;
|
|
778
821
|
}
|
|
779
822
|
$success = imagecopyresampled(
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
823
|
+
$new_img,
|
|
824
|
+
$src_img,
|
|
825
|
+
$dst_x,
|
|
826
|
+
$dst_y,
|
|
827
|
+
0,
|
|
828
|
+
0,
|
|
829
|
+
$new_width,
|
|
830
|
+
$new_height,
|
|
831
|
+
$img_width,
|
|
832
|
+
$img_height
|
|
833
|
+
) && $write_func($new_img, $new_file_path, $image_quality);
|
|
791
834
|
$this->gd_set_image_object($file_path, $new_img);
|
|
792
835
|
return $success;
|
|
793
836
|
}
|
|
@@ -801,7 +844,12 @@ class UploadHandler
|
|
|
801
844
|
$image->setResourceLimit($type, $limit);
|
|
802
845
|
}
|
|
803
846
|
}
|
|
804
|
-
|
|
847
|
+
try {
|
|
848
|
+
$image->readImage($file_path);
|
|
849
|
+
} catch (ImagickException $e) {
|
|
850
|
+
error_log($e->getMessage());
|
|
851
|
+
return null;
|
|
852
|
+
}
|
|
805
853
|
$this->image_objects[$file_path] = $image;
|
|
806
854
|
}
|
|
807
855
|
return $this->image_objects[$file_path];
|
|
@@ -858,6 +906,7 @@ class UploadHandler
|
|
|
858
906
|
$file_path,
|
|
859
907
|
!empty($options['crop']) || !empty($options['no_cache'])
|
|
860
908
|
);
|
|
909
|
+
if (is_null($image)) return false;
|
|
861
910
|
if ($image->getImageFormat() === 'GIF') {
|
|
862
911
|
// Handle animated GIFs:
|
|
863
912
|
$images = $image->coalesceImages();
|
|
@@ -870,32 +919,28 @@ class UploadHandler
|
|
|
870
919
|
$image_oriented = false;
|
|
871
920
|
if (!empty($options['auto_orient'])) {
|
|
872
921
|
$image_oriented = $this->imagick_orient_image($image);
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
$image_resize = false;
|
|
922
|
+
}
|
|
923
|
+
$image_resize = false;
|
|
876
924
|
$new_width = $max_width = $img_width = $image->getImageWidth();
|
|
877
|
-
$new_height = $max_height = $img_height = $image->getImageHeight();
|
|
878
|
-
|
|
925
|
+
$new_height = $max_height = $img_height = $image->getImageHeight();
|
|
879
926
|
// use isset(). User might be setting max_width = 0 (auto in regular resizing). Value 0 would be considered empty when you use empty()
|
|
880
927
|
if (isset($options['max_width'])) {
|
|
881
|
-
$image_resize = true;
|
|
882
|
-
$new_width = $max_width = $options['max_width'];
|
|
928
|
+
$image_resize = true;
|
|
929
|
+
$new_width = $max_width = $options['max_width'];
|
|
883
930
|
}
|
|
884
931
|
if (isset($options['max_height'])) {
|
|
885
932
|
$image_resize = true;
|
|
886
933
|
$new_height = $max_height = $options['max_height'];
|
|
887
934
|
}
|
|
888
|
-
|
|
889
935
|
$image_strip = (isset($options['strip']) ? $options['strip'] : false);
|
|
890
|
-
|
|
891
|
-
if ( !$image_oriented && ($max_width >= $img_width) && ($max_height >= $img_height) && !$image_strip && empty($options["jpeg_quality"]) ) {
|
|
936
|
+
if ( !$image_oriented && ($max_width >= $img_width) && ($max_height >= $img_height) && !$image_strip && empty($options["jpeg_quality"]) ) {
|
|
892
937
|
if ($file_path !== $new_file_path) {
|
|
893
938
|
return copy($file_path, $new_file_path);
|
|
894
939
|
}
|
|
895
940
|
return true;
|
|
896
941
|
}
|
|
897
942
|
$crop = (isset($options['crop']) ? $options['crop'] : false);
|
|
898
|
-
|
|
943
|
+
|
|
899
944
|
if ($crop) {
|
|
900
945
|
$x = 0;
|
|
901
946
|
$y = 0;
|
|
@@ -1021,13 +1066,18 @@ class UploadHandler
|
|
|
1021
1066
|
}
|
|
1022
1067
|
|
|
1023
1068
|
protected function create_scaled_image($file_name, $version, $options) {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1069
|
+
try {
|
|
1070
|
+
if ($this->options['image_library'] === 2) {
|
|
1071
|
+
return $this->imagemagick_create_scaled_image($file_name, $version, $options);
|
|
1072
|
+
}
|
|
1073
|
+
if ($this->options['image_library'] && extension_loaded('imagick')) {
|
|
1074
|
+
return $this->imagick_create_scaled_image($file_name, $version, $options);
|
|
1075
|
+
}
|
|
1076
|
+
return $this->gd_create_scaled_image($file_name, $version, $options);
|
|
1077
|
+
} catch (\Exception $e) {
|
|
1078
|
+
error_log($e->getMessage());
|
|
1079
|
+
return false;
|
|
1029
1080
|
}
|
|
1030
|
-
return $this->gd_create_scaled_image($file_name, $version, $options);
|
|
1031
1081
|
}
|
|
1032
1082
|
|
|
1033
1083
|
protected function destroy_image_object($file_path) {
|
|
@@ -1036,15 +1086,31 @@ class UploadHandler
|
|
|
1036
1086
|
}
|
|
1037
1087
|
}
|
|
1038
1088
|
|
|
1039
|
-
protected function
|
|
1040
|
-
|
|
1041
|
-
|
|
1089
|
+
protected function imagetype($file_path) {
|
|
1090
|
+
$fp = fopen($file_path, 'r');
|
|
1091
|
+
$data = fread($fp, 4);
|
|
1092
|
+
fclose($fp);
|
|
1093
|
+
// GIF: 47 49 46 38
|
|
1094
|
+
if ($data === 'GIF8') {
|
|
1095
|
+
return self::IMAGETYPE_GIF;
|
|
1096
|
+
}
|
|
1097
|
+
// JPG: FF D8 FF
|
|
1098
|
+
if (bin2hex(substr($data, 0, 3)) === 'ffd8ff') {
|
|
1099
|
+
return self::IMAGETYPE_JPEG;
|
|
1042
1100
|
}
|
|
1043
|
-
|
|
1044
|
-
|
|
1101
|
+
// PNG: 89 50 4E 47
|
|
1102
|
+
if (bin2hex(@$data[0]).substr($data, 1, 4) === '89PNG') {
|
|
1103
|
+
return self::IMAGETYPE_PNG;
|
|
1045
1104
|
}
|
|
1046
|
-
|
|
1047
|
-
|
|
1105
|
+
return false;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
protected function is_valid_image_file($file_path) {
|
|
1109
|
+
return !!$this->imagetype($file_path);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
protected function has_image_file_extension($file_path) {
|
|
1113
|
+
return !!preg_match('/\.(gif|jpe?g|png)$/i', $file_path);
|
|
1048
1114
|
}
|
|
1049
1115
|
|
|
1050
1116
|
protected function handle_image_file($file_path, $file) {
|
|
@@ -1065,20 +1131,20 @@ class UploadHandler
|
|
|
1065
1131
|
}
|
|
1066
1132
|
if (count($failed_versions)) {
|
|
1067
1133
|
$file->error = $this->get_error_message('image_resize')
|
|
1068
|
-
|
|
1134
|
+
.' ('.implode(', ', $failed_versions).')';
|
|
1069
1135
|
}
|
|
1070
1136
|
// Free memory:
|
|
1071
1137
|
$this->destroy_image_object($file_path);
|
|
1072
1138
|
}
|
|
1073
1139
|
|
|
1074
1140
|
protected function handle_file_upload($uploaded_file, $name, $size, $type, $error,
|
|
1075
|
-
|
|
1141
|
+
$index = null, $content_range = null) {
|
|
1076
1142
|
$file = new \stdClass();
|
|
1077
1143
|
$file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error,
|
|
1078
1144
|
$index, $content_range);
|
|
1079
1145
|
$file->size = $this->fix_integer_overflow((int)$size);
|
|
1080
1146
|
$file->type = $type;
|
|
1081
|
-
if ($this->validate($uploaded_file, $file, $error, $index)) {
|
|
1147
|
+
if ($this->validate($uploaded_file, $file, $error, $index, $content_range)) {
|
|
1082
1148
|
$this->handle_form_data($file, $index);
|
|
1083
1149
|
$upload_dir = $this->get_upload_path();
|
|
1084
1150
|
if (!is_dir($upload_dir)) {
|
|
@@ -1109,8 +1175,12 @@ class UploadHandler
|
|
|
1109
1175
|
$file_size = $this->get_file_size($file_path, $append_file);
|
|
1110
1176
|
if ($file_size === $file->size) {
|
|
1111
1177
|
$file->url = $this->get_download_url($file->name);
|
|
1112
|
-
if ($this->
|
|
1113
|
-
$this->
|
|
1178
|
+
if ($this->has_image_file_extension($file->name)) {
|
|
1179
|
+
if ($content_range && !$this->validate_image_file($file_path, $file, $error, $index)) {
|
|
1180
|
+
unlink($file_path);
|
|
1181
|
+
} else {
|
|
1182
|
+
$this->handle_image_file($file_path, $file);
|
|
1183
|
+
}
|
|
1114
1184
|
}
|
|
1115
1185
|
} else {
|
|
1116
1186
|
$file->size = $file_size;
|
|
@@ -1196,11 +1266,11 @@ class UploadHandler
|
|
|
1196
1266
|
switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) {
|
|
1197
1267
|
case 'jpeg':
|
|
1198
1268
|
case 'jpg':
|
|
1199
|
-
return
|
|
1269
|
+
return self::IMAGETYPE_JPEG;
|
|
1200
1270
|
case 'png':
|
|
1201
|
-
return
|
|
1271
|
+
return self::IMAGETYPE_PNG;
|
|
1202
1272
|
case 'gif':
|
|
1203
|
-
return
|
|
1273
|
+
return self::IMAGETYPE_GIF;
|
|
1204
1274
|
default:
|
|
1205
1275
|
return '';
|
|
1206
1276
|
}
|
|
@@ -1273,8 +1343,7 @@ class UploadHandler
|
|
|
1273
1343
|
$json = json_encode($content);
|
|
1274
1344
|
$redirect = stripslashes($this->get_post_param('redirect'));
|
|
1275
1345
|
if ($redirect && preg_match($this->options['redirect_allow_target'], $redirect)) {
|
|
1276
|
-
$this->header('Location: '.sprintf($redirect, rawurlencode($json)));
|
|
1277
|
-
return;
|
|
1346
|
+
return $this->header('Location: '.sprintf($redirect, rawurlencode($json)));
|
|
1278
1347
|
}
|
|
1279
1348
|
$this->head();
|
|
1280
1349
|
if ($this->get_server_var('HTTP_CONTENT_RANGE')) {
|
|
@@ -1342,7 +1411,7 @@ class UploadHandler
|
|
|
1342
1411
|
$content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE');
|
|
1343
1412
|
$content_range = $content_range_header ?
|
|
1344
1413
|
preg_split('/[^0-9]+/', $content_range_header) : null;
|
|
1345
|
-
$size =
|
|
1414
|
+
$size = @$content_range[3];
|
|
1346
1415
|
$files = array();
|
|
1347
1416
|
if ($upload) {
|
|
1348
1417
|
if (is_array($upload['tmp_name'])) {
|
|
@@ -1365,11 +1434,11 @@ class UploadHandler
|
|
|
1365
1434
|
$files[] = $this->handle_file_upload(
|
|
1366
1435
|
isset($upload['tmp_name']) ? $upload['tmp_name'] : null,
|
|
1367
1436
|
$file_name ? $file_name : (isset($upload['name']) ?
|
|
1368
|
-
|
|
1437
|
+
$upload['name'] : null),
|
|
1369
1438
|
$size ? $size : (isset($upload['size']) ?
|
|
1370
|
-
|
|
1439
|
+
$upload['size'] : $this->get_server_var('CONTENT_LENGTH')),
|
|
1371
1440
|
isset($upload['type']) ?
|
|
1372
|
-
|
|
1441
|
+
$upload['type'] : $this->get_server_var('CONTENT_TYPE'),
|
|
1373
1442
|
isset($upload['error']) ? $upload['error'] : null,
|
|
1374
1443
|
null,
|
|
1375
1444
|
$content_range
|
|
@@ -1388,7 +1457,7 @@ class UploadHandler
|
|
|
1388
1457
|
$response = array();
|
|
1389
1458
|
foreach ($file_names as $file_name) {
|
|
1390
1459
|
$file_path = $this->get_upload_path($file_name);
|
|
1391
|
-
$success =
|
|
1460
|
+
$success = strlen($file_name) > 0 && $file_name[0] !== '.' && is_file($file_path) && unlink($file_path);
|
|
1392
1461
|
if ($success) {
|
|
1393
1462
|
foreach ($this->options['image_versions'] as $version => $options) {
|
|
1394
1463
|
if (!empty($version)) {
|