WebP Express - Version 0.14.5

Version Description

(released: 20 jun 2019)

  • Various fixes
Download this release

Release Info

Developer rosell.dk
Plugin Icon 128x128 WebP Express
Version 0.14.5
Comparing to
See all releases

Code changes from version 0.14.4 to 0.14.5

Files changed (61) hide show
  1. README.txt +10 -2
  2. composer.json +1 -1
  3. composer.lock +5 -5
  4. lib/classes/AlterHtmlInit.php +1 -1
  5. lib/classes/Convert.php +4 -0
  6. lib/classes/ConvertHelperIndependent.php +40 -2
  7. lib/classes/ConvertersHelper.php +1 -1
  8. lib/options/enqueue_scripts.php +2 -2
  9. lib/options/js/0.14.2/whitelist_old.js +0 -189
  10. lib/options/js/{0.14.2 → 0.14.5}/authorized_sites_bak.js +0 -0
  11. lib/options/js/{0.14.2 → 0.14.5}/bulk-convert.js +0 -0
  12. lib/options/js/{0.14.2 → 0.14.5}/converters.js +0 -0
  13. lib/options/js/{0.14.2 → 0.14.5}/das-popup.js +0 -0
  14. lib/options/js/{0.14.2 → 0.14.5}/image-comparison-slider.js +0 -0
  15. lib/options/js/{0.14.2 → 0.14.5}/page.js +0 -0
  16. lib/options/js/{0.14.2 → 0.14.5}/purge-cache.js +0 -0
  17. lib/options/js/{0.14.2 → 0.14.5}/sortable.min.js +0 -0
  18. lib/options/js/{0.14.2 → 0.14.5}/test-convert.js +0 -0
  19. lib/options/js/{0.14.2 → 0.14.5}/whitelist.js +9 -1
  20. lib/options/options/conversion-options/jpeg.inc +2 -2
  21. lib/options/options/conversion-options/png.inc +3 -2
  22. lib/options/options/general/image-types.inc +1 -3
  23. lib/options/page-messages.php +7 -6
  24. lib/options/submit.php +10 -2
  25. vendor/composer/installed.json +6 -6
  26. vendor/rosell-dk/webp-convert/build-scripts/PHPMerger.php +7 -3
  27. vendor/rosell-dk/webp-convert/build-scripts/build.php +20 -4
  28. vendor/rosell-dk/webp-convert/build-tests-webp-convert/WebPConvertBuildTest.php +11 -1
  29. vendor/rosell-dk/webp-convert/build-tests-wod/WodBuildTest.php +13 -2
  30. vendor/rosell-dk/webp-convert/src-build/webp-convert.inc +268 -106
  31. vendor/rosell-dk/webp-convert/src-build/webp-on-demand-1.inc +793 -16
  32. vendor/rosell-dk/webp-convert/src-build/webp-on-demand-2.inc +53 -668
  33. vendor/rosell-dk/webp-convert/src/Convert/Converters/AbstractConverter.php +7 -22
  34. vendor/rosell-dk/webp-convert/src/Convert/Converters/BaseTraits/SourceValidationTrait.php +0 -64
  35. vendor/rosell-dk/webp-convert/src/Exceptions/InvalidInput/InvalidImageTypeException.php +10 -0
  36. vendor/rosell-dk/webp-convert/src/Exceptions/InvalidInput/TargetNotFoundException.php +10 -0
  37. vendor/rosell-dk/webp-convert/src/Exceptions/InvalidInputException.php +10 -0
  38. vendor/rosell-dk/webp-convert/src/Helpers/InputValidator.php +61 -0
  39. vendor/rosell-dk/webp-convert/src/Helpers/MimeType.php +40 -0
  40. vendor/rosell-dk/webp-convert/src/Helpers/PathChecker.php +97 -0
  41. vendor/rosell-dk/webp-convert/src/Serve/Report.php +5 -3
  42. vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebP.php +8 -13
  43. vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebPWithErrorHandling.php +3 -2
  44. vendor/rosell-dk/webp-convert/src/Serve/ServeFile.php +11 -1
  45. vendor/rosell-dk/webp-convert/tests/Convert/Converters/AbstractConverterTest.php +27 -10
  46. vendor/rosell-dk/webp-convert/tests/Convert/Converters/BaseTraits/AutoQualityTraitTest.php +20 -12
  47. vendor/rosell-dk/webp-convert/tests/Convert/Converters/ConverterTestHelper.php +21 -5
  48. vendor/rosell-dk/webp-convert/tests/Convert/Converters/CwebpTest.php +16 -8
  49. vendor/rosell-dk/webp-convert/tests/Convert/Converters/EwwwTest.php +12 -4
  50. vendor/rosell-dk/webp-convert/tests/Convert/Converters/GdTest.php +12 -4
  51. vendor/rosell-dk/webp-convert/tests/Convert/Converters/GraphicsMagickTest.php +10 -2
  52. vendor/rosell-dk/webp-convert/tests/Convert/Converters/ImageMagickTest.php +10 -2
  53. vendor/rosell-dk/webp-convert/tests/Convert/Converters/StackTest.php +14 -4
  54. vendor/rosell-dk/webp-convert/tests/Convert/Converters/VipsTest.php +12 -3
  55. vendor/rosell-dk/webp-convert/tests/Convert/Converters/WPCTest.php +36 -16
  56. vendor/rosell-dk/webp-convert/tests/Serve/ServeConvertedWebPTest.php +34 -22
  57. vendor/rosell-dk/webp-convert/tests/Serve/ServeFileTest.php +21 -8
  58. vendor/rosell-dk/webp-convert/tests/WebPConvertTest.php +2 -1
  59. webp-express.php +1 -1
  60. wod/webp-on-demand.php +25 -3
  61. wod/webp-realizer.php +7 -1
README.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://ko-fi.com/rosell
4
  Tags: webp, images, performance
5
  Requires at least: 4.0
6
  Tested up to: 5.2
7
- Stable tag: 0.14.4
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -12,7 +12,7 @@ License URI: https://www.gnu.org/licenses/gpl-3.0.html
12
  Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP.
13
 
14
  == Description ==
15
- [](http://coderisk.com/wp/plugin/webp-express/RIPS-NAA8tMia3z)
16
  Almost 4 out of 5 mobile users use a browser that is able to display webp images. Yet, on most websites, they are served jpeg images, which are typically double the size of webp images for a given quality. What a waste of bandwidth! This plugin was created to help remedy that situation. With little effort, Wordpress admins can have their site serving autogenerated webp images to browsers that supports it, while still serving jpeg and png files to browsers that does not support webp.
17
 
18
  ### The image converter
@@ -605,6 +605,11 @@ Easy enough! - [Go here!](https://ko-fi.com/rosell). Or [here](https://buymeacof
605
 
606
  == Changelog ==
607
 
 
 
 
 
 
608
  = 0.14.4 =
609
  *(released: 18 jun 2019)*
610
 
@@ -819,6 +824,9 @@ For older releases, check out changelog.txt
819
 
820
  == Upgrade Notice ==
821
 
 
 
 
822
  = 0.14.4 =
823
  Now bundles with multiple cwebp binaries for linux for systems where 1.0.2 fails.
824
 
4
  Tags: webp, images, performance
5
  Requires at least: 4.0
6
  Tested up to: 5.2
7
+ Stable tag: 0.14.5
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
12
  Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP.
13
 
14
  == Description ==
15
+
16
  Almost 4 out of 5 mobile users use a browser that is able to display webp images. Yet, on most websites, they are served jpeg images, which are typically double the size of webp images for a given quality. What a waste of bandwidth! This plugin was created to help remedy that situation. With little effort, Wordpress admins can have their site serving autogenerated webp images to browsers that supports it, while still serving jpeg and png files to browsers that does not support webp.
17
 
18
  ### The image converter
605
 
606
  == Changelog ==
607
 
608
+ = 0.14.5 =
609
+ *(released: 20 jun 2019)*
610
+
611
+ * Various fixes
612
+
613
  = 0.14.4 =
614
  *(released: 18 jun 2019)*
615
 
824
 
825
  == Upgrade Notice ==
826
 
827
+ = 0.14.5 =
828
+ Various fixes
829
+
830
  = 0.14.4 =
831
  Now bundles with multiple cwebp binaries for linux for systems where 1.0.2 fails.
832
 
composer.json CHANGED
@@ -4,7 +4,7 @@
4
  "type": "project",
5
  "license": "MIT",
6
  "require": {
7
- "rosell-dk/webp-convert": "^2.0.5",
8
  "rosell-dk/webp-convert-cloud-service": "^2.0.0",
9
  "rosell-dk/dom-util-for-webp": "^0.3.0"
10
  },
4
  "type": "project",
5
  "license": "MIT",
6
  "require": {
7
+ "rosell-dk/webp-convert": "^2.1.0",
8
  "rosell-dk/webp-convert-cloud-service": "^2.0.0",
9
  "rosell-dk/dom-util-for-webp": "^0.3.0"
10
  },
composer.lock CHANGED
@@ -118,16 +118,16 @@
118
  },
119
  {
120
  "name": "rosell-dk/webp-convert",
121
- "version": "2.0.5",
122
  "source": {
123
  "type": "git",
124
  "url": "https://github.com/rosell-dk/webp-convert.git",
125
- "reference": "5d69bbb048334badffca2983511800604d650da3"
126
  },
127
  "dist": {
128
  "type": "zip",
129
- "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/5d69bbb048334badffca2983511800604d650da3",
130
- "reference": "5d69bbb048334badffca2983511800604d650da3",
131
  "shasum": ""
132
  },
133
  "require": {
@@ -190,7 +190,7 @@
190
  "png",
191
  "png2webp"
192
  ],
193
- "time": "2019-06-18T12:27:33+00:00"
194
  },
195
  {
196
  "name": "rosell-dk/webp-convert-cloud-service",
118
  },
119
  {
120
  "name": "rosell-dk/webp-convert",
121
+ "version": "2.1.0",
122
  "source": {
123
  "type": "git",
124
  "url": "https://github.com/rosell-dk/webp-convert.git",
125
+ "reference": "b142cfc2b2b8a1930b3b394c40f0923871ef2abd"
126
  },
127
  "dist": {
128
  "type": "zip",
129
+ "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/b142cfc2b2b8a1930b3b394c40f0923871ef2abd",
130
+ "reference": "b142cfc2b2b8a1930b3b394c40f0923871ef2abd",
131
  "shasum": ""
132
  },
133
  "require": {
190
  "png",
191
  "png2webp"
192
  ],
193
+ "time": "2019-06-20T12:12:13+00:00"
194
  },
195
  {
196
  "name": "rosell-dk/webp-convert-cloud-service",
lib/classes/AlterHtmlInit.php CHANGED
@@ -110,7 +110,7 @@ class AlterHtmlInit
110
 
111
  /*
112
  TODO:
113
- check out these hooks (used by Jecpack, in class.photon.php)
114
 
115
  // Images in post content and galleries
116
  add_filter( 'the_content', array( __CLASS__, 'filter_the_content' ), 999999 );
110
 
111
  /*
112
  TODO:
113
+ check out these hooks (used by Jetpack, in class.photon.php)
114
 
115
  // Images in post content and galleries
116
  add_filter( 'the_content', array( __CLASS__, 'filter_the_content' ), 999999 );
lib/classes/Convert.php CHANGED
@@ -29,6 +29,8 @@ class Convert
29
 
30
  public static function convertFile($source, $config = null, $convertOptions = null, $converter = null)
31
  {
 
 
32
  if (is_null($config)) {
33
  $config = Config::loadConfigAndFix();
34
  }
@@ -41,6 +43,7 @@ class Convert
41
  }*/
42
 
43
  $destination = self::getDestination($source, $config);
 
44
 
45
  $logDir = Paths::getWebPExpressContentDirAbs() . '/log';
46
 
@@ -56,6 +59,7 @@ class Convert
56
 
57
  public static function findSource($destination, &$config = null)
58
  {
 
59
  if (is_null($config)) {
60
  $config = Config::loadConfigAndFix();
61
  }
29
 
30
  public static function convertFile($source, $config = null, $convertOptions = null, $converter = null)
31
  {
32
+ $source = ConvertHelperIndependent::sanitizeAbsFilePath($source);
33
+
34
  if (is_null($config)) {
35
  $config = Config::loadConfigAndFix();
36
  }
43
  }*/
44
 
45
  $destination = self::getDestination($source, $config);
46
+ $destination = ConvertHelperIndependent::sanitizeAbsFilePath($destination);
47
 
48
  $logDir = Paths::getWebPExpressContentDirAbs() . '/log';
49
 
59
 
60
  public static function findSource($destination, &$config = null)
61
  {
62
+ $destination = ConvertHelperIndependent::sanitizeAbsFilePath($destination);
63
  if (is_null($config)) {
64
  $config = Config::loadConfigAndFix();
65
  }
lib/classes/ConvertHelperIndependent.php CHANGED
@@ -72,7 +72,7 @@ class ConvertHelperIndependent
72
  /**
73
  * Get destination from source (and some configurations)
74
  */
75
- public static function getDestination($source, $destinationFolder, $destinationExt, $webExpressContentDirAbs, $uploadDirAbs)
76
  {
77
  if (self::storeMingledOrNot($source, $destinationFolder, $uploadDirAbs)) {
78
  if ($destinationExt == 'append') {
@@ -102,6 +102,43 @@ class ConvertHelperIndependent
102
  }
103
  }
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  /**
106
  * Find source corresponding to destination, separate
107
  * We can rely on destinationExt being "append" for separate
@@ -132,6 +169,7 @@ class ConvertHelperIndependent
132
  $source = $sourceRel;
133
  $source = preg_replace('/\\.(webp)$/', '', $source);
134
  }
 
135
  if (!@file_exists($source)) {
136
  return false;
137
  }
@@ -234,7 +272,7 @@ APACHE
234
 
235
  $text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
236
 
237
- $text = 'WebP Express 0.14.4. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
238
 
239
  $logFile = self::getLogFilename($source, $logDir);
240
 
72
  /**
73
  * Get destination from source (and some configurations)
74
  */
75
+ private static function getDestinationUnsanitized($source, $destinationFolder, $destinationExt, $webExpressContentDirAbs, $uploadDirAbs)
76
  {
77
  if (self::storeMingledOrNot($source, $destinationFolder, $uploadDirAbs)) {
78
  if ($destinationExt == 'append') {
102
  }
103
  }
104
 
105
+ /**
106
+ * Sanitize absolute file path.
107
+ *
108
+ * Make sure that file path is not a stream wrapper.
109
+ * This protects against Phar Deserialization and possibly other nasty tricks
110
+ * https://blog.ripstech.com/2018/new-php-exploitation-technique/
111
+ * https://www.php.net/manual/en/wrappers.phar.php
112
+ *
113
+ * We also prevent directory traversal, as we do not expect any traversal in our absolute paths.
114
+ *
115
+ * @param string $absFilePath
116
+ * @return string sanitized file path
117
+ */
118
+ public static function sanitizeAbsFilePath($absFilePath) {
119
+ // Remove NUL characters (https://st-g.de/2011/04/doing-filename-checks-securely-in-PHP)
120
+ $absFilePath = str_replace(chr(0), '', $absFilePath);
121
+
122
+ // remove "../"
123
+ $absFilePath = preg_replace('#\.\.\/#', '', $absFilePath);
124
+
125
+ // remove "phar://", "php://" and the like from the beginning of the string
126
+ // important that this is done after removing "../" - otherwise one could send "../phar://"
127
+ $absFilePath = preg_replace('#^\\w+://#', '', $absFilePath);
128
+
129
+ return $absFilePath;
130
+ }
131
+
132
+ /**
133
+ * Get destination from source (and some configurations)
134
+ */
135
+ public static function getDestination($source, $destinationFolder, $destinationExt, $webExpressContentDirAbs, $uploadDirAbs)
136
+ {
137
+ return self::sanitizeAbsFilePath(
138
+ self::getDestinationUnsanitized($source, $destinationFolder, $destinationExt, $webExpressContentDirAbs, $uploadDirAbs)
139
+ );
140
+ }
141
+
142
  /**
143
  * Find source corresponding to destination, separate
144
  * We can rely on destinationExt being "append" for separate
169
  $source = $sourceRel;
170
  $source = preg_replace('/\\.(webp)$/', '', $source);
171
  }
172
+ $source = self::sanitizeAbsFilePath($source);
173
  if (!@file_exists($source)) {
174
  return false;
175
  }
272
 
273
  $text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
274
 
275
+ $text = 'WebP Express 0.14.5. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
276
 
277
  $logFile = self::getLogFilename($source, $logDir);
278
 
lib/classes/ConvertersHelper.php CHANGED
@@ -156,7 +156,7 @@ class ConvertersHelper
156
  * Get working and active converters.
157
  *
158
  * @param object $config
159
- * @return array
160
  */
161
  public static function getWorkingAndActiveConverters($config)
162
  {
156
  * Get working and active converters.
157
  *
158
  * @param object $config
159
+ * @return array Array of converter objects
160
  */
161
  public static function getWorkingAndActiveConverters($config)
162
  {
lib/options/enqueue_scripts.php CHANGED
@@ -8,8 +8,8 @@ use \WebPExpress\Paths;
8
  include_once __DIR__ . '/../classes/Config.php';
9
  use \WebPExpress\Config;
10
 
11
- $ver = '1';
12
- $jsDir = 'js/0.14.2';
13
 
14
  if (!function_exists('webp_express_add_inline_script')) {
15
  function webp_express_add_inline_script($id, $script, $position) {
8
  include_once __DIR__ . '/../classes/Config.php';
9
  use \WebPExpress\Config;
10
 
11
+ $ver = '1'; // note: Minimum 1
12
+ $jsDir = 'js/0.14.5';
13
 
14
  if (!function_exists('webp_express_add_inline_script')) {
15
  function webp_express_add_inline_script($id, $script, $position) {
lib/options/js/0.14.2/whitelist_old.js DELETED
@@ -1,189 +0,0 @@
1
- function updateWhitelistInputValue() {
2
- //var val = [];
3
-
4
- document.getElementsByName('whitelist')[0].value = JSON.stringify(window.whitelist);
5
- }
6
-
7
- function openPasswordPopup(i) {
8
- window.currentWhitelistPassword = i;
9
- document.getElementById('whitelist_enter_password').value = '';
10
- document.getElementById('whitelist_hash_password').checked = false;
11
-
12
- var options = '#TB_inline?inlineId=whitelist_enter_password_popup&width=400&height=300';
13
- tb_show("Enter password", options);
14
-
15
- }
16
- function setPassword() {
17
-
18
- var i = window.currentWhitelistPassword;
19
- var password = document.getElementById('whitelist_enter_password').value;
20
- var hashPassword = document.getElementById('whitelist_hash_password').checked;
21
-
22
- //var password = window.prompt('Enter password');
23
-
24
- window.whitelist[i]['password'] = '';
25
- window.whitelist[i]['new_password'] = password;
26
- window.whitelist[i]['hash_new_password'] = hashPassword;
27
-
28
- setWhitelistHTML();
29
- tb_remove();
30
- }
31
-
32
- function setWhitelistHTML() {
33
- var s = '';
34
- s+='<table class="whitelist" id="whitelist_table">';
35
- s+='<tr>';
36
- s+='<th>Site<span id="whitelist_site_helptext2"></span></th>'
37
- s+='<th>Password<span id="password_helptext2"></span></th>'
38
- //s+='<th>Salt<span id="salt_helptext2"></span></th>'
39
- //s+='<th>Limit<span id="whitelist_quota_helptext2"></span></th>'
40
- s+='</tr>';
41
- s=='</th></tr>';
42
- if (window.whitelist) {
43
- for (var i=0; i<window.whitelist.length; i++) {
44
- s+='<tr>';
45
- s+='<td><input type="text" size="15" id="whitelist-site-' + i + '" placeholder="hostname or IP"></input></td>';
46
- //s+='<td><input type="text" size="10" id="whitelist-password-' + i + '"></input></td>';
47
-
48
- s+='<td><a href="javascript:openPasswordPopup(' + i + ')">Click to ' +
49
- ((window.whitelist[i]['password'] || window.whitelist[i]['new_password']) ? 'change' : 'set')
50
- + '</td>';
51
- //s+='<td>' + (window.whitelist[i]['salt'] || '') + '</td>';
52
-
53
- //s+='<td class="quota"><nobr><input type="text" size="3" id="whitelist-quota-' + i + '"></input><i> per hour</i></nobr></td>';
54
- //s+='<td class="buttons"><button type="button" class="button button-secondary" onclick="whitelistRemoveRow(' + i + ')">remove</button></td>';
55
- s+='<td class="remove"><a href="javascript:whitelistRemoveRow(' + i + ')">remove row</a></td>';
56
- s+='</tr>';
57
- }
58
- }
59
- s+='<tr><td colspan="3" class="whitelist-add-site">';
60
- s+='<button type="button" class="button button-secondary" id="whitelist_add" onclick="whitelistAddSite()">+ Add site</button>';
61
- s+='</td></tr>';
62
- s+='</table>';
63
-
64
- document.getElementById('whitelist_div').innerHTML = s;
65
-
66
- if (window.whitelist) {
67
- for (var i=0; i<window.whitelist.length; i++) {
68
- document.getElementById('whitelist-site-' + i).value = window.whitelist[i]['site'];
69
- //document.getElementById('whitelist-password-hashed' + i).value = window.whitelist[i]['password_hashed'];
70
- //document.getElementById('whitelist-quota-' + i).value = window.whitelist[i]['quota'];
71
- }
72
- }
73
- updateWhitelistInputValue();
74
-
75
- document.getElementById('password_helptext2').innerHTML = document.getElementById('password_helptext').innerHTML;
76
- document.getElementById('whitelist_site_helptext2').innerHTML = document.getElementById('whitelist_site_helptext').innerHTML;
77
- //document.getElementById('whitelist_quota_helptext2').innerHTML = document.getElementById('whitelist_quota_helptext').innerHTML;
78
-
79
- }
80
-
81
- function whitelistStartPolling() {
82
-
83
- jQuery.post(window.ajaxurl, {
84
- 'action': 'webpexpress_start_listening',
85
- }, function(response) {
86
- window.whitelistTid = window.setInterval(function() {
87
- jQuery.post(window.ajaxurl, {
88
- 'action': 'webpexpress_get_request',
89
- }, function(response) {
90
- if (response && (response.substr(0,1) == '{')) {
91
- var r = JSON.parse(response);
92
- window.webpexpress_incoming_request = r;
93
- //console.log(r);
94
- window.clearInterval(window.whitelistTid);
95
- closeDasPopup();
96
-
97
- // Show request
98
- openDasPopup('whitelist_accept_request', 300, 200);
99
-
100
- var s = '';
101
- s += 'Website: ' + r['website'] + '<br>';
102
- s += 'IP: ' + r['ip'] + '<br>';
103
-
104
- document.getElementById('request_details').innerHTML = s;
105
- } else {
106
- console.log('Got this from the server: ' + response);
107
- }
108
- }
109
- );
110
- }, 2000);
111
- }
112
- );
113
- }
114
-
115
- function whitelistCancelListening() {
116
- jQuery.post(window.ajaxurl, {
117
- 'action': 'webpexpress_stop_listening',
118
- }, function(response) {}
119
- );
120
- closeDasPopup();
121
- }
122
-
123
- function whitelistAcceptRequest() {
124
- whitelistCancelListening();
125
-
126
- var r = window.webpexpress_incoming_request;
127
- window.whitelist.push({
128
- id: r['website'],
129
- new_password: r['password'],
130
- // new_password: '',
131
- //quota: 60
132
- });
133
- setWhitelistHTML();
134
- }
135
-
136
- function whitelistDenyRequest() {
137
- whitelistCancelListening();
138
- }
139
-
140
- function whitelistAddSite() {
141
- whitelistStartPolling();
142
- openDasPopup('whitelist_listen_popup', 400, 300);
143
- }
144
-
145
- function whitelistAdd() {
146
- }
147
-
148
- function whitelistRemoveRow(i) {
149
- window.whitelist.splice(i, 1);
150
- setWhitelistHTML();
151
- }
152
-
153
- document.addEventListener('DOMContentLoaded', function() {
154
-
155
- window.setInterval(function() {
156
- var el = document.getElementById('animated_dots');
157
- if (el.innerText == '....') {
158
- el.innerText = '';
159
- } else {
160
- el.innerText += '.';
161
- }
162
- }, 500);
163
-
164
- setWhitelistHTML();
165
-
166
- document.getElementById('whitelist_div').addEventListener("input", function(e){
167
- console.log(e);
168
- for (var i=0; i<window.whitelist.length; i++) {
169
- window.whitelist[i]['site'] = document.getElementById('whitelist-site-' + i).value;
170
- //window.whitelist[i]['password_hashed'] = document.getElementById('whitelist-password-hashed' + i).value;
171
- //window.whitelist[i]['quota'] = document.getElementById('whitelist-quota-' + i).value;
172
- }
173
- updateWhitelistInputValue();
174
- });
175
-
176
- document.getElementById('whitelist_table').addEventListener("change", function(e){
177
- // Clean up
178
- for (var i=0; i<window.whitelist.length; i++) {
179
- var s = document.getElementById('whitelist-site-' + i).value;
180
- var s2 = s.replace(/^https?:\/\//, '');
181
- if (s2 != s) {
182
- e.target.value = s2;
183
- window.whitelist[i][0] = s2;
184
- updateWhitelistInputValue();
185
- }
186
- }
187
- });
188
-
189
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/options/js/{0.14.2 → 0.14.5}/authorized_sites_bak.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/bulk-convert.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/converters.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/das-popup.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/image-comparison-slider.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/page.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/purge-cache.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/sortable.min.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/test-convert.js RENAMED
File without changes
lib/options/js/{0.14.2 → 0.14.5}/whitelist.js RENAMED
@@ -87,6 +87,14 @@ function whitelistRemoveEntry(i) {
87
  window.whitelist.splice(i, 1);
88
  whitelistSetHTML();
89
  }
 
 
 
 
 
 
 
 
90
  function whitelistSetHTML() {
91
  updateWhitelistInputValue();
92
  var s = '';
@@ -96,7 +104,7 @@ function whitelistSetHTML() {
96
  s+='<ul>';
97
  for (var i=0; i<window.whitelist.length; i++) {
98
  s+='<li>';
99
- s+=window.whitelist[i]['label'];
100
  s+='<div class="whitelist-links">'
101
  s+='<a href="javascript:whitelistEditEntry(' + i + ')">edit</a>';
102
  s+='<a href="javascript:whitelistRemoveEntry(' + i + ')">remove</a>';
87
  window.whitelist.splice(i, 1);
88
  whitelistSetHTML();
89
  }
90
+
91
+ function whitelistEncodeHTMLEntities(s)
92
+ {
93
+ return s.replace(/./gm, function(s) {
94
+ return "&#" + s.charCodeAt(0) + ";";
95
+ });
96
+ }
97
+
98
  function whitelistSetHTML() {
99
  updateWhitelistInputValue();
100
  var s = '';
104
  s+='<ul>';
105
  for (var i=0; i<window.whitelist.length; i++) {
106
  s+='<li>';
107
+ s+= whitelistEncodeHTMLEntities(window.whitelist[i]['label']);
108
  s+='<div class="whitelist-links">'
109
  s+='<a href="javascript:whitelistEditEntry(' + i + ')">edit</a>';
110
  s+='<a href="javascript:whitelistRemoveEntry(' + i + ')">remove</a>';
lib/options/options/conversion-options/jpeg.inc CHANGED
@@ -64,7 +64,7 @@ png
64
  '<p>If you select the "Same as the jpeg" option, WebP Express will try to determine the quality of ' .
65
  'the jpeg and use that for the webp - unless the quality is higher than the limit entered, in which ' .
66
  'case the limit is used.</p>' .
67
- '<p>Ouality detection requires imagick or gmagick (not neccessarily compiled with webp). ' .
68
  'In case quality detection is not available, the fallback quality is used.</p>' .
69
  (
70
  $canDetectQuality ?
@@ -110,7 +110,7 @@ png
110
  echo helpIcon(
111
  'Fallback quality in case quality detection is not available or should fail for some reason (which has yet to be seen). ' .
112
  (
113
- !$canDetectQuality ?
114
  'You have quality detection working, btw, so this setting will probably never be used' :
115
  '<i>You do not have quality detection working, btw</i> - which means that all conversions will have the fixed quality entered here'
116
  )
64
  '<p>If you select the "Same as the jpeg" option, WebP Express will try to determine the quality of ' .
65
  'the jpeg and use that for the webp - unless the quality is higher than the limit entered, in which ' .
66
  'case the limit is used.</p>' .
67
+ '<p>Ouality detection requires imagick, imagemagick or gmagick (not neccessarily compiled with webp). ' .
68
  'In case quality detection is not available, the fallback quality is used.</p>' .
69
  (
70
  $canDetectQuality ?
110
  echo helpIcon(
111
  'Fallback quality in case quality detection is not available or should fail for some reason (which has yet to be seen). ' .
112
  (
113
+ $canDetectQuality ?
114
  'You have quality detection working, btw, so this setting will probably never be used' :
115
  '<i>You do not have quality detection working, btw</i> - which means that all conversions will have the fixed quality entered here'
116
  )
lib/options/options/conversion-options/png.inc CHANGED
@@ -41,8 +41,9 @@
41
  <input type="text" size=3 name="png-quality" value="<?php echo $config['png-quality'] ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
42
  <?php
43
  echo helpIcon(
44
- 'You probably want to set this value a bit higher than the quality for JPEGs. PNGs are often used for icons and graphics, ' .
45
- 'which perhaps demands a bit more quality than photos, which jpegs often are used for.'
 
46
  );
47
  ?>
48
  <label style="margin-left:10px">
41
  <input type="text" size=3 name="png-quality" value="<?php echo $config['png-quality'] ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
42
  <?php
43
  echo helpIcon(
44
+ '<p>You probably want to set this value a bit higher than the quality for JPEGs. PNGs are often used for icons and graphics, ' .
45
+ 'which perhaps demands a bit more quality than photos, which jpegs often are used for.</p>' .
46
+ '<p>Note that there is no "Same as PNG" option available here as PNGs are lossless</p>'
47
  );
48
  ?>
49
  <label style="margin-left:10px">
lib/options/options/general/image-types.inc CHANGED
@@ -18,10 +18,8 @@ switch ($config['operation-mode']) {
18
  }
19
  if ($config['operation-mode'] == 'no-conversion') {
20
  echo helpIcon('<p>Select which types of images you would like to redirect and/or have altered in the HTML</p>');
21
-
22
  } else {
23
- echo helpIcon('<p>Beware that the Gd conversion method cannot handle transparency for PNGs. PNG conversions havent been tested much yet. Please report any problems with PNG images <a target="_blank" href="https://github.com/rosell-dk/webp-convert/issues/42">here</a></p><p>The term "send" means an internal redirect on the server (not to be confused with an external redirect, such as a 301 or 302 response)</p>');
24
-
25
  }
26
  echo '</th><td>';
27
 
18
  }
19
  if ($config['operation-mode'] == 'no-conversion') {
20
  echo helpIcon('<p>Select which types of images you would like to redirect and/or have altered in the HTML</p>');
 
21
  } else {
22
+ echo helpIcon('<p>Beware that some has reported problems with Gd and PNG, but it has not been pinned down when it happens. It is probably on older versions of Gd. Please report any problems with Gd!</p>');
 
23
  }
24
  echo '</th><td>';
25
 
lib/options/page-messages.php CHANGED
@@ -17,7 +17,6 @@ use \WebPExpress\State;
17
  //echo '<pre>' . print_r(BulkConvert::getList($config), true) . "</pre>";
18
  //echo '<pre>' . print_r(BulkConvert::convertFile('/var/www/webp-express-tests/we0/wordpress/uploads-moved/space in name.jpg'), true) . "</pre>";
19
 
20
-
21
  if ((!State::getState('configured', false))) {
22
  include __DIR__ . "/page-welcome.php";
23
  }
@@ -236,11 +235,13 @@ if ($config['image-types'] == 3) {
236
  $workingConverters = ConvertersHelper::getWorkingAndActiveConverters($config);
237
  if (count($workingConverters) == 1) {
238
  if (ConvertersHelper::getConverterId($workingConverters[0]) == 'gd') {
239
- Messenger::printMessage(
240
- 'warning',
241
- 'You have enabled PNGs, but configured Gd to skip PNGs, and Gd is your only active working converter. ' .
242
- 'This is a bad combination!'
243
- );
 
 
244
  }
245
  }
246
  }
17
  //echo '<pre>' . print_r(BulkConvert::getList($config), true) . "</pre>";
18
  //echo '<pre>' . print_r(BulkConvert::convertFile('/var/www/webp-express-tests/we0/wordpress/uploads-moved/space in name.jpg'), true) . "</pre>";
19
 
 
20
  if ((!State::getState('configured', false))) {
21
  include __DIR__ . "/page-welcome.php";
22
  }
235
  $workingConverters = ConvertersHelper::getWorkingAndActiveConverters($config);
236
  if (count($workingConverters) == 1) {
237
  if (ConvertersHelper::getConverterId($workingConverters[0]) == 'gd') {
238
+ if (isset($workingConverters[0]['options']['skip-pngs']) && $workingConverters[0]['options']['skip-pngs']) {
239
+ Messenger::printMessage(
240
+ 'warning',
241
+ 'You have enabled PNGs, but configured Gd to skip PNGs, and Gd is your only active working converter. ' .
242
+ 'This is a bad combination!'
243
+ );
244
+ }
245
  }
246
  }
247
  }
lib/options/submit.php CHANGED
@@ -10,7 +10,6 @@ use \WebPExpress\HTAccess;
10
  use \WebPExpress\Messenger;
11
  use \WebPExpress\Paths;
12
 
13
-
14
  check_admin_referer('webpexpress-save-settings-nonce');
15
 
16
  DismissableMessages::dismissMessage('0.14.0/say-hello-to-vips');
@@ -133,9 +132,18 @@ if ($_POST['operation-mode'] != 'no-conversion') {
133
  // Web Service
134
  // -------------
135
 
 
 
 
 
 
 
 
 
 
136
  $config['web-service'] = [
137
  'enabled' => isset($_POST['web-service-enabled']),
138
- 'whitelist' => json_decode(wp_unslash($_POST['whitelist']), true)
139
  ];
140
 
141
  // Set existing api keys in web service (we removed them from the json array, for security purposes)
10
  use \WebPExpress\Messenger;
11
  use \WebPExpress\Paths;
12
 
 
13
  check_admin_referer('webpexpress-save-settings-nonce');
14
 
15
  DismissableMessages::dismissMessage('0.14.0/say-hello-to-vips');
132
  // Web Service
133
  // -------------
134
 
135
+ $whitelistPosted = json_decode(wp_unslash($_POST['whitelist']), true);
136
+
137
+ // Sanitize whitelist
138
+ foreach ($whitelistPosted as &$whitelist) {
139
+ $whitelist['label'] = sanitize_text_field($whitelist['label']);
140
+ $whitelist['ip'] = sanitize_text_field($whitelist['ip']);
141
+ $whitelist['api-key'] = sanitize_text_field($whitelist['api-key']);
142
+ }
143
+
144
  $config['web-service'] = [
145
  'enabled' => isset($_POST['web-service-enabled']),
146
+ 'whitelist' => $whitelistPosted
147
  ];
148
 
149
  // Set existing api keys in web service (we removed them from the json array, for security purposes)
vendor/composer/installed.json CHANGED
@@ -115,17 +115,17 @@
115
  },
116
  {
117
  "name": "rosell-dk/webp-convert",
118
- "version": "2.0.5",
119
- "version_normalized": "2.0.5.0",
120
  "source": {
121
  "type": "git",
122
  "url": "https://github.com/rosell-dk/webp-convert.git",
123
- "reference": "5d69bbb048334badffca2983511800604d650da3"
124
  },
125
  "dist": {
126
  "type": "zip",
127
- "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/5d69bbb048334badffca2983511800604d650da3",
128
- "reference": "5d69bbb048334badffca2983511800604d650da3",
129
  "shasum": ""
130
  },
131
  "require": {
@@ -143,7 +143,7 @@
143
  "ext-vips": "to use Vips extension for converting.",
144
  "php-stan/php-stan": "Suggested for dev, in order to analyse code before committing"
145
  },
146
- "time": "2019-06-18T12:27:33+00:00",
147
  "type": "library",
148
  "extra": {
149
  "scripts-descriptions": {
115
  },
116
  {
117
  "name": "rosell-dk/webp-convert",
118
+ "version": "2.1.0",
119
+ "version_normalized": "2.1.0.0",
120
  "source": {
121
  "type": "git",
122
  "url": "https://github.com/rosell-dk/webp-convert.git",
123
+ "reference": "b142cfc2b2b8a1930b3b394c40f0923871ef2abd"
124
  },
125
  "dist": {
126
  "type": "zip",
127
+ "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/b142cfc2b2b8a1930b3b394c40f0923871ef2abd",
128
+ "reference": "b142cfc2b2b8a1930b3b394c40f0923871ef2abd",
129
  "shasum": ""
130
  },
131
  "require": {
143
  "ext-vips": "to use Vips extension for converting.",
144
  "php-stan/php-stan": "Suggested for dev, in order to analyse code before committing"
145
  },
146
+ "time": "2019-06-20T12:12:13+00:00",
147
  "type": "library",
148
  "extra": {
149
  "scripts-descriptions": {
vendor/rosell-dk/webp-convert/build-scripts/PHPMerger.php CHANGED
@@ -28,16 +28,20 @@ class PhpMerger
28
 
29
  // load dirs in defined order. No recursion.
30
  foreach ($def['dirs'] as $dir) {
31
- $dirAbs = __DIR__ . '/' . $def['root'] . '/' . $dir;
 
 
 
 
32
  $files = glob($dirAbs . '/*.php');
33
  foreach ($files as $file) {
34
  // only require files that begins with uppercase (A-Z)
35
  if (preg_match('/\/[A-Z][a-zA-Z]*\.php/', $file)) {
36
- $file = str_replace(__DIR__ . '/' . $def['root'], '', $file);
37
  $file = str_replace('./', '', $file);
38
 
39
  //echo $file . "\n";
40
- self::add_to_queue($def['root'] . $file);
41
  }
42
  }
43
  }
28
 
29
  // load dirs in defined order. No recursion.
30
  foreach ($def['dirs'] as $dir) {
31
+ $dirAbs = __DIR__ . '/' . $def['dir-root'] . '/' . $dir;
32
+ if (!is_dir($dirAbs)) {
33
+ echo 'Dir not found: ' . $dirAbs;
34
+ return false;
35
+ }
36
  $files = glob($dirAbs . '/*.php');
37
  foreach ($files as $file) {
38
  // only require files that begins with uppercase (A-Z)
39
  if (preg_match('/\/[A-Z][a-zA-Z]*\.php/', $file)) {
40
+ $file = str_replace(__DIR__ . '/' . $def['dir-root'], '', $file);
41
  $file = str_replace('./', '', $file);
42
 
43
  //echo $file . "\n";
44
+ self::add_to_queue($def['dir-root'] . $file);
45
  }
46
  }
47
  }
vendor/rosell-dk/webp-convert/build-scripts/build.php CHANGED
@@ -16,8 +16,15 @@ $filesInWod1 = [
16
  '/Serve/ServeConvertedWebP.php',
17
  '/Serve/ServeConvertedWebPWithErrorHandling.php',
18
  '/Serve/ServeFile.php',
 
 
 
 
 
 
19
  '/Serve/Header.php',
20
- '/WebPConvert.php'
 
21
  ];
22
 
23
  // Build "webp-on-demand-1.php" (for non-composer projects)
@@ -29,8 +36,11 @@ $success = PhpMerger::generate([
29
  [
30
  'root' => '../src/',
31
  'files' => $filesInWod1,
 
32
  'dirs' => [
33
  // dirs will be required in specified order. There is no recursion, so you need to specify subdirs as well.
 
 
34
  //'.',
35
  ]
36
  ]
@@ -39,11 +49,11 @@ $success = PhpMerger::generate([
39
  if (!$success) {
40
  exit(255);
41
  }
42
-
43
  $jobsEverything = [
44
  [
45
  'root' => '../src/',
46
-
47
  'files' => [
48
  // put base classes here
49
  'Options/Option.php',
@@ -63,8 +73,9 @@ $jobsEverything = [
63
  'Options',
64
  'Convert/Converters/BaseTraits',
65
  'Convert/Converters/ConverterTraits',
66
- 'Convert/BaseConverters',
67
  'Convert/Converters',
 
 
68
  'Convert/Exceptions',
69
  'Convert/Exceptions/ConversionFailed',
70
  'Convert/Exceptions/ConversionFailed/ConverterNotOperational',
@@ -73,6 +84,7 @@ $jobsEverything = [
73
  'Convert/Helpers',
74
  'Convert',
75
  'Exceptions',
 
76
  'Helpers',
77
  'Loggers',
78
  'Serve',
@@ -83,6 +95,7 @@ $jobsEverything = [
83
  ],
84
  [
85
  'root' => '../vendor/rosell-dk/image-mime-type-guesser/src/',
 
86
 
87
  'files' => [
88
  // put base classes here
@@ -111,6 +124,9 @@ if (!$success) {
111
  $jobsWod2 = $jobsEverything;
112
  $jobsWod2[0]['exclude'] = $filesInWod1;
113
 
 
 
 
114
  // Build "webp-on-demand-2.inc"
115
  // It must contain everything EXCEPT those classes that were included in 'webp-on-demand-1.inc'
116
  $success = PhpMerger::generate([
16
  '/Serve/ServeConvertedWebP.php',
17
  '/Serve/ServeConvertedWebPWithErrorHandling.php',
18
  '/Serve/ServeFile.php',
19
+ '/Exceptions/WebPConvertException.php',
20
+ '/Exceptions/InvalidInputException.php',
21
+ '/Exceptions/InvalidInput/InvalidImageTypeException.php',
22
+ '/Exceptions/InvalidInput/TargetNotFoundException.php',
23
+ '/Helpers/PathChecker.php',
24
+ '/Helpers/InputValidator.php',
25
  '/Serve/Header.php',
26
+ '/WebPConvert.php',
27
+ //'../vendor/rosell-dk/image-mime-type-guesser/src/Detectors/AbstractDetector.php',
28
  ];
29
 
30
  // Build "webp-on-demand-1.php" (for non-composer projects)
36
  [
37
  'root' => '../src/',
38
  'files' => $filesInWod1,
39
+ 'dir-root' => '..',
40
  'dirs' => [
41
  // dirs will be required in specified order. There is no recursion, so you need to specify subdirs as well.
42
+ 'vendor/rosell-dk/image-mime-type-guesser/src',
43
+ 'vendor/rosell-dk/image-mime-type-guesser/src/Detectors',
44
  //'.',
45
  ]
46
  ]
49
  if (!$success) {
50
  exit(255);
51
  }
52
+ //exit(0);
53
  $jobsEverything = [
54
  [
55
  'root' => '../src/',
56
+ 'dir-root' => '../src',
57
  'files' => [
58
  // put base classes here
59
  'Options/Option.php',
73
  'Options',
74
  'Convert/Converters/BaseTraits',
75
  'Convert/Converters/ConverterTraits',
 
76
  'Convert/Converters',
77
+ 'Convert/Converters/BaseTraits',
78
+ 'Convert/Converters/ConverterTraits',
79
  'Convert/Exceptions',
80
  'Convert/Exceptions/ConversionFailed',
81
  'Convert/Exceptions/ConversionFailed/ConverterNotOperational',
84
  'Convert/Helpers',
85
  'Convert',
86
  'Exceptions',
87
+ 'Exceptions/InvalidInput',
88
  'Helpers',
89
  'Loggers',
90
  'Serve',
95
  ],
96
  [
97
  'root' => '../vendor/rosell-dk/image-mime-type-guesser/src/',
98
+ 'dir-root' => '../vendor/rosell-dk/image-mime-type-guesser/src',
99
 
100
  'files' => [
101
  // put base classes here
124
  $jobsWod2 = $jobsEverything;
125
  $jobsWod2[0]['exclude'] = $filesInWod1;
126
 
127
+ // remove second job (ImageMimeTypeGuesser is included in wod-1)
128
+ unset($jobsWod2[1]);
129
+
130
  // Build "webp-on-demand-2.inc"
131
  // It must contain everything EXCEPT those classes that were included in 'webp-on-demand-1.inc'
132
  $success = PhpMerger::generate([
vendor/rosell-dk/webp-convert/build-tests-webp-convert/WebPConvertBuildTest.php CHANGED
@@ -15,11 +15,21 @@ use PHPUnit\Framework\TestCase;
15
  class WebPConvertBuildTest extends TestCase
16
  {
17
 
 
 
 
 
 
 
 
 
 
 
18
  public function testWebPConvertBuildNotCompletelyBroken()
19
  {
20
  require __DIR__ . '/../src-build/webp-convert.inc';
21
 
22
- $source = __DIR__ . '/../tests/images/png-without-extension';
23
  $this->assertTrue(file_exists($source));
24
 
25
  ob_start();
15
  class WebPConvertBuildTest extends TestCase
16
  {
17
 
18
+ public static function getImageFolder()
19
+ {
20
+ return realpath(__DIR__ . '/../tests/images');
21
+ }
22
+
23
+ public static function getImagePath($image)
24
+ {
25
+ return self::getImageFolder() . '/' . $image;
26
+ }
27
+
28
  public function testWebPConvertBuildNotCompletelyBroken()
29
  {
30
  require __DIR__ . '/../src-build/webp-convert.inc';
31
 
32
+ $source = self::getImagePath('png-without-extension');
33
  $this->assertTrue(file_exists($source));
34
 
35
  ob_start();
vendor/rosell-dk/webp-convert/build-tests-wod/WodBuildTest.php CHANGED
@@ -14,6 +14,17 @@ class WodBuildTest extends TestCase
14
 
15
  private static $buildDir = __DIR__ . '/../src-build';
16
 
 
 
 
 
 
 
 
 
 
 
 
17
  public function autoloadingDisallowed($class) {
18
  throw new \Exception('no autoloading expected! ' . $class);
19
  }
@@ -38,7 +49,7 @@ class WodBuildTest extends TestCase
38
 
39
  spl_autoload_register([self::class, 'autoloaderLoad'], true, true);
40
 
41
- $source = __DIR__ . '/../tests/images/png-without-extension';
42
  $this->assertTrue(file_exists($source));
43
 
44
  ob_start();
@@ -101,7 +112,7 @@ class WodBuildTest extends TestCase
101
  require_once $wod1;
102
 
103
 
104
- $source = __DIR__ . '/../tests/images/png-without-extension';
105
  $this->assertTrue(file_exists($source));
106
 
107
  /*
14
 
15
  private static $buildDir = __DIR__ . '/../src-build';
16
 
17
+ public static function getImageFolder()
18
+ {
19
+ return realpath(__DIR__ . '/../tests/images');
20
+ }
21
+
22
+ public static function getImagePath($image)
23
+ {
24
+ return self::getImageFolder() . '/' . $image;
25
+ }
26
+
27
+
28
  public function autoloadingDisallowed($class) {
29
  throw new \Exception('no autoloading expected! ' . $class);
30
  }
49
 
50
  spl_autoload_register([self::class, 'autoloaderLoad'], true, true);
51
 
52
+ $source = self::getImagePath('png-without-extension');
53
  $this->assertTrue(file_exists($source));
54
 
55
  ob_start();
112
  require_once $wod1;
113
 
114
 
115
+ $source = self::getImagePath('png-without-extension');
116
  $this->assertTrue(file_exists($source));
117
 
118
  /*
vendor/rosell-dk/webp-convert/src-build/webp-convert.inc CHANGED
@@ -142,18 +142,17 @@ class Option
142
 
143
  namespace WebPConvert\Convert\Converters;
144
 
 
 
145
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
146
- use WebPConvert\Exceptions\WebPConvertException;
147
  use WebPConvert\Convert\Converters\BaseTraits\AutoQualityTrait;
148
  use WebPConvert\Convert\Converters\BaseTraits\DestinationPreparationTrait;
149
  use WebPConvert\Convert\Converters\BaseTraits\LoggerTrait;
150
  use WebPConvert\Convert\Converters\BaseTraits\OptionsTrait;
151
- use WebPConvert\Convert\Converters\BaseTraits\SourceValidationTrait;
152
  use WebPConvert\Convert\Converters\BaseTraits\WarningLoggerTrait;
 
153
  use WebPConvert\Loggers\BaseLogger;
154
 
155
- use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
156
-
157
  /**
158
  * Base for all converter classes.
159
  *
@@ -167,7 +166,6 @@ abstract class AbstractConverter
167
  use OptionsTrait;
168
  use WarningLoggerTrait;
169
  use DestinationPreparationTrait;
170
- use SourceValidationTrait;
171
  use LoggerTrait;
172
 
173
  /**
@@ -205,9 +203,6 @@ abstract class AbstractConverter
205
  /** @var string Where to save the webp (complete path) */
206
  protected $destination;
207
 
208
- /** @var string|false|null Where to save the webp (complete path) */
209
- private $sourceMimeType;
210
-
211
  /**
212
  * Check basis operationality
213
  *
@@ -250,6 +245,8 @@ abstract class AbstractConverter
250
  */
251
  public function __construct($source, $destination, $options = [], $logger = null)
252
  {
 
 
253
  $this->source = $source;
254
  $this->destination = $destination;
255
 
@@ -257,7 +254,7 @@ abstract class AbstractConverter
257
  $this->setProvidedOptions($options);
258
 
259
  if (!isset($this->options['_skip_input_check'])) {
260
- $this->log('WebP Convert 2.0.0', 'italic');
261
  $this->logLn(' ignited.');
262
  $this->logLn('- PHP version: ' . phpversion());
263
  if (isset($_SERVER['SERVER_SOFTWARE'])) {
@@ -266,9 +263,6 @@ abstract class AbstractConverter
266
  $this->logLn('');
267
  $this->logLn(self::getConverterDisplayName() . ' converter ignited');
268
  }
269
-
270
- $this->checkSourceExists();
271
- $this->checkSourceMimeType();
272
  }
273
 
274
  /**
@@ -376,10 +370,6 @@ abstract class AbstractConverter
376
  $this->removeExistingDestinationIfExists();
377
 
378
  if (!isset($this->options['_skip_input_check'])) {
379
- // Run basic input validations (if source exists and if file extension is valid)
380
- $this->checkSourceExists();
381
- $this->checkSourceMimeType();
382
-
383
  // Check that a file can be written to destination
384
  $this->checkDestinationWritable();
385
  }
@@ -517,12 +507,7 @@ abstract class AbstractConverter
517
  */
518
  public function getMimeTypeOfSource()
519
  {
520
- if (!isset($this->sourceMimeType)) {
521
- // PS: Scrutinizer complains that ImageMimeTypeGuesser::lenientGuess could also return a boolean
522
- // but this is not true! - it returns string|false|null, just as this method does.
523
- $this->sourceMimeType = ImageMimeTypeGuesser::lenientGuess($this->source);
524
- }
525
- return $this->sourceMimeType;
526
  }
527
  }
528
 
@@ -1816,71 +1801,6 @@ trait OptionsTrait
1816
 
1817
  namespace WebPConvert\Convert\Converters\BaseTraits;
1818
 
1819
- use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\TargetNotFoundException;
1820
- use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\InvalidImageTypeException;
1821
-
1822
- /**
1823
- * Trait for handling options
1824
- *
1825
- * This trait is currently only used in the AbstractConverter class. It has been extracted into a
1826
- * trait in order to bundle the methods concerning options.
1827
- *
1828
- * @package WebPConvert
1829
- * @author Bjørn Rosell <it@rosell.dk>
1830
- * @since Class available since Release 2.0.0
1831
- */
1832
- trait SourceValidationTrait
1833
- {
1834
-
1835
- abstract protected function getMimeTypeOfSource();
1836
- abstract public function getSource();
1837
-
1838
- /** @var array Array of allowed mime types for source. */
1839
- public static $allowedMimeTypes = ['image/jpeg', 'image/png'];
1840
-
1841
- /**
1842
- * Check that source file exists.
1843
- *
1844
- * Note: As the input validations are only run one time in a stack,
1845
- * this method is not overridable
1846
- *
1847
- * @throws TargetNotFoundException
1848
- * @return void
1849
- */
1850
- private function checkSourceExists()
1851
- {
1852
- // Check if source exists
1853
- if (!@file_exists($this->getSource())) {
1854
- throw new TargetNotFoundException('File or directory not found: ' . $this->getSource());
1855
- }
1856
- }
1857
-
1858
- /**
1859
- * Check that source has a valid mime type.
1860
- *
1861
- * Note: As the input validations are only run one time in a stack,
1862
- * this method is not overridable
1863
- *
1864
- * @throws InvalidImageTypeException If mime type could not be detected or is unsupported
1865
- * @return void
1866
- */
1867
- private function checkSourceMimeType()
1868
- {
1869
- $fileMimeType = $this->getMimeTypeOfSource();
1870
- if (is_null($fileMimeType)) {
1871
- throw new InvalidImageTypeException('Image type could not be detected');
1872
- } elseif ($fileMimeType === false) {
1873
- throw new InvalidImageTypeException('File seems not to be an image.');
1874
- } elseif (!in_array($fileMimeType, self::$allowedMimeTypes)) {
1875
- throw new InvalidImageTypeException('Unsupported mime type: ' . $fileMimeType);
1876
- }
1877
- }
1878
- }
1879
-
1880
- ?><?php
1881
-
1882
- namespace WebPConvert\Convert\Converters\BaseTraits;
1883
-
1884
  /**
1885
  * Trait for handling warnings (by logging them)
1886
  *
@@ -5668,6 +5588,240 @@ class ConverterFactory
5668
 
5669
  ?><?php
5670
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5671
  namespace WebPConvert\Loggers;
5672
 
5673
  /**
@@ -5924,8 +6078,9 @@ class Header
5924
  ?><?php
5925
  namespace WebPConvert\Serve;
5926
 
5927
- use WebPConvert\WebPConvert;
5928
  use WebPConvert\Loggers\EchoLogger;
 
5929
 
5930
  /**
5931
  * Class for generating a HTML report of converting an image.
@@ -5938,6 +6093,7 @@ class Report
5938
  {
5939
  public static function convertAndReport($source, $destination, $options)
5940
  {
 
5941
  ?>
5942
  <html>
5943
  <head>
@@ -5951,8 +6107,8 @@ class Report
5951
  </head>
5952
  <body>
5953
  <table>
5954
- <tr><td><i>source:</i></td><td><?php echo $source ?></td></tr>
5955
- <tr><td><i>destination:</i></td><td><?php echo $destination ?><td></tr>
5956
  </table>
5957
  <br>
5958
  <?php
@@ -5977,9 +6133,9 @@ class Report
5977
  ?><?php
5978
  namespace WebPConvert\Serve;
5979
 
5980
- use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
5981
-
5982
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
 
 
5983
  use WebPConvert\Serve\Exceptions\ServeFailedException;
5984
  use WebPConvert\Serve\Header;
5985
  use WebPConvert\Serve\Report;
@@ -6047,7 +6203,8 @@ class ServeConvertedWebP
6047
  */
6048
  public static function serveOriginal($source, $serveImageOptions = [])
6049
  {
6050
- $contentType = ImageMimeTypeGuesser::lenientGuess($source);
 
6051
  if (is_null($contentType)) {
6052
  throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
6053
  } elseif ($contentType === false) {
@@ -6060,6 +6217,8 @@ class ServeConvertedWebP
6060
  /**
6061
  * Serve destination file.
6062
  *
 
 
6063
  * @param string $destination path to destination file
6064
  * @param array $serveImageOptions (optional) options for serving (such as which headers to add)
6065
  * Supported options:
@@ -6068,6 +6227,7 @@ class ServeConvertedWebP
6068
  */
6069
  public static function serveDestination($destination, $serveImageOptions = [])
6070
  {
 
6071
  ServeFile::serve($destination, 'image/webp', $serveImageOptions);
6072
  }
6073
 
@@ -6103,16 +6263,7 @@ class ServeConvertedWebP
6103
  */
6104
  public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
6105
  {
6106
-
6107
- if (empty($source)) {
6108
- throw new ServeFailedException('Source argument missing');
6109
- }
6110
- if (empty($destination)) {
6111
- throw new ServeFailedException('Destination argument missing');
6112
- }
6113
- if (@!file_exists($source)) {
6114
- throw new ServeFailedException('Source file was not found');
6115
- }
6116
 
6117
  $options = self::processOptions($options);
6118
 
@@ -6178,6 +6329,7 @@ class ServeConvertedWebP
6178
  ?><?php
6179
  namespace WebPConvert\Serve;
6180
 
 
6181
  use WebPConvert\Options\Options;
6182
  use WebPConvert\Options\StringOption;
6183
  use WebPConvert\Serve\Header;
@@ -6245,7 +6397,6 @@ class ServeConvertedWebPWithErrorHandling
6245
  {
6246
  self::addHeadersPreventingCaching();
6247
 
6248
- //Header::addLogHeader('Failure');
6249
  Header::addLogHeader('Performing fail action: ' . $fail);
6250
 
6251
  switch ($fail) {
@@ -6312,9 +6463,10 @@ class ServeConvertedWebPWithErrorHandling
6312
  $convertLogger = null,
6313
  $serveClass = '\\WebPConvert\\Serve\\ServeConvertedWebP'
6314
  ) {
6315
- $options = self::processOptions($options);
6316
 
 
6317
  try {
 
6318
  //ServeConvertedWebP::serve($source, $destination, $options, $serveLogger);
6319
  call_user_func($serveClass . '::serve', $source, $destination, $options, $serveLogger, $convertLogger);
6320
  } catch (\Exception $e) {
@@ -6339,6 +6491,7 @@ class ServeConvertedWebPWithErrorHandling
6339
  namespace WebPConvert\Serve;
6340
 
6341
  //use WebPConvert\Serve\Report;
 
6342
  use WebPConvert\Options\ArrayOption;
6343
  use WebPConvert\Options\BooleanOption;
6344
  use WebPConvert\Options\Options;
@@ -6415,10 +6568,19 @@ class ServeFile
6415
  */
6416
  public static function serve($filename, $contentType, $options = [])
6417
  {
 
 
 
 
 
 
 
 
 
6418
  if (!file_exists($filename)) {
6419
  Header::addHeader('X-WebP-Convert-Error: Could not read file');
6420
  throw new ServeFailedException('Could not read file');
6421
- }
6422
 
6423
  $options = self::processOptions($options);
6424
 
142
 
143
  namespace WebPConvert\Convert\Converters;
144
 
145
+ use WebPConvert\Helpers\InputValidator;
146
+ use WebPConvert\Helpers\MimeType;
147
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
 
148
  use WebPConvert\Convert\Converters\BaseTraits\AutoQualityTrait;
149
  use WebPConvert\Convert\Converters\BaseTraits\DestinationPreparationTrait;
150
  use WebPConvert\Convert\Converters\BaseTraits\LoggerTrait;
151
  use WebPConvert\Convert\Converters\BaseTraits\OptionsTrait;
 
152
  use WebPConvert\Convert\Converters\BaseTraits\WarningLoggerTrait;
153
+ use WebPConvert\Exceptions\WebPConvertException;
154
  use WebPConvert\Loggers\BaseLogger;
155
 
 
 
156
  /**
157
  * Base for all converter classes.
158
  *
166
  use OptionsTrait;
167
  use WarningLoggerTrait;
168
  use DestinationPreparationTrait;
 
169
  use LoggerTrait;
170
 
171
  /**
203
  /** @var string Where to save the webp (complete path) */
204
  protected $destination;
205
 
 
 
 
206
  /**
207
  * Check basis operationality
208
  *
245
  */
246
  public function __construct($source, $destination, $options = [], $logger = null)
247
  {
248
+ InputValidator::checkSourceAndDestination($source, $destination);
249
+
250
  $this->source = $source;
251
  $this->destination = $destination;
252
 
254
  $this->setProvidedOptions($options);
255
 
256
  if (!isset($this->options['_skip_input_check'])) {
257
+ $this->log('WebP Convert 2.0.5', 'italic');
258
  $this->logLn(' ignited.');
259
  $this->logLn('- PHP version: ' . phpversion());
260
  if (isset($_SERVER['SERVER_SOFTWARE'])) {
263
  $this->logLn('');
264
  $this->logLn(self::getConverterDisplayName() . ' converter ignited');
265
  }
 
 
 
266
  }
267
 
268
  /**
370
  $this->removeExistingDestinationIfExists();
371
 
372
  if (!isset($this->options['_skip_input_check'])) {
 
 
 
 
373
  // Check that a file can be written to destination
374
  $this->checkDestinationWritable();
375
  }
507
  */
508
  public function getMimeTypeOfSource()
509
  {
510
+ return MimeType::getMimeTypeDetectionResult($this->source);
 
 
 
 
 
511
  }
512
  }
513
 
1801
 
1802
  namespace WebPConvert\Convert\Converters\BaseTraits;
1803
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1804
  /**
1805
  * Trait for handling warnings (by logging them)
1806
  *
5588
 
5589
  ?><?php
5590
 
5591
+ namespace WebPConvert\Exceptions;
5592
+
5593
+ use WebPConvert\Exceptions\WebPConvertException;
5594
+
5595
+ class InvalidInputException extends WebPConvertException
5596
+ {
5597
+ public $description = 'Invalid input';
5598
+ }
5599
+
5600
+ ?><?php
5601
+
5602
+ namespace WebPConvert\Exceptions\InvalidInput;
5603
+
5604
+ use WebPConvert\Exceptions\InvalidInputException;
5605
+
5606
+ class InvalidImageTypeException extends InvalidInputException
5607
+ {
5608
+ public $description = 'The converter does not handle the supplied image type';
5609
+ }
5610
+
5611
+ ?><?php
5612
+
5613
+ namespace WebPConvert\Exceptions\InvalidInput;
5614
+
5615
+ use WebPConvert\Exceptions\InvalidInputException;
5616
+
5617
+ class TargetNotFoundException extends InvalidInputException
5618
+ {
5619
+ public $description = 'The converter could not locate source file';
5620
+ }
5621
+
5622
+ ?><?php
5623
+
5624
+ namespace WebPConvert\Helpers;
5625
+
5626
+ use WebPConvert\Helpers\MimeType;
5627
+ use WebPConvert\Helpers\PathChecker;
5628
+ use WebPConvert\Exceptions\InvalidInputException;
5629
+ use WebPConvert\Exceptions\InvalidInput\InvalidImageTypeException;
5630
+
5631
+ /**
5632
+ * Functions for sanitizing.
5633
+ *
5634
+ * @package WebPConvert
5635
+ * @author Bjørn Rosell <it@rosell.dk>
5636
+ * @since Class available since Release 2.0.6
5637
+ */
5638
+ class InputValidator
5639
+ {
5640
+
5641
+ private static $allowedMimeTypes = [
5642
+ 'image/jpeg',
5643
+ 'image/png'
5644
+ ];
5645
+
5646
+ /**
5647
+ * Check mimetype and if file path is ok and exists
5648
+ */
5649
+ public static function checkMimeType($filePath, $allowedMimeTypes = null)
5650
+ {
5651
+ if (is_null($allowedMimeTypes)) {
5652
+ $allowedMimeTypes = self::$allowedMimeTypes;
5653
+ }
5654
+ // the following also tests that file path is ok and file exists
5655
+ $fileMimeType = MimeType::getMimeTypeDetectionResult($filePath);
5656
+
5657
+ if (is_null($fileMimeType)) {
5658
+ throw new InvalidImageTypeException('Image type could not be detected');
5659
+ } elseif ($fileMimeType === false) {
5660
+ throw new InvalidImageTypeException('File seems not to be an image.');
5661
+ } elseif (!in_array($fileMimeType, $allowedMimeTypes)) {
5662
+ throw new InvalidImageTypeException('Unsupported mime type: ' . $fileMimeType);
5663
+ }
5664
+ }
5665
+
5666
+ public static function checkSource($source)
5667
+ {
5668
+ PathChecker::checkSourcePath($source);
5669
+ self::checkMimeType($source);
5670
+ }
5671
+
5672
+ public static function checkDestination($destination)
5673
+ {
5674
+ PathChecker::checkDestinationPath($destination);
5675
+ }
5676
+
5677
+ public static function checkSourceAndDestination($source, $destination)
5678
+ {
5679
+ self::checkSource($source);
5680
+ self::checkDestination($destination);
5681
+ }
5682
+ }
5683
+
5684
+ ?><?php
5685
+
5686
+ namespace WebPConvert\Helpers;
5687
+
5688
+ use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
5689
+
5690
+ use WebPConvert\Exceptions\InvalidInputException;
5691
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
5692
+
5693
+ /**
5694
+ * Get MimeType, results cached by path.
5695
+ *
5696
+ * @package WebPConvert
5697
+ * @author Bjørn Rosell <it@rosell.dk>
5698
+ * @since Class available since Release 2.0.6
5699
+ */
5700
+ class MimeType
5701
+ {
5702
+ private static $cachedDetections = [];
5703
+
5704
+ /**
5705
+ * Get mime type for image (best guess).
5706
+ *
5707
+ * It falls back to using file extension. If that fails too, false is returned
5708
+ *
5709
+ * @return string|false|null mimetype (if it is an image, and type could be determined / guessed),
5710
+ * false (if it is not an image type that the server knowns about)
5711
+ * or null (if nothing can be determined)
5712
+ */
5713
+ public static function getMimeTypeDetectionResult($absFilePath)
5714
+ {
5715
+ PathChecker::checkAbsolutePathAndExists($absFilePath);
5716
+
5717
+ if (isset(self::$cachedDetections[$absFilePath])) {
5718
+ return self::$cachedDetections[$absFilePath];
5719
+ }
5720
+ $cachedDetections[$absFilePath] = ImageMimeTypeGuesser::lenientGuess($absFilePath);
5721
+ return $cachedDetections[$absFilePath];
5722
+ }
5723
+ }
5724
+
5725
+ ?><?php
5726
+
5727
+ namespace WebPConvert\Helpers;
5728
+
5729
+ use WebPConvert\Exceptions\InvalidInputException;
5730
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
5731
+
5732
+ /**
5733
+ * Functions for sanitizing.
5734
+ *
5735
+ * @package WebPConvert
5736
+ * @author Bjørn Rosell <it@rosell.dk>
5737
+ * @since Class available since Release 2.0.6
5738
+ */
5739
+ class PathChecker
5740
+ {
5741
+
5742
+ /**
5743
+ * Check absolute file path to prevent attacks.
5744
+ *
5745
+ * - Prevents non printable characters
5746
+ * - Prevents stream wrappers
5747
+ * - Prevents directory traversal
5748
+ *
5749
+ * Preventing non printable characters is especially done to prevent the NUL character, which can be used
5750
+ * to bypass other tests. See https://st-g.de/2011/04/doing-filename-checks-securely-in-PHP.
5751
+ *
5752
+ * Preventeng stream wrappers is especially done to protect against Phar Deserialization.
5753
+ * See https://blog.ripstech.com/2018/new-php-exploitation-technique/
5754
+ *
5755
+ * @param string $absFilePath
5756
+ * @return string sanitized file path
5757
+ */
5758
+ public static function checkAbsolutePath($absFilePath, $text = 'file')
5759
+ {
5760
+ if (empty($absFilePath)) {
5761
+ throw new InvalidInputException('Empty filepath for ' . $text);
5762
+ }
5763
+
5764
+ // Prevent non printable characters
5765
+ if (!ctype_print($absFilePath)) {
5766
+ throw new InvalidInputException('Non-printable characters are not allowed in ' . $text);
5767
+ }
5768
+
5769
+ // Prevent directory traversal
5770
+ if (preg_match('#\.\.\/#', $absFilePath)) {
5771
+ throw new InvalidInputException('Directory traversal is not allowed in ' . $text . ' path');
5772
+ }
5773
+
5774
+ // Prevent stream wrappers ("phar://", "php://" and the like)
5775
+ // https://www.php.net/manual/en/wrappers.phar.php
5776
+ if (preg_match('#^\\w+://#', $absFilePath)) {
5777
+ throw new InvalidInputException('Stream wrappers are not allowed in ' . $text . ' path');
5778
+ }
5779
+ }
5780
+
5781
+ public static function checkAbsolutePathAndExists($absFilePath, $text = 'file')
5782
+ {
5783
+ if (empty($absFilePath)) {
5784
+ throw new TargetNotFoundException($text . ' argument missing');
5785
+ }
5786
+ self::checkAbsolutePath($absFilePath, $text);
5787
+ if (@!file_exists($absFilePath)) {
5788
+ throw new TargetNotFoundException($text . ' file was not found');
5789
+ }
5790
+ if (@is_dir($absFilePath)) {
5791
+ throw new InvalidInputException($text . ' is a directory');
5792
+ }
5793
+ }
5794
+
5795
+ /**
5796
+ * Checks that source path is secure, file exists and it is not a dir.
5797
+ *
5798
+ * To also check mime type, use InputValidator::checkSource
5799
+ */
5800
+ public static function checkSourcePath($source)
5801
+ {
5802
+ self::checkAbsolutePathAndExists($source, 'source');
5803
+ }
5804
+
5805
+ public static function checkDestinationPath($destination)
5806
+ {
5807
+ if (empty($destination)) {
5808
+ throw new InvalidInputException('Destination argument missing');
5809
+ }
5810
+ self::checkAbsolutePath($destination, 'destination');
5811
+ if (@is_dir($destination)) {
5812
+ throw new InvalidInputException('Destination is a directory');
5813
+ }
5814
+ }
5815
+
5816
+ public static function checkSourceAndDestinationPaths($source, $destination)
5817
+ {
5818
+ self::checkSourcePath($source);
5819
+ self::checkDestinationPath($destination);
5820
+ }
5821
+ }
5822
+
5823
+ ?><?php
5824
+
5825
  namespace WebPConvert\Loggers;
5826
 
5827
  /**
6078
  ?><?php
6079
  namespace WebPConvert\Serve;
6080
 
6081
+ use WebPConvert\Helpers\InputValidator;
6082
  use WebPConvert\Loggers\EchoLogger;
6083
+ use WebPConvert\WebPConvert;
6084
 
6085
  /**
6086
  * Class for generating a HTML report of converting an image.
6093
  {
6094
  public static function convertAndReport($source, $destination, $options)
6095
  {
6096
+ InputValidator::checkSourceAndDestination($source, $destination);
6097
  ?>
6098
  <html>
6099
  <head>
6107
  </head>
6108
  <body>
6109
  <table>
6110
+ <tr><td><i>source:</i></td><td><?php echo htmlentities($source) ?></td></tr>
6111
+ <tr><td><i>destination:</i></td><td><?php echo htmlentities($destination) ?><td></tr>
6112
  </table>
6113
  <br>
6114
  <?php
6133
  ?><?php
6134
  namespace WebPConvert\Serve;
6135
 
 
 
6136
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
6137
+ use WebPConvert\Helpers\InputValidator;
6138
+ use WebPConvert\Helpers\MimeType;
6139
  use WebPConvert\Serve\Exceptions\ServeFailedException;
6140
  use WebPConvert\Serve\Header;
6141
  use WebPConvert\Serve\Report;
6203
  */
6204
  public static function serveOriginal($source, $serveImageOptions = [])
6205
  {
6206
+ InputValidator::checkSource($source);
6207
+ $contentType = MimeType::getMimeTypeDetectionResult($source);
6208
  if (is_null($contentType)) {
6209
  throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
6210
  } elseif ($contentType === false) {
6217
  /**
6218
  * Serve destination file.
6219
  *
6220
+ * TODO: SHould this really be public?
6221
+ *
6222
  * @param string $destination path to destination file
6223
  * @param array $serveImageOptions (optional) options for serving (such as which headers to add)
6224
  * Supported options:
6227
  */
6228
  public static function serveDestination($destination, $serveImageOptions = [])
6229
  {
6230
+ InputValidator::checkDestination($destination);
6231
  ServeFile::serve($destination, 'image/webp', $serveImageOptions);
6232
  }
6233
 
6263
  */
6264
  public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
6265
  {
6266
+ InputValidator::checkSourceAndDestination($source, $destination);
 
 
 
 
 
 
 
 
 
6267
 
6268
  $options = self::processOptions($options);
6269
 
6329
  ?><?php
6330
  namespace WebPConvert\Serve;
6331
 
6332
+ use WebPConvert\Helpers\InputValidator;
6333
  use WebPConvert\Options\Options;
6334
  use WebPConvert\Options\StringOption;
6335
  use WebPConvert\Serve\Header;
6397
  {
6398
  self::addHeadersPreventingCaching();
6399
 
 
6400
  Header::addLogHeader('Performing fail action: ' . $fail);
6401
 
6402
  switch ($fail) {
6463
  $convertLogger = null,
6464
  $serveClass = '\\WebPConvert\\Serve\\ServeConvertedWebP'
6465
  ) {
 
6466
 
6467
+ $options = self::processOptions($options);
6468
  try {
6469
+ InputValidator::checkSourceAndDestination($source, $destination);
6470
  //ServeConvertedWebP::serve($source, $destination, $options, $serveLogger);
6471
  call_user_func($serveClass . '::serve', $source, $destination, $options, $serveLogger, $convertLogger);
6472
  } catch (\Exception $e) {
6491
  namespace WebPConvert\Serve;
6492
 
6493
  //use WebPConvert\Serve\Report;
6494
+ use WebPConvert\Helpers\InputValidator;
6495
  use WebPConvert\Options\ArrayOption;
6496
  use WebPConvert\Options\BooleanOption;
6497
  use WebPConvert\Options\Options;
6568
  */
6569
  public static function serve($filename, $contentType, $options = [])
6570
  {
6571
+ // Check mimetype - this also checks that path is secure and file exists
6572
+ InputValidator::checkMimeType($filename, [
6573
+ 'image/jpeg',
6574
+ 'image/png',
6575
+ 'image/webp',
6576
+ 'image/gif'
6577
+ ]);
6578
+
6579
+ /*
6580
  if (!file_exists($filename)) {
6581
  Header::addHeader('X-WebP-Convert-Error: Could not read file');
6582
  throw new ServeFailedException('Could not read file');
6583
+ }*/
6584
 
6585
  $options = self::processOptions($options);
6586
 
vendor/rosell-dk/webp-convert/src-build/webp-on-demand-1.inc CHANGED
@@ -2,9 +2,9 @@
2
  ?><?php
3
  namespace WebPConvert\Serve;
4
 
5
- use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
6
-
7
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
 
 
8
  use WebPConvert\Serve\Exceptions\ServeFailedException;
9
  use WebPConvert\Serve\Header;
10
  use WebPConvert\Serve\Report;
@@ -72,7 +72,8 @@ class ServeConvertedWebP
72
  */
73
  public static function serveOriginal($source, $serveImageOptions = [])
74
  {
75
- $contentType = ImageMimeTypeGuesser::lenientGuess($source);
 
76
  if (is_null($contentType)) {
77
  throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
78
  } elseif ($contentType === false) {
@@ -85,6 +86,8 @@ class ServeConvertedWebP
85
  /**
86
  * Serve destination file.
87
  *
 
 
88
  * @param string $destination path to destination file
89
  * @param array $serveImageOptions (optional) options for serving (such as which headers to add)
90
  * Supported options:
@@ -93,6 +96,7 @@ class ServeConvertedWebP
93
  */
94
  public static function serveDestination($destination, $serveImageOptions = [])
95
  {
 
96
  ServeFile::serve($destination, 'image/webp', $serveImageOptions);
97
  }
98
 
@@ -128,16 +132,7 @@ class ServeConvertedWebP
128
  */
129
  public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
130
  {
131
-
132
- if (empty($source)) {
133
- throw new ServeFailedException('Source argument missing');
134
- }
135
- if (empty($destination)) {
136
- throw new ServeFailedException('Destination argument missing');
137
- }
138
- if (@!file_exists($source)) {
139
- throw new ServeFailedException('Source file was not found');
140
- }
141
 
142
  $options = self::processOptions($options);
143
 
@@ -203,6 +198,7 @@ class ServeConvertedWebP
203
  ?><?php
204
  namespace WebPConvert\Serve;
205
 
 
206
  use WebPConvert\Options\Options;
207
  use WebPConvert\Options\StringOption;
208
  use WebPConvert\Serve\Header;
@@ -270,7 +266,6 @@ class ServeConvertedWebPWithErrorHandling
270
  {
271
  self::addHeadersPreventingCaching();
272
 
273
- //Header::addLogHeader('Failure');
274
  Header::addLogHeader('Performing fail action: ' . $fail);
275
 
276
  switch ($fail) {
@@ -337,9 +332,10 @@ class ServeConvertedWebPWithErrorHandling
337
  $convertLogger = null,
338
  $serveClass = '\\WebPConvert\\Serve\\ServeConvertedWebP'
339
  ) {
340
- $options = self::processOptions($options);
341
 
 
342
  try {
 
343
  //ServeConvertedWebP::serve($source, $destination, $options, $serveLogger);
344
  call_user_func($serveClass . '::serve', $source, $destination, $options, $serveLogger, $convertLogger);
345
  } catch (\Exception $e) {
@@ -364,6 +360,7 @@ class ServeConvertedWebPWithErrorHandling
364
  namespace WebPConvert\Serve;
365
 
366
  //use WebPConvert\Serve\Report;
 
367
  use WebPConvert\Options\ArrayOption;
368
  use WebPConvert\Options\BooleanOption;
369
  use WebPConvert\Options\Options;
@@ -440,10 +437,19 @@ class ServeFile
440
  */
441
  public static function serve($filename, $contentType, $options = [])
442
  {
 
 
 
 
 
 
 
 
 
443
  if (!file_exists($filename)) {
444
  Header::addHeader('X-WebP-Convert-Error: Could not read file');
445
  throw new ServeFailedException('Could not read file');
446
- }
447
 
448
  $options = self::processOptions($options);
449
 
@@ -484,6 +490,244 @@ class ServeFile
484
  }
485
  }
486
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
  ?><?php
488
  namespace WebPConvert\Serve;
489
 
@@ -614,3 +858,536 @@ class WebPConvert
614
  }
615
  }
616
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  ?><?php
3
  namespace WebPConvert\Serve;
4
 
 
 
5
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
6
+ use WebPConvert\Helpers\InputValidator;
7
+ use WebPConvert\Helpers\MimeType;
8
  use WebPConvert\Serve\Exceptions\ServeFailedException;
9
  use WebPConvert\Serve\Header;
10
  use WebPConvert\Serve\Report;
72
  */
73
  public static function serveOriginal($source, $serveImageOptions = [])
74
  {
75
+ InputValidator::checkSource($source);
76
+ $contentType = MimeType::getMimeTypeDetectionResult($source);
77
  if (is_null($contentType)) {
78
  throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
79
  } elseif ($contentType === false) {
86
  /**
87
  * Serve destination file.
88
  *
89
+ * TODO: SHould this really be public?
90
+ *
91
  * @param string $destination path to destination file
92
  * @param array $serveImageOptions (optional) options for serving (such as which headers to add)
93
  * Supported options:
96
  */
97
  public static function serveDestination($destination, $serveImageOptions = [])
98
  {
99
+ InputValidator::checkDestination($destination);
100
  ServeFile::serve($destination, 'image/webp', $serveImageOptions);
101
  }
102
 
132
  */
133
  public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
134
  {
135
+ InputValidator::checkSourceAndDestination($source, $destination);
 
 
 
 
 
 
 
 
 
136
 
137
  $options = self::processOptions($options);
138
 
198
  ?><?php
199
  namespace WebPConvert\Serve;
200
 
201
+ use WebPConvert\Helpers\InputValidator;
202
  use WebPConvert\Options\Options;
203
  use WebPConvert\Options\StringOption;
204
  use WebPConvert\Serve\Header;
266
  {
267
  self::addHeadersPreventingCaching();
268
 
 
269
  Header::addLogHeader('Performing fail action: ' . $fail);
270
 
271
  switch ($fail) {
332
  $convertLogger = null,
333
  $serveClass = '\\WebPConvert\\Serve\\ServeConvertedWebP'
334
  ) {
 
335
 
336
+ $options = self::processOptions($options);
337
  try {
338
+ InputValidator::checkSourceAndDestination($source, $destination);
339
  //ServeConvertedWebP::serve($source, $destination, $options, $serveLogger);
340
  call_user_func($serveClass . '::serve', $source, $destination, $options, $serveLogger, $convertLogger);
341
  } catch (\Exception $e) {
360
  namespace WebPConvert\Serve;
361
 
362
  //use WebPConvert\Serve\Report;
363
+ use WebPConvert\Helpers\InputValidator;
364
  use WebPConvert\Options\ArrayOption;
365
  use WebPConvert\Options\BooleanOption;
366
  use WebPConvert\Options\Options;
437
  */
438
  public static function serve($filename, $contentType, $options = [])
439
  {
440
+ // Check mimetype - this also checks that path is secure and file exists
441
+ InputValidator::checkMimeType($filename, [
442
+ 'image/jpeg',
443
+ 'image/png',
444
+ 'image/webp',
445
+ 'image/gif'
446
+ ]);
447
+
448
+ /*
449
  if (!file_exists($filename)) {
450
  Header::addHeader('X-WebP-Convert-Error: Could not read file');
451
  throw new ServeFailedException('Could not read file');
452
+ }*/
453
 
454
  $options = self::processOptions($options);
455
 
490
  }
491
  }
492
 
493
+ ?><?php
494
+
495
+ namespace WebPConvert\Exceptions;
496
+
497
+ /**
498
+ * WebPConvertException is the base exception for all exceptions in this library.
499
+ *
500
+ * Note that the parameters for the constructor differs from that of the Exception class.
501
+ * We do not use exception code here, but are instead allowing two version of the error message:
502
+ * a short version and a long version.
503
+ * The short version may not contain special characters or dynamic content.
504
+ * The detailed version may.
505
+ * If the detailed version isn't provided, getDetailedMessage will return the short version.
506
+ *
507
+ */
508
+ class WebPConvertException extends \Exception
509
+ {
510
+ public $description = '';
511
+ protected $detailedMessage;
512
+ protected $shortMessage;
513
+
514
+ public function getDetailedMessage()
515
+ {
516
+ return $this->detailedMessage;
517
+ }
518
+
519
+ public function getShortMessage()
520
+ {
521
+ return $this->shortMessage;
522
+ }
523
+
524
+ public function __construct($shortMessage = "", $detailedMessage = "", $previous = null)
525
+ {
526
+ $detailedMessage = ($detailedMessage != '') ? $detailedMessage : $shortMessage;
527
+ $this->detailedMessage = $detailedMessage;
528
+ $this->shortMessage = $shortMessage;
529
+
530
+ parent::__construct(
531
+ $detailedMessage,
532
+ 0,
533
+ $previous
534
+ );
535
+ }
536
+ }
537
+
538
+ ?><?php
539
+
540
+ namespace WebPConvert\Exceptions;
541
+
542
+ use WebPConvert\Exceptions\WebPConvertException;
543
+
544
+ class InvalidInputException extends WebPConvertException
545
+ {
546
+ public $description = 'Invalid input';
547
+ }
548
+
549
+ ?><?php
550
+
551
+ namespace WebPConvert\Exceptions\InvalidInput;
552
+
553
+ use WebPConvert\Exceptions\InvalidInputException;
554
+
555
+ class InvalidImageTypeException extends InvalidInputException
556
+ {
557
+ public $description = 'The converter does not handle the supplied image type';
558
+ }
559
+
560
+ ?><?php
561
+
562
+ namespace WebPConvert\Exceptions\InvalidInput;
563
+
564
+ use WebPConvert\Exceptions\InvalidInputException;
565
+
566
+ class TargetNotFoundException extends InvalidInputException
567
+ {
568
+ public $description = 'The converter could not locate source file';
569
+ }
570
+
571
+ ?><?php
572
+
573
+ namespace WebPConvert\Helpers;
574
+
575
+ use WebPConvert\Exceptions\InvalidInputException;
576
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
577
+
578
+ /**
579
+ * Functions for sanitizing.
580
+ *
581
+ * @package WebPConvert
582
+ * @author Bjørn Rosell <it@rosell.dk>
583
+ * @since Class available since Release 2.0.6
584
+ */
585
+ class PathChecker
586
+ {
587
+
588
+ /**
589
+ * Check absolute file path to prevent attacks.
590
+ *
591
+ * - Prevents non printable characters
592
+ * - Prevents stream wrappers
593
+ * - Prevents directory traversal
594
+ *
595
+ * Preventing non printable characters is especially done to prevent the NUL character, which can be used
596
+ * to bypass other tests. See https://st-g.de/2011/04/doing-filename-checks-securely-in-PHP.
597
+ *
598
+ * Preventeng stream wrappers is especially done to protect against Phar Deserialization.
599
+ * See https://blog.ripstech.com/2018/new-php-exploitation-technique/
600
+ *
601
+ * @param string $absFilePath
602
+ * @return string sanitized file path
603
+ */
604
+ public static function checkAbsolutePath($absFilePath, $text = 'file')
605
+ {
606
+ if (empty($absFilePath)) {
607
+ throw new InvalidInputException('Empty filepath for ' . $text);
608
+ }
609
+
610
+ // Prevent non printable characters
611
+ if (!ctype_print($absFilePath)) {
612
+ throw new InvalidInputException('Non-printable characters are not allowed in ' . $text);
613
+ }
614
+
615
+ // Prevent directory traversal
616
+ if (preg_match('#\.\.\/#', $absFilePath)) {
617
+ throw new InvalidInputException('Directory traversal is not allowed in ' . $text . ' path');
618
+ }
619
+
620
+ // Prevent stream wrappers ("phar://", "php://" and the like)
621
+ // https://www.php.net/manual/en/wrappers.phar.php
622
+ if (preg_match('#^\\w+://#', $absFilePath)) {
623
+ throw new InvalidInputException('Stream wrappers are not allowed in ' . $text . ' path');
624
+ }
625
+ }
626
+
627
+ public static function checkAbsolutePathAndExists($absFilePath, $text = 'file')
628
+ {
629
+ if (empty($absFilePath)) {
630
+ throw new TargetNotFoundException($text . ' argument missing');
631
+ }
632
+ self::checkAbsolutePath($absFilePath, $text);
633
+ if (@!file_exists($absFilePath)) {
634
+ throw new TargetNotFoundException($text . ' file was not found');
635
+ }
636
+ if (@is_dir($absFilePath)) {
637
+ throw new InvalidInputException($text . ' is a directory');
638
+ }
639
+ }
640
+
641
+ /**
642
+ * Checks that source path is secure, file exists and it is not a dir.
643
+ *
644
+ * To also check mime type, use InputValidator::checkSource
645
+ */
646
+ public static function checkSourcePath($source)
647
+ {
648
+ self::checkAbsolutePathAndExists($source, 'source');
649
+ }
650
+
651
+ public static function checkDestinationPath($destination)
652
+ {
653
+ if (empty($destination)) {
654
+ throw new InvalidInputException('Destination argument missing');
655
+ }
656
+ self::checkAbsolutePath($destination, 'destination');
657
+ if (@is_dir($destination)) {
658
+ throw new InvalidInputException('Destination is a directory');
659
+ }
660
+ }
661
+
662
+ public static function checkSourceAndDestinationPaths($source, $destination)
663
+ {
664
+ self::checkSourcePath($source);
665
+ self::checkDestinationPath($destination);
666
+ }
667
+ }
668
+
669
+ ?><?php
670
+
671
+ namespace WebPConvert\Helpers;
672
+
673
+ use WebPConvert\Helpers\MimeType;
674
+ use WebPConvert\Helpers\PathChecker;
675
+ use WebPConvert\Exceptions\InvalidInputException;
676
+ use WebPConvert\Exceptions\InvalidInput\InvalidImageTypeException;
677
+
678
+ /**
679
+ * Functions for sanitizing.
680
+ *
681
+ * @package WebPConvert
682
+ * @author Bjørn Rosell <it@rosell.dk>
683
+ * @since Class available since Release 2.0.6
684
+ */
685
+ class InputValidator
686
+ {
687
+
688
+ private static $allowedMimeTypes = [
689
+ 'image/jpeg',
690
+ 'image/png'
691
+ ];
692
+
693
+ /**
694
+ * Check mimetype and if file path is ok and exists
695
+ */
696
+ public static function checkMimeType($filePath, $allowedMimeTypes = null)
697
+ {
698
+ if (is_null($allowedMimeTypes)) {
699
+ $allowedMimeTypes = self::$allowedMimeTypes;
700
+ }
701
+ // the following also tests that file path is ok and file exists
702
+ $fileMimeType = MimeType::getMimeTypeDetectionResult($filePath);
703
+
704
+ if (is_null($fileMimeType)) {
705
+ throw new InvalidImageTypeException('Image type could not be detected');
706
+ } elseif ($fileMimeType === false) {
707
+ throw new InvalidImageTypeException('File seems not to be an image.');
708
+ } elseif (!in_array($fileMimeType, $allowedMimeTypes)) {
709
+ throw new InvalidImageTypeException('Unsupported mime type: ' . $fileMimeType);
710
+ }
711
+ }
712
+
713
+ public static function checkSource($source)
714
+ {
715
+ PathChecker::checkSourcePath($source);
716
+ self::checkMimeType($source);
717
+ }
718
+
719
+ public static function checkDestination($destination)
720
+ {
721
+ PathChecker::checkDestinationPath($destination);
722
+ }
723
+
724
+ public static function checkSourceAndDestination($source, $destination)
725
+ {
726
+ self::checkSource($source);
727
+ self::checkDestination($destination);
728
+ }
729
+ }
730
+
731
  ?><?php
732
  namespace WebPConvert\Serve;
733
 
858
  }
859
  }
860
 
861
+ ?><?php
862
+
863
+ /**
864
+ * ImageMimeTypeGuesser - Detect / guess mime type of an image
865
+ *
866
+ * @link https://github.com/rosell-dk/image-mime-type-guesser
867
+ * @license MIT
868
+ */
869
+
870
+ namespace ImageMimeTypeGuesser;
871
+
872
+ class GuessFromExtension
873
+ {
874
+
875
+
876
+ /**
877
+ * Make a wild guess based on file extension.
878
+ *
879
+ * - and I mean wild!
880
+ *
881
+ * Only most popular image types are recognized.
882
+ * Many are not. See this list: https://www.iana.org/assignments/media-types/media-types.xhtml
883
+ * - and the constants here: https://secure.php.net/manual/en/function.exif-imagetype.php
884
+ *
885
+ * If no mapping found, nothing is returned
886
+ *
887
+ * TODO: jp2, jpx, ...
888
+ * Returns:
889
+ * - mimetype (if file extension could be mapped to an image type),
890
+ * - false (if file extension could be mapped to a type known not to be an image type)
891
+ * - null (if file extension could not be mapped to any mime type, using our little list)
892
+ *
893
+ * @param string $filePath The path to the file
894
+ * @return string|false|null mimetype (if file extension could be mapped to an image type),
895
+ * false (if file extension could be mapped to a type known not to be an image type)
896
+ * or null (if file extension could not be mapped to any mime type, using our little list)
897
+ */
898
+ public static function guess($filePath)
899
+ {
900
+ if (!@file_exists($filePath)) {
901
+ return false;
902
+ }
903
+ /*
904
+ Not using pathinfo, as it is locale aware, and I'm not sure if that could lead to problems
905
+
906
+ if (!function_exists('pathinfo')) {
907
+ // This is really a just in case! - We do not expect this to happen.
908
+ // - in fact we have a test case asserting that this does not happen.
909
+ return null;
910
+ //
911
+ $fileExtension = pathinfo($filePath, PATHINFO_EXTENSION);
912
+ $fileExtension = strtolower($fileExtension);
913
+ }*/
914
+
915
+ $result = preg_match('#\\.([^.]*)$#', $filePath, $matches);
916
+ if ($result !== 1) {
917
+ return null;
918
+ }
919
+ $fileExtension = $matches[1];
920
+
921
+ // Trivial image mime types
922
+ if (in_array($fileExtension, ['bmp', 'gif', 'jpeg', 'png', 'tiff', 'webp'])) {
923
+ return 'image/' . $fileExtension;
924
+ }
925
+
926
+ // Common extensions that are definitely not images
927
+ if (in_array($fileExtension, ['txt', 'doc', 'zip', 'gz', 'exe'])) {
928
+ return false;
929
+ }
930
+
931
+ // Non-trivial image mime types
932
+ switch ($fileExtension) {
933
+ case 'ico':
934
+ return 'image/vnd.microsoft.icon'; // or perhaps 'x-icon' ?
935
+
936
+ case 'jpg':
937
+ return 'image/jpeg';
938
+
939
+ case 'svg':
940
+ return 'image/svg+xml';
941
+
942
+ case 'tif':
943
+ return 'image/tiff';
944
+ }
945
+
946
+ // We do not know this extension, return null
947
+ return null;
948
+ }
949
+
950
+ }
951
+
952
+ ?><?php
953
+
954
+ /**
955
+ * ImageMimeTypeGuesser - Detect / guess mime type of an image
956
+ *
957
+ * The library is born out of a discussion here:
958
+ * https://github.com/rosell-dk/webp-convert/issues/98
959
+ *
960
+ * @link https://github.com/rosell-dk/image-mime-type-guesser
961
+ * @license MIT
962
+ */
963
+
964
+ namespace ImageMimeTypeGuesser;
965
+
966
+ use \ImageMimeTypeGuesser\Detectors\Stack;
967
+
968
+ class ImageMimeTypeGuesser
969
+ {
970
+
971
+
972
+ /**
973
+ * Try to detect mime type of image using all available detectors (the "stack" detector).
974
+ *
975
+ * Returns:
976
+ * - mime type (string) (if it is in fact an image, and type could be determined)
977
+ * - false (if it is not an image type that the server knowns about)
978
+ * - null (if nothing can be determined)
979
+ *
980
+ * @param string $filePath The path to the file
981
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
982
+ * false (if it is not an image type that the server knowns about)
983
+ * or null (if nothing can be determined)
984
+ */
985
+ public static function detect($filePath)
986
+ {
987
+ return Stack::detect($filePath);
988
+ }
989
+
990
+ /**
991
+ * Try to detect mime type of image. If that fails, make a guess based on the file extension.
992
+ *
993
+ * Try to detect mime type of image using "stack" detector (all available methods, until one succeeds)
994
+ * If that fails (null), fall back to wild west guessing based solely on file extension.
995
+ *
996
+ * Returns:
997
+ * - mime type (string) (if it is an image, and type could be determined / mapped from file extension))
998
+ * - false (if it is not an image type that the server knowns about)
999
+ * - null (if nothing can be determined)
1000
+ *
1001
+ * @param string $filePath The path to the file
1002
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1003
+ * false (if it is not an image type that the server knowns about)
1004
+ * or null (if nothing can be determined)
1005
+ */
1006
+ public static function guess($filePath)
1007
+ {
1008
+ $detectionResult = self::detect($filePath);
1009
+ if (!is_null($detectionResult)) {
1010
+ return $detectionResult;
1011
+ }
1012
+
1013
+ // fall back to the wild west method
1014
+ return GuessFromExtension::guess($filePath);
1015
+ }
1016
+
1017
+ /**
1018
+ * Try to detect mime type of image. If that fails, make a guess based on the file extension.
1019
+ *
1020
+ * Try to detect mime type of image using "stack" detector (all available methods, until one succeeds)
1021
+ * If that fails (false or null), fall back to wild west guessing based solely on file extension.
1022
+ *
1023
+ * Returns:
1024
+ * - mime type (string) (if it is an image, and type could be determined / mapped from file extension)
1025
+ * - false (if it is not an image type that the server knowns about)
1026
+ * - null (if nothing can be determined)
1027
+ *
1028
+ * @param string $filePath The path to the file
1029
+ * @return string|false|null mimetype (if it is an image, and type could be determined / guessed),
1030
+ * false (if it is not an image type that the server knowns about)
1031
+ * or null (if nothing can be determined)
1032
+ */
1033
+ public static function lenientGuess($filePath)
1034
+ {
1035
+ $detectResult = self::detect($filePath);
1036
+ if ($detectResult === false) {
1037
+ // The server does not recognize this image type.
1038
+ // - but perhaps it is because it does not know about this image type.
1039
+ // - so we turn to mapping the file extension
1040
+ return GuessFromExtension::guess($filePath);
1041
+ } elseif (is_null($detectResult)) {
1042
+ // the mime type could not be determined
1043
+ // perhaps we also in this case want to turn to mapping the file extension
1044
+ return GuessFromExtension::guess($filePath);
1045
+ }
1046
+ return $detectResult;
1047
+ }
1048
+
1049
+
1050
+ /**
1051
+ * Check if the *detected* mime type is in a list of accepted mime types.
1052
+ *
1053
+ * @param string $filePath The path to the file
1054
+ * @param string[] $mimeTypes Mime types to accept
1055
+ * @return bool Whether the detected mime type is in the $mimeTypes array or not
1056
+ */
1057
+ public static function detectIsIn($filePath, $mimeTypes)
1058
+ {
1059
+ return in_array(self::detect($filePath), $mimeTypes);
1060
+ }
1061
+
1062
+ /**
1063
+ * Check if the *guessed* mime type is in a list of accepted mime types.
1064
+ *
1065
+ * @param string $filePath The path to the file
1066
+ * @param string[] $mimeTypes Mime types to accept
1067
+ * @return bool Whether the detected / guessed mime type is in the $mimeTypes array or not
1068
+ */
1069
+ public static function guessIsIn($filePath, $mimeTypes)
1070
+ {
1071
+ return in_array(self::guess($filePath), $mimeTypes);
1072
+ }
1073
+
1074
+ /**
1075
+ * Check if the *leniently guessed* mime type is in a list of accepted mime types.
1076
+ *
1077
+ * @param string $filePath The path to the file
1078
+ * @param string[] $mimeTypes Mime types to accept
1079
+ * @return bool Whether the detected / leniently guessed mime type is in the $mimeTypes array or not
1080
+ */
1081
+ public static function lenientGuessIsIn($filePath, $mimeTypes)
1082
+ {
1083
+ return in_array(self::lenientGuess($filePath), $mimeTypes);
1084
+ }
1085
+ }
1086
+
1087
+ ?><?php
1088
+
1089
+ namespace ImageMimeTypeGuesser\Detectors;
1090
+
1091
+ use ImageMimeTypeGuesser\Detectors\AbstractDetector;
1092
+
1093
+ abstract class AbstractDetector
1094
+ {
1095
+ /**
1096
+ * Try to detect mime type of image
1097
+ *
1098
+ * Returns:
1099
+ * - mime type (string) (if it is in fact an image, and type could be determined)
1100
+ * - false (if it is not an image type that the server knowns about)
1101
+ * - null (if nothing can be determined)
1102
+ *
1103
+ * @param string $filePath The path to the file
1104
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1105
+ * false (if it is not an image type that the server knowns about)
1106
+ * or null (if nothing can be determined)
1107
+ */
1108
+ abstract protected function doDetect($filePath);
1109
+
1110
+ /**
1111
+ * Create an instance of this class
1112
+ *
1113
+ * @param string $filePath The path to the file
1114
+ * @return static
1115
+ */
1116
+ public static function createInstance()
1117
+ {
1118
+ return new static();
1119
+ }
1120
+
1121
+ /**
1122
+ * Detect mime type of file (for images only)
1123
+ *
1124
+ * Returns:
1125
+ * - mime type (string) (if it is in fact an image, and type could be determined)
1126
+ * - false (if it is not an image type that the server knowns about)
1127
+ * - null (if nothing can be determined)
1128
+ *
1129
+ * @param string $filePath The path to the file
1130
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1131
+ * false (if it is not an image type that the server knowns about)
1132
+ * or null (if nothing can be determined)
1133
+ */
1134
+ public static function detect($filePath)
1135
+ {
1136
+ if (!@file_exists($filePath)) {
1137
+ return false;
1138
+ }
1139
+ return self::createInstance()->doDetect($filePath);
1140
+ }
1141
+ }
1142
+
1143
+ ?><?php
1144
+
1145
+ namespace ImageMimeTypeGuesser\Detectors;
1146
+
1147
+ use \ImageMimeTypeGuesser\Detectors\AbstractDetector;
1148
+
1149
+ class ExifImageType extends AbstractDetector
1150
+ {
1151
+
1152
+ /**
1153
+ * Try to detect mime type of image using *exif_imagetype*.
1154
+ *
1155
+ * Returns:
1156
+ * - mime type (string) (if it is in fact an image, and type could be determined)
1157
+ * - false (if it is not an image type that the server knowns about)
1158
+ * - null (if nothing can be determined)
1159
+ *
1160
+ * @param string $filePath The path to the file
1161
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1162
+ * false (if it is not an image type that the server knowns about)
1163
+ * or null (if nothing can be determined)
1164
+ */
1165
+ protected function doDetect($filePath)
1166
+ {
1167
+ // exif_imagetype is fast, however not available on all systems,
1168
+ // It may return false. In that case we can rely on that the file is not an image (and return false)
1169
+ if (function_exists('exif_imagetype')) {
1170
+ try {
1171
+ $imageType = exif_imagetype($filePath);
1172
+ return ($imageType ? image_type_to_mime_type($imageType) : false);
1173
+ } catch (\Exception $e) {
1174
+ // Might for example get "Read error!"
1175
+ // well well, don't let this stop us
1176
+ //echo $e->getMessage();
1177
+ // throw($e);
1178
+ }
1179
+ }
1180
+ return null;
1181
+ }
1182
+ }
1183
+
1184
+ ?><?php
1185
+
1186
+ namespace ImageMimeTypeGuesser\Detectors;
1187
+
1188
+ class FInfo extends AbstractDetector
1189
+ {
1190
+
1191
+ /**
1192
+ * Try to detect mime type of image using *finfo* class.
1193
+ *
1194
+ * Returns:
1195
+ * - mime type (string) (if it is in fact an image, and type could be determined)
1196
+ * - false (if it is not an image type that the server knowns about)
1197
+ * - null (if nothing can be determined)
1198
+ *
1199
+ * @param string $filePath The path to the file
1200
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1201
+ * false (if it is not an image type that the server knowns about)
1202
+ * or null (if nothing can be determined)
1203
+ */
1204
+ protected function doDetect($filePath)
1205
+ {
1206
+
1207
+ if (class_exists('finfo')) {
1208
+ // phpcs:ignore PHPCompatibility.PHP.NewClasses.finfoFound
1209
+ $finfo = new \finfo(FILEINFO_MIME);
1210
+ $mime = explode('; ', $finfo->file($filePath));
1211
+ $result = $mime[0];
1212
+
1213
+ if (strpos($result, 'image/') === 0) {
1214
+ return $result;
1215
+ } else {
1216
+ return false;
1217
+ }
1218
+ }
1219
+ return null;
1220
+ }
1221
+ }
1222
+
1223
+ ?><?php
1224
+
1225
+ namespace ImageMimeTypeGuesser\Detectors;
1226
+
1227
+ class GetImageSize extends AbstractDetector
1228
+ {
1229
+
1230
+ /**
1231
+ * Try to detect mime type of image using *getimagesize()*.
1232
+ *
1233
+ * Returns:
1234
+ * - mime type (string) (if it is in fact an image, and type could be determined)
1235
+ * - false (if it is not an image type that the server knowns about)
1236
+ * - null (if nothing can be determined)
1237
+ *
1238
+ * @param string $filePath The path to the file
1239
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1240
+ * false (if it is not an image type that the server knowns about)
1241
+ * or null (if nothing can be determined)
1242
+ */
1243
+ protected function doDetect($filePath)
1244
+ {
1245
+ // getimagesize is slower than exif_imagetype
1246
+ // It may not return "mime". In that case we can rely on that the file is not an image (and return false)
1247
+ if (function_exists('getimagesize')) {
1248
+ try {
1249
+ $imageSize = getimagesize($filePath);
1250
+ return (isset($imageSize['mime']) ? $imageSize['mime'] : false);
1251
+ } catch (\Exception $e) {
1252
+ // well well, don't let this stop us either
1253
+ return null;
1254
+ }
1255
+ }
1256
+ return null;
1257
+ }
1258
+ }
1259
+
1260
+ ?><?php
1261
+
1262
+ namespace ImageMimeTypeGuesser\Detectors;
1263
+
1264
+ class MimeContentType extends AbstractDetector
1265
+ {
1266
+
1267
+ /**
1268
+ * Try to detect mime type of image using *mime_content_type()*.
1269
+ *
1270
+ * Returns:
1271
+ * - mime type (string) (if it is in fact an image, and type could be determined)
1272
+ * - false (if it is not an image type that the server knowns about)
1273
+ * - null (if nothing can be determined)
1274
+ *
1275
+ * @param string $filePath The path to the file
1276
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1277
+ * false (if it is not an image type that the server knowns about)
1278
+ * or null (if nothing can be determined)
1279
+ */
1280
+ protected function doDetect($filePath)
1281
+ {
1282
+ // mime_content_type supposedly used to be deprecated, but it seems it isn't anymore
1283
+ // it may return false on failure.
1284
+ if (function_exists('mime_content_type')) {
1285
+ try {
1286
+ $result = mime_content_type($filePath);
1287
+ if ($result !== false) {
1288
+ if (strpos($result, 'image/') === 0) {
1289
+ return $result;
1290
+ } else {
1291
+ return false;
1292
+ }
1293
+ }
1294
+ } catch (\Exception $e) {
1295
+ // we are unstoppable!
1296
+ }
1297
+ }
1298
+ return null;
1299
+ }
1300
+ }
1301
+
1302
+ ?><?php
1303
+
1304
+ namespace ImageMimeTypeGuesser\Detectors;
1305
+
1306
+ use \ImageMimeTypeGuesser\Detectors\AbstractDetector;
1307
+
1308
+ class SniffFirstFourBytes extends AbstractDetector
1309
+ {
1310
+
1311
+ /**
1312
+ * Try to detect mime type by sniffing the first four bytes.
1313
+ *
1314
+ * Credits: Based on the code here: http://phil.lavin.me.uk/2011/12/php-accurately-detecting-the-type-of-a-file/
1315
+ *
1316
+ * Returns:
1317
+ * - mime type (string) (if it is in fact an image, and type could be determined)
1318
+ * - false (if it is not an image type that the server knowns about)
1319
+ * - null (if nothing can be determined)
1320
+ *
1321
+ * @param string $filePath The path to the file
1322
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1323
+ * false (if it is not an image type that the server knowns about)
1324
+ * or null (if nothing can be determined)
1325
+ */
1326
+ protected function doDetect($filePath)
1327
+ {
1328
+ // PNG, GIF, JFIF JPEG, EXIF JPEF (respectively)
1329
+ $known = [
1330
+ '89504E47' => 'image/png',
1331
+ '47494638' => 'image/gif',
1332
+ 'FFD8FFE0' => 'image/jpeg', // JFIF JPEG
1333
+ 'FFD8FFE1' => 'image/jpeg', // EXIF JPEG
1334
+ ];
1335
+
1336
+ $handle = @fopen($filePath, 'r');
1337
+ if ($handle === false) {
1338
+ return null;
1339
+ }
1340
+ $firstFour = @fread($handle, 4);
1341
+ if ($firstFour === false) {
1342
+ return null;
1343
+ }
1344
+ $key = strtoupper(bin2hex($firstFour));
1345
+ if (isset($known[$key])) {
1346
+ return $known[$key];
1347
+ }
1348
+ }
1349
+ }
1350
+
1351
+ ?><?php
1352
+
1353
+ namespace ImageMimeTypeGuesser\Detectors;
1354
+
1355
+ class Stack extends AbstractDetector
1356
+ {
1357
+ /**
1358
+ * Try to detect mime type of image using all available detectors.
1359
+ *
1360
+ * Returns:
1361
+ * - mime type (string) (if it is in fact an image, and type could be determined)
1362
+ * - false (if it is not an image type that the server knowns about)
1363
+ * - null (if nothing can be determined)
1364
+ *
1365
+ * @param string $filePath The path to the file
1366
+ * @return string|false|null mimetype (if it is an image, and type could be determined),
1367
+ * false (if it is not an image type that the server knowns about)
1368
+ * or null (if nothing can be determined)
1369
+ */
1370
+ protected function doDetect($filePath)
1371
+ {
1372
+ $detectors = [
1373
+ 'ExifImageType',
1374
+ 'FInfo',
1375
+ 'SniffFirstFourBytes',
1376
+ 'GetImageSize',
1377
+ 'MimeContentType',
1378
+ ];
1379
+
1380
+ foreach ($detectors as $className) {
1381
+ $result = call_user_func(
1382
+ array("\\ImageMimeTypeGuesser\\Detectors\\" . $className, 'detect'),
1383
+ $filePath
1384
+ );
1385
+ if (!is_null($result)) {
1386
+ return $result;
1387
+ }
1388
+ }
1389
+
1390
+ return null; // undetermined
1391
+ }
1392
+ }
1393
+
vendor/rosell-dk/webp-convert/src-build/webp-on-demand-2.inc CHANGED
@@ -142,18 +142,17 @@ class Option
142
 
143
  namespace WebPConvert\Convert\Converters;
144
 
 
 
145
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
146
- use WebPConvert\Exceptions\WebPConvertException;
147
  use WebPConvert\Convert\Converters\BaseTraits\AutoQualityTrait;
148
  use WebPConvert\Convert\Converters\BaseTraits\DestinationPreparationTrait;
149
  use WebPConvert\Convert\Converters\BaseTraits\LoggerTrait;
150
  use WebPConvert\Convert\Converters\BaseTraits\OptionsTrait;
151
- use WebPConvert\Convert\Converters\BaseTraits\SourceValidationTrait;
152
  use WebPConvert\Convert\Converters\BaseTraits\WarningLoggerTrait;
 
153
  use WebPConvert\Loggers\BaseLogger;
154
 
155
- use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
156
-
157
  /**
158
  * Base for all converter classes.
159
  *
@@ -167,7 +166,6 @@ abstract class AbstractConverter
167
  use OptionsTrait;
168
  use WarningLoggerTrait;
169
  use DestinationPreparationTrait;
170
- use SourceValidationTrait;
171
  use LoggerTrait;
172
 
173
  /**
@@ -205,9 +203,6 @@ abstract class AbstractConverter
205
  /** @var string Where to save the webp (complete path) */
206
  protected $destination;
207
 
208
- /** @var string|false|null Where to save the webp (complete path) */
209
- private $sourceMimeType;
210
-
211
  /**
212
  * Check basis operationality
213
  *
@@ -250,6 +245,8 @@ abstract class AbstractConverter
250
  */
251
  public function __construct($source, $destination, $options = [], $logger = null)
252
  {
 
 
253
  $this->source = $source;
254
  $this->destination = $destination;
255
 
@@ -257,7 +254,7 @@ abstract class AbstractConverter
257
  $this->setProvidedOptions($options);
258
 
259
  if (!isset($this->options['_skip_input_check'])) {
260
- $this->log('WebP Convert 2.0.0', 'italic');
261
  $this->logLn(' ignited.');
262
  $this->logLn('- PHP version: ' . phpversion());
263
  if (isset($_SERVER['SERVER_SOFTWARE'])) {
@@ -266,9 +263,6 @@ abstract class AbstractConverter
266
  $this->logLn('');
267
  $this->logLn(self::getConverterDisplayName() . ' converter ignited');
268
  }
269
-
270
- $this->checkSourceExists();
271
- $this->checkSourceMimeType();
272
  }
273
 
274
  /**
@@ -376,10 +370,6 @@ abstract class AbstractConverter
376
  $this->removeExistingDestinationIfExists();
377
 
378
  if (!isset($this->options['_skip_input_check'])) {
379
- // Run basic input validations (if source exists and if file extension is valid)
380
- $this->checkSourceExists();
381
- $this->checkSourceMimeType();
382
-
383
  // Check that a file can be written to destination
384
  $this->checkDestinationWritable();
385
  }
@@ -517,57 +507,7 @@ abstract class AbstractConverter
517
  */
518
  public function getMimeTypeOfSource()
519
  {
520
- if (!isset($this->sourceMimeType)) {
521
- // PS: Scrutinizer complains that ImageMimeTypeGuesser::lenientGuess could also return a boolean
522
- // but this is not true! - it returns string|false|null, just as this method does.
523
- $this->sourceMimeType = ImageMimeTypeGuesser::lenientGuess($this->source);
524
- }
525
- return $this->sourceMimeType;
526
- }
527
- }
528
-
529
- ?><?php
530
-
531
- namespace WebPConvert\Exceptions;
532
-
533
- /**
534
- * WebPConvertException is the base exception for all exceptions in this library.
535
- *
536
- * Note that the parameters for the constructor differs from that of the Exception class.
537
- * We do not use exception code here, but are instead allowing two version of the error message:
538
- * a short version and a long version.
539
- * The short version may not contain special characters or dynamic content.
540
- * The detailed version may.
541
- * If the detailed version isn't provided, getDetailedMessage will return the short version.
542
- *
543
- */
544
- class WebPConvertException extends \Exception
545
- {
546
- public $description = '';
547
- protected $detailedMessage;
548
- protected $shortMessage;
549
-
550
- public function getDetailedMessage()
551
- {
552
- return $this->detailedMessage;
553
- }
554
-
555
- public function getShortMessage()
556
- {
557
- return $this->shortMessage;
558
- }
559
-
560
- public function __construct($shortMessage = "", $detailedMessage = "", $previous = null)
561
- {
562
- $detailedMessage = ($detailedMessage != '') ? $detailedMessage : $shortMessage;
563
- $this->detailedMessage = $detailedMessage;
564
- $this->shortMessage = $shortMessage;
565
-
566
- parent::__construct(
567
- $detailedMessage,
568
- 0,
569
- $previous
570
- );
571
  }
572
  }
573
 
@@ -1738,71 +1678,6 @@ trait OptionsTrait
1738
 
1739
  namespace WebPConvert\Convert\Converters\BaseTraits;
1740
 
1741
- use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\TargetNotFoundException;
1742
- use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\InvalidImageTypeException;
1743
-
1744
- /**
1745
- * Trait for handling options
1746
- *
1747
- * This trait is currently only used in the AbstractConverter class. It has been extracted into a
1748
- * trait in order to bundle the methods concerning options.
1749
- *
1750
- * @package WebPConvert
1751
- * @author Bjørn Rosell <it@rosell.dk>
1752
- * @since Class available since Release 2.0.0
1753
- */
1754
- trait SourceValidationTrait
1755
- {
1756
-
1757
- abstract protected function getMimeTypeOfSource();
1758
- abstract public function getSource();
1759
-
1760
- /** @var array Array of allowed mime types for source. */
1761
- public static $allowedMimeTypes = ['image/jpeg', 'image/png'];
1762
-
1763
- /**
1764
- * Check that source file exists.
1765
- *
1766
- * Note: As the input validations are only run one time in a stack,
1767
- * this method is not overridable
1768
- *
1769
- * @throws TargetNotFoundException
1770
- * @return void
1771
- */
1772
- private function checkSourceExists()
1773
- {
1774
- // Check if source exists
1775
- if (!@file_exists($this->getSource())) {
1776
- throw new TargetNotFoundException('File or directory not found: ' . $this->getSource());
1777
- }
1778
- }
1779
-
1780
- /**
1781
- * Check that source has a valid mime type.
1782
- *
1783
- * Note: As the input validations are only run one time in a stack,
1784
- * this method is not overridable
1785
- *
1786
- * @throws InvalidImageTypeException If mime type could not be detected or is unsupported
1787
- * @return void
1788
- */
1789
- private function checkSourceMimeType()
1790
- {
1791
- $fileMimeType = $this->getMimeTypeOfSource();
1792
- if (is_null($fileMimeType)) {
1793
- throw new InvalidImageTypeException('Image type could not be detected');
1794
- } elseif ($fileMimeType === false) {
1795
- throw new InvalidImageTypeException('File seems not to be an image.');
1796
- } elseif (!in_array($fileMimeType, self::$allowedMimeTypes)) {
1797
- throw new InvalidImageTypeException('Unsupported mime type: ' . $fileMimeType);
1798
- }
1799
- }
1800
- }
1801
-
1802
- ?><?php
1803
-
1804
- namespace WebPConvert\Convert\Converters\BaseTraits;
1805
-
1806
  /**
1807
  * Trait for handling warnings (by logging them)
1808
  *
@@ -5590,6 +5465,47 @@ class ConverterFactory
5590
 
5591
  ?><?php
5592
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5593
  namespace WebPConvert\Loggers;
5594
 
5595
  /**
@@ -5794,8 +5710,9 @@ class EchoLogger extends BaseLogger
5794
  ?><?php
5795
  namespace WebPConvert\Serve;
5796
 
5797
- use WebPConvert\WebPConvert;
5798
  use WebPConvert\Loggers\EchoLogger;
 
5799
 
5800
  /**
5801
  * Class for generating a HTML report of converting an image.
@@ -5808,6 +5725,7 @@ class Report
5808
  {
5809
  public static function convertAndReport($source, $destination, $options)
5810
  {
 
5811
  ?>
5812
  <html>
5813
  <head>
@@ -5821,8 +5739,8 @@ class Report
5821
  </head>
5822
  <body>
5823
  <table>
5824
- <tr><td><i>source:</i></td><td><?php echo $source ?></td></tr>
5825
- <tr><td><i>destination:</i></td><td><?php echo $destination ?><td></tr>
5826
  </table>
5827
  <br>
5828
  <?php
@@ -5855,536 +5773,3 @@ class ServeFailedException extends WebPConvertException
5855
  public $description = 'Failed serving';
5856
  }
5857
 
5858
- ?><?php
5859
-
5860
- namespace ImageMimeTypeGuesser\Detectors;
5861
-
5862
- use ImageMimeTypeGuesser\Detectors\AbstractDetector;
5863
-
5864
- abstract class AbstractDetector
5865
- {
5866
- /**
5867
- * Try to detect mime type of image
5868
- *
5869
- * Returns:
5870
- * - mime type (string) (if it is in fact an image, and type could be determined)
5871
- * - false (if it is not an image type that the server knowns about)
5872
- * - null (if nothing can be determined)
5873
- *
5874
- * @param string $filePath The path to the file
5875
- * @return string|false|null mimetype (if it is an image, and type could be determined),
5876
- * false (if it is not an image type that the server knowns about)
5877
- * or null (if nothing can be determined)
5878
- */
5879
- abstract protected function doDetect($filePath);
5880
-
5881
- /**
5882
- * Create an instance of this class
5883
- *
5884
- * @param string $filePath The path to the file
5885
- * @return static
5886
- */
5887
- public static function createInstance()
5888
- {
5889
- return new static();
5890
- }
5891
-
5892
- /**
5893
- * Detect mime type of file (for images only)
5894
- *
5895
- * Returns:
5896
- * - mime type (string) (if it is in fact an image, and type could be determined)
5897
- * - false (if it is not an image type that the server knowns about)
5898
- * - null (if nothing can be determined)
5899
- *
5900
- * @param string $filePath The path to the file
5901
- * @return string|false|null mimetype (if it is an image, and type could be determined),
5902
- * false (if it is not an image type that the server knowns about)
5903
- * or null (if nothing can be determined)
5904
- */
5905
- public static function detect($filePath)
5906
- {
5907
- if (!@file_exists($filePath)) {
5908
- return false;
5909
- }
5910
- return self::createInstance()->doDetect($filePath);
5911
- }
5912
- }
5913
-
5914
- ?><?php
5915
-
5916
- /**
5917
- * ImageMimeTypeGuesser - Detect / guess mime type of an image
5918
- *
5919
- * @link https://github.com/rosell-dk/image-mime-type-guesser
5920
- * @license MIT
5921
- */
5922
-
5923
- namespace ImageMimeTypeGuesser;
5924
-
5925
- class GuessFromExtension
5926
- {
5927
-
5928
-
5929
- /**
5930
- * Make a wild guess based on file extension.
5931
- *
5932
- * - and I mean wild!
5933
- *
5934
- * Only most popular image types are recognized.
5935
- * Many are not. See this list: https://www.iana.org/assignments/media-types/media-types.xhtml
5936
- * - and the constants here: https://secure.php.net/manual/en/function.exif-imagetype.php
5937
- *
5938
- * If no mapping found, nothing is returned
5939
- *
5940
- * TODO: jp2, jpx, ...
5941
- * Returns:
5942
- * - mimetype (if file extension could be mapped to an image type),
5943
- * - false (if file extension could be mapped to a type known not to be an image type)
5944
- * - null (if file extension could not be mapped to any mime type, using our little list)
5945
- *
5946
- * @param string $filePath The path to the file
5947
- * @return string|false|null mimetype (if file extension could be mapped to an image type),
5948
- * false (if file extension could be mapped to a type known not to be an image type)
5949
- * or null (if file extension could not be mapped to any mime type, using our little list)
5950
- */
5951
- public static function guess($filePath)
5952
- {
5953
- if (!@file_exists($filePath)) {
5954
- return false;
5955
- }
5956
- /*
5957
- Not using pathinfo, as it is locale aware, and I'm not sure if that could lead to problems
5958
-
5959
- if (!function_exists('pathinfo')) {
5960
- // This is really a just in case! - We do not expect this to happen.
5961
- // - in fact we have a test case asserting that this does not happen.
5962
- return null;
5963
- //
5964
- $fileExtension = pathinfo($filePath, PATHINFO_EXTENSION);
5965
- $fileExtension = strtolower($fileExtension);
5966
- }*/
5967
-
5968
- $result = preg_match('#\\.([^.]*)$#', $filePath, $matches);
5969
- if ($result !== 1) {
5970
- return null;
5971
- }
5972
- $fileExtension = $matches[1];
5973
-
5974
- // Trivial image mime types
5975
- if (in_array($fileExtension, ['bmp', 'gif', 'jpeg', 'png', 'tiff', 'webp'])) {
5976
- return 'image/' . $fileExtension;
5977
- }
5978
-
5979
- // Common extensions that are definitely not images
5980
- if (in_array($fileExtension, ['txt', 'doc', 'zip', 'gz', 'exe'])) {
5981
- return false;
5982
- }
5983
-
5984
- // Non-trivial image mime types
5985
- switch ($fileExtension) {
5986
- case 'ico':
5987
- return 'image/vnd.microsoft.icon'; // or perhaps 'x-icon' ?
5988
-
5989
- case 'jpg':
5990
- return 'image/jpeg';
5991
-
5992
- case 'svg':
5993
- return 'image/svg+xml';
5994
-
5995
- case 'tif':
5996
- return 'image/tiff';
5997
- }
5998
-
5999
- // We do not know this extension, return null
6000
- return null;
6001
- }
6002
-
6003
- }
6004
-
6005
- ?><?php
6006
-
6007
- /**
6008
- * ImageMimeTypeGuesser - Detect / guess mime type of an image
6009
- *
6010
- * The library is born out of a discussion here:
6011
- * https://github.com/rosell-dk/webp-convert/issues/98
6012
- *
6013
- * @link https://github.com/rosell-dk/image-mime-type-guesser
6014
- * @license MIT
6015
- */
6016
-
6017
- namespace ImageMimeTypeGuesser;
6018
-
6019
- use \ImageMimeTypeGuesser\Detectors\Stack;
6020
-
6021
- class ImageMimeTypeGuesser
6022
- {
6023
-
6024
-
6025
- /**
6026
- * Try to detect mime type of image using all available detectors (the "stack" detector).
6027
- *
6028
- * Returns:
6029
- * - mime type (string) (if it is in fact an image, and type could be determined)
6030
- * - false (if it is not an image type that the server knowns about)
6031
- * - null (if nothing can be determined)
6032
- *
6033
- * @param string $filePath The path to the file
6034
- * @return string|false|null mimetype (if it is an image, and type could be determined),
6035
- * false (if it is not an image type that the server knowns about)
6036
- * or null (if nothing can be determined)
6037
- */
6038
- public static function detect($filePath)
6039
- {
6040
- return Stack::detect($filePath);
6041
- }
6042
-
6043
- /**
6044
- * Try to detect mime type of image. If that fails, make a guess based on the file extension.
6045
- *
6046
- * Try to detect mime type of image using "stack" detector (all available methods, until one succeeds)
6047
- * If that fails (null), fall back to wild west guessing based solely on file extension.
6048
- *
6049
- * Returns:
6050
- * - mime type (string) (if it is an image, and type could be determined / mapped from file extension))
6051
- * - false (if it is not an image type that the server knowns about)
6052
- * - null (if nothing can be determined)
6053
- *
6054
- * @param string $filePath The path to the file
6055
- * @return string|false|null mimetype (if it is an image, and type could be determined),
6056
- * false (if it is not an image type that the server knowns about)
6057
- * or null (if nothing can be determined)
6058
- */
6059
- public static function guess($filePath)
6060
- {
6061
- $detectionResult = self::detect($filePath);
6062
- if (!is_null($detectionResult)) {
6063
- return $detectionResult;
6064
- }
6065
-
6066
- // fall back to the wild west method
6067
- return GuessFromExtension::guess($filePath);
6068
- }
6069
-
6070
- /**
6071
- * Try to detect mime type of image. If that fails, make a guess based on the file extension.
6072
- *
6073
- * Try to detect mime type of image using "stack" detector (all available methods, until one succeeds)
6074
- * If that fails (false or null), fall back to wild west guessing based solely on file extension.
6075
- *
6076
- * Returns:
6077
- * - mime type (string) (if it is an image, and type could be determined / mapped from file extension)
6078
- * - false (if it is not an image type that the server knowns about)
6079
- * - null (if nothing can be determined)
6080
- *
6081
- * @param string $filePath The path to the file
6082
- * @return string|false|null mimetype (if it is an image, and type could be determined / guessed),
6083
- * false (if it is not an image type that the server knowns about)
6084
- * or null (if nothing can be determined)
6085
- */
6086
- public static function lenientGuess($filePath)
6087
- {
6088
- $detectResult = self::detect($filePath);
6089
- if ($detectResult === false) {
6090
- // The server does not recognize this image type.
6091
- // - but perhaps it is because it does not know about this image type.
6092
- // - so we turn to mapping the file extension
6093
- return GuessFromExtension::guess($filePath);
6094
- } elseif (is_null($detectResult)) {
6095
- // the mime type could not be determined
6096
- // perhaps we also in this case want to turn to mapping the file extension
6097
- return GuessFromExtension::guess($filePath);
6098
- }
6099
- return $detectResult;
6100
- }
6101
-
6102
-
6103
- /**
6104
- * Check if the *detected* mime type is in a list of accepted mime types.
6105
- *
6106
- * @param string $filePath The path to the file
6107
- * @param string[] $mimeTypes Mime types to accept
6108
- * @return bool Whether the detected mime type is in the $mimeTypes array or not
6109
- */
6110
- public static function detectIsIn($filePath, $mimeTypes)
6111
- {
6112
- return in_array(self::detect($filePath), $mimeTypes);
6113
- }
6114
-
6115
- /**
6116
- * Check if the *guessed* mime type is in a list of accepted mime types.
6117
- *
6118
- * @param string $filePath The path to the file
6119
- * @param string[] $mimeTypes Mime types to accept
6120
- * @return bool Whether the detected / guessed mime type is in the $mimeTypes array or not
6121
- */
6122
- public static function guessIsIn($filePath, $mimeTypes)
6123
- {
6124
- return in_array(self::guess($filePath), $mimeTypes);
6125
- }
6126
-
6127
- /**
6128
- * Check if the *leniently guessed* mime type is in a list of accepted mime types.
6129
- *
6130
- * @param string $filePath The path to the file
6131
- * @param string[] $mimeTypes Mime types to accept
6132
- * @return bool Whether the detected / leniently guessed mime type is in the $mimeTypes array or not
6133
- */
6134
- public static function lenientGuessIsIn($filePath, $mimeTypes)
6135
- {
6136
- return in_array(self::lenientGuess($filePath), $mimeTypes);
6137
- }
6138
- }
6139
-
6140
- ?><?php
6141
-
6142
- namespace ImageMimeTypeGuesser\Detectors;
6143
-
6144
- use \ImageMimeTypeGuesser\Detectors\AbstractDetector;
6145
-
6146
- class ExifImageType extends AbstractDetector
6147
- {
6148
-
6149
- /**
6150
- * Try to detect mime type of image using *exif_imagetype*.
6151
- *
6152
- * Returns:
6153
- * - mime type (string) (if it is in fact an image, and type could be determined)
6154
- * - false (if it is not an image type that the server knowns about)
6155
- * - null (if nothing can be determined)
6156
- *
6157
- * @param string $filePath The path to the file
6158
- * @return string|false|null mimetype (if it is an image, and type could be determined),
6159
- * false (if it is not an image type that the server knowns about)
6160
- * or null (if nothing can be determined)
6161
- */
6162
- protected function doDetect($filePath)
6163
- {
6164
- // exif_imagetype is fast, however not available on all systems,
6165
- // It may return false. In that case we can rely on that the file is not an image (and return false)
6166
- if (function_exists('exif_imagetype')) {
6167
- try {
6168
- $imageType = exif_imagetype($filePath);
6169
- return ($imageType ? image_type_to_mime_type($imageType) : false);
6170
- } catch (\Exception $e) {
6171
- // Might for example get "Read error!"
6172
- // well well, don't let this stop us
6173
- //echo $e->getMessage();
6174
- // throw($e);
6175
- }
6176
- }
6177
- return null;
6178
- }
6179
- }
6180
-
6181
- ?><?php
6182
-
6183
- namespace ImageMimeTypeGuesser\Detectors;
6184
-
6185
- class FInfo extends AbstractDetector
6186
- {
6187
-
6188
- /**
6189
- * Try to detect mime type of image using *finfo* class.
6190
- *
6191
- * Returns:
6192
- * - mime type (string) (if it is in fact an image, and type could be determined)
6193
- * - false (if it is not an image type that the server knowns about)
6194
- * - null (if nothing can be determined)
6195
- *
6196
- * @param string $filePath The path to the file
6197
- * @return string|false|null mimetype (if it is an image, and type could be determined),
6198
- * false (if it is not an image type that the server knowns about)
6199
- * or null (if nothing can be determined)
6200
- */
6201
- protected function doDetect($filePath)
6202
- {
6203
-
6204
- if (class_exists('finfo')) {
6205
- // phpcs:ignore PHPCompatibility.PHP.NewClasses.finfoFound
6206
- $finfo = new \finfo(FILEINFO_MIME);
6207
- $mime = explode('; ', $finfo->file($filePath));
6208
- $result = $mime[0];
6209
-
6210
- if (strpos($result, 'image/') === 0) {
6211
- return $result;
6212
- } else {
6213
- return false;
6214
- }
6215
- }
6216
- return null;
6217
- }
6218
- }
6219
-
6220
- ?><?php
6221
-
6222
- namespace ImageMimeTypeGuesser\Detectors;
6223
-
6224
- class GetImageSize extends AbstractDetector
6225
- {
6226
-
6227
- /**
6228
- * Try to detect mime type of image using *getimagesize()*.
6229
- *
6230
- * Returns:
6231
- * - mime type (string) (if it is in fact an image, and type could be determined)
6232
- * - false (if it is not an image type that the server knowns about)
6233
- * - null (if nothing can be determined)
6234
- *
6235
- * @param string $filePath The path to the file
6236
- * @return string|false|null mimetype (if it is an image, and type could be determined),
6237
- * false (if it is not an image type that the server knowns about)
6238
- * or null (if nothing can be determined)
6239
- */
6240
- protected function doDetect($filePath)
6241
- {
6242
- // getimagesize is slower than exif_imagetype
6243
- // It may not return "mime". In that case we can rely on that the file is not an image (and return false)
6244
- if (function_exists('getimagesize')) {
6245
- try {
6246
- $imageSize = getimagesize($filePath);
6247
- return (isset($imageSize['mime']) ? $imageSize['mime'] : false);
6248
- } catch (\Exception $e) {
6249
- // well well, don't let this stop us either
6250
- return null;
6251
- }
6252
- }
6253
- return null;
6254
- }
6255
- }
6256
-
6257
- ?><?php
6258
-
6259
- namespace ImageMimeTypeGuesser\Detectors;
6260
-
6261
- class MimeContentType extends AbstractDetector
6262
- {
6263
-
6264
- /**
6265
- * Try to detect mime type of image using *mime_content_type()*.
6266
- *
6267
- * Returns:
6268
- * - mime type (string) (if it is in fact an image, and type could be determined)
6269
- * - false (if it is not an image type that the server knowns about)
6270
- * - null (if nothing can be determined)
6271
- *
6272
- * @param string $filePath The path to the file
6273
- * @return string|false|null mimetype (if it is an image, and type could be determined),
6274
- * false (if it is not an image type that the server knowns about)
6275
- * or null (if nothing can be determined)
6276
- */
6277
- protected function doDetect($filePath)
6278
- {
6279
- // mime_content_type supposedly used to be deprecated, but it seems it isn't anymore
6280
- // it may return false on failure.
6281
- if (function_exists('mime_content_type')) {
6282
- try {
6283
- $result = mime_content_type($filePath);
6284
- if ($result !== false) {
6285
- if (strpos($result, 'image/') === 0) {
6286
- return $result;
6287
- } else {
6288
- return false;
6289
- }
6290
- }
6291
- } catch (\Exception $e) {
6292
- // we are unstoppable!
6293
- }
6294
- }
6295
- return null;
6296
- }
6297
- }
6298
-
6299
- ?><?php
6300
-
6301
- namespace ImageMimeTypeGuesser\Detectors;
6302
-
6303
- use \ImageMimeTypeGuesser\Detectors\AbstractDetector;
6304
-
6305
- class SniffFirstFourBytes extends AbstractDetector
6306
- {
6307
-
6308
- /**
6309
- * Try to detect mime type by sniffing the first four bytes.
6310
- *
6311
- * Credits: Based on the code here: http://phil.lavin.me.uk/2011/12/php-accurately-detecting-the-type-of-a-file/
6312
- *
6313
- * Returns:
6314
- * - mime type (string) (if it is in fact an image, and type could be determined)
6315
- * - false (if it is not an image type that the server knowns about)
6316
- * - null (if nothing can be determined)
6317
- *
6318
- * @param string $filePath The path to the file
6319
- * @return string|false|null mimetype (if it is an image, and type could be determined),
6320
- * false (if it is not an image type that the server knowns about)
6321
- * or null (if nothing can be determined)
6322
- */
6323
- protected function doDetect($filePath)
6324
- {
6325
- // PNG, GIF, JFIF JPEG, EXIF JPEF (respectively)
6326
- $known = [
6327
- '89504E47' => 'image/png',
6328
- '47494638' => 'image/gif',
6329
- 'FFD8FFE0' => 'image/jpeg', // JFIF JPEG
6330
- 'FFD8FFE1' => 'image/jpeg', // EXIF JPEG
6331
- ];
6332
-
6333
- $handle = @fopen($filePath, 'r');
6334
- if ($handle === false) {
6335
- return null;
6336
- }
6337
- $firstFour = @fread($handle, 4);
6338
- if ($firstFour === false) {
6339
- return null;
6340
- }
6341
- $key = strtoupper(bin2hex($firstFour));
6342
- if (isset($known[$key])) {
6343
- return $known[$key];
6344
- }
6345
- }
6346
- }
6347
-
6348
- ?><?php
6349
-
6350
- namespace ImageMimeTypeGuesser\Detectors;
6351
-
6352
- class Stack extends AbstractDetector
6353
- {
6354
- /**
6355
- * Try to detect mime type of image using all available detectors.
6356
- *
6357
- * Returns:
6358
- * - mime type (string) (if it is in fact an image, and type could be determined)
6359
- * - false (if it is not an image type that the server knowns about)
6360
- * - null (if nothing can be determined)
6361
- *
6362
- * @param string $filePath The path to the file
6363
- * @return string|false|null mimetype (if it is an image, and type could be determined),
6364
- * false (if it is not an image type that the server knowns about)
6365
- * or null (if nothing can be determined)
6366
- */
6367
- protected function doDetect($filePath)
6368
- {
6369
- $detectors = [
6370
- 'ExifImageType',
6371
- 'FInfo',
6372
- 'SniffFirstFourBytes',
6373
- 'GetImageSize',
6374
- 'MimeContentType',
6375
- ];
6376
-
6377
- foreach ($detectors as $className) {
6378
- $result = call_user_func(
6379
- array("\\ImageMimeTypeGuesser\\Detectors\\" . $className, 'detect'),
6380
- $filePath
6381
- );
6382
- if (!is_null($result)) {
6383
- return $result;
6384
- }
6385
- }
6386
-
6387
- return null; // undetermined
6388
- }
6389
- }
6390
-
142
 
143
  namespace WebPConvert\Convert\Converters;
144
 
145
+ use WebPConvert\Helpers\InputValidator;
146
+ use WebPConvert\Helpers\MimeType;
147
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
 
148
  use WebPConvert\Convert\Converters\BaseTraits\AutoQualityTrait;
149
  use WebPConvert\Convert\Converters\BaseTraits\DestinationPreparationTrait;
150
  use WebPConvert\Convert\Converters\BaseTraits\LoggerTrait;
151
  use WebPConvert\Convert\Converters\BaseTraits\OptionsTrait;
 
152
  use WebPConvert\Convert\Converters\BaseTraits\WarningLoggerTrait;
153
+ use WebPConvert\Exceptions\WebPConvertException;
154
  use WebPConvert\Loggers\BaseLogger;
155
 
 
 
156
  /**
157
  * Base for all converter classes.
158
  *
166
  use OptionsTrait;
167
  use WarningLoggerTrait;
168
  use DestinationPreparationTrait;
 
169
  use LoggerTrait;
170
 
171
  /**
203
  /** @var string Where to save the webp (complete path) */
204
  protected $destination;
205
 
 
 
 
206
  /**
207
  * Check basis operationality
208
  *
245
  */
246
  public function __construct($source, $destination, $options = [], $logger = null)
247
  {
248
+ InputValidator::checkSourceAndDestination($source, $destination);
249
+
250
  $this->source = $source;
251
  $this->destination = $destination;
252
 
254
  $this->setProvidedOptions($options);
255
 
256
  if (!isset($this->options['_skip_input_check'])) {
257
+ $this->log('WebP Convert 2.0.5', 'italic');
258
  $this->logLn(' ignited.');
259
  $this->logLn('- PHP version: ' . phpversion());
260
  if (isset($_SERVER['SERVER_SOFTWARE'])) {
263
  $this->logLn('');
264
  $this->logLn(self::getConverterDisplayName() . ' converter ignited');
265
  }
 
 
 
266
  }
267
 
268
  /**
370
  $this->removeExistingDestinationIfExists();
371
 
372
  if (!isset($this->options['_skip_input_check'])) {
 
 
 
 
373
  // Check that a file can be written to destination
374
  $this->checkDestinationWritable();
375
  }
507
  */
508
  public function getMimeTypeOfSource()
509
  {
510
+ return MimeType::getMimeTypeDetectionResult($this->source);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
  }
512
  }
513
 
1678
 
1679
  namespace WebPConvert\Convert\Converters\BaseTraits;
1680
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1681
  /**
1682
  * Trait for handling warnings (by logging them)
1683
  *
5465
 
5466
  ?><?php
5467
 
5468
+ namespace WebPConvert\Helpers;
5469
+
5470
+ use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
5471
+
5472
+ use WebPConvert\Exceptions\InvalidInputException;
5473
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
5474
+
5475
+ /**
5476
+ * Get MimeType, results cached by path.
5477
+ *
5478
+ * @package WebPConvert
5479
+ * @author Bjørn Rosell <it@rosell.dk>
5480
+ * @since Class available since Release 2.0.6
5481
+ */
5482
+ class MimeType
5483
+ {
5484
+ private static $cachedDetections = [];
5485
+
5486
+ /**
5487
+ * Get mime type for image (best guess).
5488
+ *
5489
+ * It falls back to using file extension. If that fails too, false is returned
5490
+ *
5491
+ * @return string|false|null mimetype (if it is an image, and type could be determined / guessed),
5492
+ * false (if it is not an image type that the server knowns about)
5493
+ * or null (if nothing can be determined)
5494
+ */
5495
+ public static function getMimeTypeDetectionResult($absFilePath)
5496
+ {
5497
+ PathChecker::checkAbsolutePathAndExists($absFilePath);
5498
+
5499
+ if (isset(self::$cachedDetections[$absFilePath])) {
5500
+ return self::$cachedDetections[$absFilePath];
5501
+ }
5502
+ $cachedDetections[$absFilePath] = ImageMimeTypeGuesser::lenientGuess($absFilePath);
5503
+ return $cachedDetections[$absFilePath];
5504
+ }
5505
+ }
5506
+
5507
+ ?><?php
5508
+
5509
  namespace WebPConvert\Loggers;
5510
 
5511
  /**
5710
  ?><?php
5711
  namespace WebPConvert\Serve;
5712
 
5713
+ use WebPConvert\Helpers\InputValidator;
5714
  use WebPConvert\Loggers\EchoLogger;
5715
+ use WebPConvert\WebPConvert;
5716
 
5717
  /**
5718
  * Class for generating a HTML report of converting an image.
5725
  {
5726
  public static function convertAndReport($source, $destination, $options)
5727
  {
5728
+ InputValidator::checkSourceAndDestination($source, $destination);
5729
  ?>
5730
  <html>
5731
  <head>
5739
  </head>
5740
  <body>
5741
  <table>
5742
+ <tr><td><i>source:</i></td><td><?php echo htmlentities($source) ?></td></tr>
5743
+ <tr><td><i>destination:</i></td><td><?php echo htmlentities($destination) ?><td></tr>
5744
  </table>
5745
  <br>
5746
  <?php
5773
  public $description = 'Failed serving';
5774
  }
5775
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/rosell-dk/webp-convert/src/Convert/Converters/AbstractConverter.php CHANGED
@@ -5,18 +5,17 @@
5
 
6
  namespace WebPConvert\Convert\Converters;
7
 
 
 
8
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
9
- use WebPConvert\Exceptions\WebPConvertException;
10
  use WebPConvert\Convert\Converters\BaseTraits\AutoQualityTrait;
11
  use WebPConvert\Convert\Converters\BaseTraits\DestinationPreparationTrait;
12
  use WebPConvert\Convert\Converters\BaseTraits\LoggerTrait;
13
  use WebPConvert\Convert\Converters\BaseTraits\OptionsTrait;
14
- use WebPConvert\Convert\Converters\BaseTraits\SourceValidationTrait;
15
  use WebPConvert\Convert\Converters\BaseTraits\WarningLoggerTrait;
 
16
  use WebPConvert\Loggers\BaseLogger;
17
 
18
- use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
19
-
20
  /**
21
  * Base for all converter classes.
22
  *
@@ -30,7 +29,6 @@ abstract class AbstractConverter
30
  use OptionsTrait;
31
  use WarningLoggerTrait;
32
  use DestinationPreparationTrait;
33
- use SourceValidationTrait;
34
  use LoggerTrait;
35
 
36
  /**
@@ -68,9 +66,6 @@ abstract class AbstractConverter
68
  /** @var string Where to save the webp (complete path) */
69
  protected $destination;
70
 
71
- /** @var string|false|null Where to save the webp (complete path) */
72
- private $sourceMimeType;
73
-
74
  /**
75
  * Check basis operationality
76
  *
@@ -113,6 +108,8 @@ abstract class AbstractConverter
113
  */
114
  public function __construct($source, $destination, $options = [], $logger = null)
115
  {
 
 
116
  $this->source = $source;
117
  $this->destination = $destination;
118
 
@@ -120,7 +117,7 @@ abstract class AbstractConverter
120
  $this->setProvidedOptions($options);
121
 
122
  if (!isset($this->options['_skip_input_check'])) {
123
- $this->log('WebP Convert 2.0.0', 'italic');
124
  $this->logLn(' ignited.');
125
  $this->logLn('- PHP version: ' . phpversion());
126
  if (isset($_SERVER['SERVER_SOFTWARE'])) {
@@ -129,9 +126,6 @@ abstract class AbstractConverter
129
  $this->logLn('');
130
  $this->logLn(self::getConverterDisplayName() . ' converter ignited');
131
  }
132
-
133
- $this->checkSourceExists();
134
- $this->checkSourceMimeType();
135
  }
136
 
137
  /**
@@ -239,10 +233,6 @@ abstract class AbstractConverter
239
  $this->removeExistingDestinationIfExists();
240
 
241
  if (!isset($this->options['_skip_input_check'])) {
242
- // Run basic input validations (if source exists and if file extension is valid)
243
- $this->checkSourceExists();
244
- $this->checkSourceMimeType();
245
-
246
  // Check that a file can be written to destination
247
  $this->checkDestinationWritable();
248
  }
@@ -380,11 +370,6 @@ abstract class AbstractConverter
380
  */
381
  public function getMimeTypeOfSource()
382
  {
383
- if (!isset($this->sourceMimeType)) {
384
- // PS: Scrutinizer complains that ImageMimeTypeGuesser::lenientGuess could also return a boolean
385
- // but this is not true! - it returns string|false|null, just as this method does.
386
- $this->sourceMimeType = ImageMimeTypeGuesser::lenientGuess($this->source);
387
- }
388
- return $this->sourceMimeType;
389
  }
390
  }
5
 
6
  namespace WebPConvert\Convert\Converters;
7
 
8
+ use WebPConvert\Helpers\InputValidator;
9
+ use WebPConvert\Helpers\MimeType;
10
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
 
11
  use WebPConvert\Convert\Converters\BaseTraits\AutoQualityTrait;
12
  use WebPConvert\Convert\Converters\BaseTraits\DestinationPreparationTrait;
13
  use WebPConvert\Convert\Converters\BaseTraits\LoggerTrait;
14
  use WebPConvert\Convert\Converters\BaseTraits\OptionsTrait;
 
15
  use WebPConvert\Convert\Converters\BaseTraits\WarningLoggerTrait;
16
+ use WebPConvert\Exceptions\WebPConvertException;
17
  use WebPConvert\Loggers\BaseLogger;
18
 
 
 
19
  /**
20
  * Base for all converter classes.
21
  *
29
  use OptionsTrait;
30
  use WarningLoggerTrait;
31
  use DestinationPreparationTrait;
 
32
  use LoggerTrait;
33
 
34
  /**
66
  /** @var string Where to save the webp (complete path) */
67
  protected $destination;
68
 
 
 
 
69
  /**
70
  * Check basis operationality
71
  *
108
  */
109
  public function __construct($source, $destination, $options = [], $logger = null)
110
  {
111
+ InputValidator::checkSourceAndDestination($source, $destination);
112
+
113
  $this->source = $source;
114
  $this->destination = $destination;
115
 
117
  $this->setProvidedOptions($options);
118
 
119
  if (!isset($this->options['_skip_input_check'])) {
120
+ $this->log('WebP Convert 2.0.5', 'italic');
121
  $this->logLn(' ignited.');
122
  $this->logLn('- PHP version: ' . phpversion());
123
  if (isset($_SERVER['SERVER_SOFTWARE'])) {
126
  $this->logLn('');
127
  $this->logLn(self::getConverterDisplayName() . ' converter ignited');
128
  }
 
 
 
129
  }
130
 
131
  /**
233
  $this->removeExistingDestinationIfExists();
234
 
235
  if (!isset($this->options['_skip_input_check'])) {
 
 
 
 
236
  // Check that a file can be written to destination
237
  $this->checkDestinationWritable();
238
  }
370
  */
371
  public function getMimeTypeOfSource()
372
  {
373
+ return MimeType::getMimeTypeDetectionResult($this->source);
 
 
 
 
 
374
  }
375
  }
vendor/rosell-dk/webp-convert/src/Convert/Converters/BaseTraits/SourceValidationTrait.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
-
3
- namespace WebPConvert\Convert\Converters\BaseTraits;
4
-
5
- use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\TargetNotFoundException;
6
- use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\InvalidImageTypeException;
7
-
8
- /**
9
- * Trait for handling options
10
- *
11
- * This trait is currently only used in the AbstractConverter class. It has been extracted into a
12
- * trait in order to bundle the methods concerning options.
13
- *
14
- * @package WebPConvert
15
- * @author Bjørn Rosell <it@rosell.dk>
16
- * @since Class available since Release 2.0.0
17
- */
18
- trait SourceValidationTrait
19
- {
20
-
21
- abstract protected function getMimeTypeOfSource();
22
- abstract public function getSource();
23
-
24
- /** @var array Array of allowed mime types for source. */
25
- public static $allowedMimeTypes = ['image/jpeg', 'image/png'];
26
-
27
- /**
28
- * Check that source file exists.
29
- *
30
- * Note: As the input validations are only run one time in a stack,
31
- * this method is not overridable
32
- *
33
- * @throws TargetNotFoundException
34
- * @return void
35
- */
36
- private function checkSourceExists()
37
- {
38
- // Check if source exists
39
- if (!@file_exists($this->getSource())) {
40
- throw new TargetNotFoundException('File or directory not found: ' . $this->getSource());
41
- }
42
- }
43
-
44
- /**
45
- * Check that source has a valid mime type.
46
- *
47
- * Note: As the input validations are only run one time in a stack,
48
- * this method is not overridable
49
- *
50
- * @throws InvalidImageTypeException If mime type could not be detected or is unsupported
51
- * @return void
52
- */
53
- private function checkSourceMimeType()
54
- {
55
- $fileMimeType = $this->getMimeTypeOfSource();
56
- if (is_null($fileMimeType)) {
57
- throw new InvalidImageTypeException('Image type could not be detected');
58
- } elseif ($fileMimeType === false) {
59
- throw new InvalidImageTypeException('File seems not to be an image.');
60
- } elseif (!in_array($fileMimeType, self::$allowedMimeTypes)) {
61
- throw new InvalidImageTypeException('Unsupported mime type: ' . $fileMimeType);
62
- }
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/rosell-dk/webp-convert/src/Exceptions/InvalidInput/InvalidImageTypeException.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPConvert\Exceptions\InvalidInput;
4
+
5
+ use WebPConvert\Exceptions\InvalidInputException;
6
+
7
+ class InvalidImageTypeException extends InvalidInputException
8
+ {
9
+ public $description = 'The converter does not handle the supplied image type';
10
+ }
vendor/rosell-dk/webp-convert/src/Exceptions/InvalidInput/TargetNotFoundException.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPConvert\Exceptions\InvalidInput;
4
+
5
+ use WebPConvert\Exceptions\InvalidInputException;
6
+
7
+ class TargetNotFoundException extends InvalidInputException
8
+ {
9
+ public $description = 'The converter could not locate source file';
10
+ }
vendor/rosell-dk/webp-convert/src/Exceptions/InvalidInputException.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPConvert\Exceptions;
4
+
5
+ use WebPConvert\Exceptions\WebPConvertException;
6
+
7
+ class InvalidInputException extends WebPConvertException
8
+ {
9
+ public $description = 'Invalid input';
10
+ }
vendor/rosell-dk/webp-convert/src/Helpers/InputValidator.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPConvert\Helpers;
4
+
5
+ use WebPConvert\Helpers\MimeType;
6
+ use WebPConvert\Helpers\PathChecker;
7
+ use WebPConvert\Exceptions\InvalidInputException;
8
+ use WebPConvert\Exceptions\InvalidInput\InvalidImageTypeException;
9
+
10
+ /**
11
+ * Functions for sanitizing.
12
+ *
13
+ * @package WebPConvert
14
+ * @author Bjørn Rosell <it@rosell.dk>
15
+ * @since Class available since Release 2.0.6
16
+ */
17
+ class InputValidator
18
+ {
19
+
20
+ private static $allowedMimeTypes = [
21
+ 'image/jpeg',
22
+ 'image/png'
23
+ ];
24
+
25
+ /**
26
+ * Check mimetype and if file path is ok and exists
27
+ */
28
+ public static function checkMimeType($filePath, $allowedMimeTypes = null)
29
+ {
30
+ if (is_null($allowedMimeTypes)) {
31
+ $allowedMimeTypes = self::$allowedMimeTypes;
32
+ }
33
+ // the following also tests that file path is ok and file exists
34
+ $fileMimeType = MimeType::getMimeTypeDetectionResult($filePath);
35
+
36
+ if (is_null($fileMimeType)) {
37
+ throw new InvalidImageTypeException('Image type could not be detected');
38
+ } elseif ($fileMimeType === false) {
39
+ throw new InvalidImageTypeException('File seems not to be an image.');
40
+ } elseif (!in_array($fileMimeType, $allowedMimeTypes)) {
41
+ throw new InvalidImageTypeException('Unsupported mime type: ' . $fileMimeType);
42
+ }
43
+ }
44
+
45
+ public static function checkSource($source)
46
+ {
47
+ PathChecker::checkSourcePath($source);
48
+ self::checkMimeType($source);
49
+ }
50
+
51
+ public static function checkDestination($destination)
52
+ {
53
+ PathChecker::checkDestinationPath($destination);
54
+ }
55
+
56
+ public static function checkSourceAndDestination($source, $destination)
57
+ {
58
+ self::checkSource($source);
59
+ self::checkDestination($destination);
60
+ }
61
+ }
vendor/rosell-dk/webp-convert/src/Helpers/MimeType.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPConvert\Helpers;
4
+
5
+ use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
6
+
7
+ use WebPConvert\Exceptions\InvalidInputException;
8
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
9
+
10
+ /**
11
+ * Get MimeType, results cached by path.
12
+ *
13
+ * @package WebPConvert
14
+ * @author Bjørn Rosell <it@rosell.dk>
15
+ * @since Class available since Release 2.0.6
16
+ */
17
+ class MimeType
18
+ {
19
+ private static $cachedDetections = [];
20
+
21
+ /**
22
+ * Get mime type for image (best guess).
23
+ *
24
+ * It falls back to using file extension. If that fails too, false is returned
25
+ *
26
+ * @return string|false|null mimetype (if it is an image, and type could be determined / guessed),
27
+ * false (if it is not an image type that the server knowns about)
28
+ * or null (if nothing can be determined)
29
+ */
30
+ public static function getMimeTypeDetectionResult($absFilePath)
31
+ {
32
+ PathChecker::checkAbsolutePathAndExists($absFilePath);
33
+
34
+ if (isset(self::$cachedDetections[$absFilePath])) {
35
+ return self::$cachedDetections[$absFilePath];
36
+ }
37
+ $cachedDetections[$absFilePath] = ImageMimeTypeGuesser::lenientGuess($absFilePath);
38
+ return $cachedDetections[$absFilePath];
39
+ }
40
+ }
vendor/rosell-dk/webp-convert/src/Helpers/PathChecker.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPConvert\Helpers;
4
+
5
+ use WebPConvert\Exceptions\InvalidInputException;
6
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
7
+
8
+ /**
9
+ * Functions for sanitizing.
10
+ *
11
+ * @package WebPConvert
12
+ * @author Bjørn Rosell <it@rosell.dk>
13
+ * @since Class available since Release 2.0.6
14
+ */
15
+ class PathChecker
16
+ {
17
+
18
+ /**
19
+ * Check absolute file path to prevent attacks.
20
+ *
21
+ * - Prevents non printable characters
22
+ * - Prevents stream wrappers
23
+ * - Prevents directory traversal
24
+ *
25
+ * Preventing non printable characters is especially done to prevent the NUL character, which can be used
26
+ * to bypass other tests. See https://st-g.de/2011/04/doing-filename-checks-securely-in-PHP.
27
+ *
28
+ * Preventeng stream wrappers is especially done to protect against Phar Deserialization.
29
+ * See https://blog.ripstech.com/2018/new-php-exploitation-technique/
30
+ *
31
+ * @param string $absFilePath
32
+ * @return string sanitized file path
33
+ */
34
+ public static function checkAbsolutePath($absFilePath, $text = 'file')
35
+ {
36
+ if (empty($absFilePath)) {
37
+ throw new InvalidInputException('Empty filepath for ' . $text);
38
+ }
39
+
40
+ // Prevent non printable characters
41
+ if (!ctype_print($absFilePath)) {
42
+ throw new InvalidInputException('Non-printable characters are not allowed in ' . $text);
43
+ }
44
+
45
+ // Prevent directory traversal
46
+ if (preg_match('#\.\.\/#', $absFilePath)) {
47
+ throw new InvalidInputException('Directory traversal is not allowed in ' . $text . ' path');
48
+ }
49
+
50
+ // Prevent stream wrappers ("phar://", "php://" and the like)
51
+ // https://www.php.net/manual/en/wrappers.phar.php
52
+ if (preg_match('#^\\w+://#', $absFilePath)) {
53
+ throw new InvalidInputException('Stream wrappers are not allowed in ' . $text . ' path');
54
+ }
55
+ }
56
+
57
+ public static function checkAbsolutePathAndExists($absFilePath, $text = 'file')
58
+ {
59
+ if (empty($absFilePath)) {
60
+ throw new TargetNotFoundException($text . ' argument missing');
61
+ }
62
+ self::checkAbsolutePath($absFilePath, $text);
63
+ if (@!file_exists($absFilePath)) {
64
+ throw new TargetNotFoundException($text . ' file was not found');
65
+ }
66
+ if (@is_dir($absFilePath)) {
67
+ throw new InvalidInputException($text . ' is a directory');
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Checks that source path is secure, file exists and it is not a dir.
73
+ *
74
+ * To also check mime type, use InputValidator::checkSource
75
+ */
76
+ public static function checkSourcePath($source)
77
+ {
78
+ self::checkAbsolutePathAndExists($source, 'source');
79
+ }
80
+
81
+ public static function checkDestinationPath($destination)
82
+ {
83
+ if (empty($destination)) {
84
+ throw new InvalidInputException('Destination argument missing');
85
+ }
86
+ self::checkAbsolutePath($destination, 'destination');
87
+ if (@is_dir($destination)) {
88
+ throw new InvalidInputException('Destination is a directory');
89
+ }
90
+ }
91
+
92
+ public static function checkSourceAndDestinationPaths($source, $destination)
93
+ {
94
+ self::checkSourcePath($source);
95
+ self::checkDestinationPath($destination);
96
+ }
97
+ }
vendor/rosell-dk/webp-convert/src/Serve/Report.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
2
  namespace WebPConvert\Serve;
3
 
4
- use WebPConvert\WebPConvert;
5
  use WebPConvert\Loggers\EchoLogger;
 
6
 
7
  /**
8
  * Class for generating a HTML report of converting an image.
@@ -15,6 +16,7 @@ class Report
15
  {
16
  public static function convertAndReport($source, $destination, $options)
17
  {
 
18
  ?>
19
  <html>
20
  <head>
@@ -28,8 +30,8 @@ class Report
28
  </head>
29
  <body>
30
  <table>
31
- <tr><td><i>source:</i></td><td><?php echo $source ?></td></tr>
32
- <tr><td><i>destination:</i></td><td><?php echo $destination ?><td></tr>
33
  </table>
34
  <br>
35
  <?php
1
  <?php
2
  namespace WebPConvert\Serve;
3
 
4
+ use WebPConvert\Helpers\InputValidator;
5
  use WebPConvert\Loggers\EchoLogger;
6
+ use WebPConvert\WebPConvert;
7
 
8
  /**
9
  * Class for generating a HTML report of converting an image.
16
  {
17
  public static function convertAndReport($source, $destination, $options)
18
  {
19
+ InputValidator::checkSourceAndDestination($source, $destination);
20
  ?>
21
  <html>
22
  <head>
30
  </head>
31
  <body>
32
  <table>
33
+ <tr><td><i>source:</i></td><td><?php echo htmlentities($source) ?></td></tr>
34
+ <tr><td><i>destination:</i></td><td><?php echo htmlentities($destination) ?><td></tr>
35
  </table>
36
  <br>
37
  <?php
vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebP.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
  namespace WebPConvert\Serve;
3
 
4
- use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
5
-
6
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
 
 
7
  use WebPConvert\Serve\Exceptions\ServeFailedException;
8
  use WebPConvert\Serve\Header;
9
  use WebPConvert\Serve\Report;
@@ -71,7 +71,8 @@ class ServeConvertedWebP
71
  */
72
  public static function serveOriginal($source, $serveImageOptions = [])
73
  {
74
- $contentType = ImageMimeTypeGuesser::lenientGuess($source);
 
75
  if (is_null($contentType)) {
76
  throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
77
  } elseif ($contentType === false) {
@@ -84,6 +85,8 @@ class ServeConvertedWebP
84
  /**
85
  * Serve destination file.
86
  *
 
 
87
  * @param string $destination path to destination file
88
  * @param array $serveImageOptions (optional) options for serving (such as which headers to add)
89
  * Supported options:
@@ -92,6 +95,7 @@ class ServeConvertedWebP
92
  */
93
  public static function serveDestination($destination, $serveImageOptions = [])
94
  {
 
95
  ServeFile::serve($destination, 'image/webp', $serveImageOptions);
96
  }
97
 
@@ -127,16 +131,7 @@ class ServeConvertedWebP
127
  */
128
  public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
129
  {
130
-
131
- if (empty($source)) {
132
- throw new ServeFailedException('Source argument missing');
133
- }
134
- if (empty($destination)) {
135
- throw new ServeFailedException('Destination argument missing');
136
- }
137
- if (@!file_exists($source)) {
138
- throw new ServeFailedException('Source file was not found');
139
- }
140
 
141
  $options = self::processOptions($options);
142
 
1
  <?php
2
  namespace WebPConvert\Serve;
3
 
 
 
4
  use WebPConvert\Convert\Exceptions\ConversionFailedException;
5
+ use WebPConvert\Helpers\InputValidator;
6
+ use WebPConvert\Helpers\MimeType;
7
  use WebPConvert\Serve\Exceptions\ServeFailedException;
8
  use WebPConvert\Serve\Header;
9
  use WebPConvert\Serve\Report;
71
  */
72
  public static function serveOriginal($source, $serveImageOptions = [])
73
  {
74
+ InputValidator::checkSource($source);
75
+ $contentType = MimeType::getMimeTypeDetectionResult($source);
76
  if (is_null($contentType)) {
77
  throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
78
  } elseif ($contentType === false) {
85
  /**
86
  * Serve destination file.
87
  *
88
+ * TODO: SHould this really be public?
89
+ *
90
  * @param string $destination path to destination file
91
  * @param array $serveImageOptions (optional) options for serving (such as which headers to add)
92
  * Supported options:
95
  */
96
  public static function serveDestination($destination, $serveImageOptions = [])
97
  {
98
+ InputValidator::checkDestination($destination);
99
  ServeFile::serve($destination, 'image/webp', $serveImageOptions);
100
  }
101
 
131
  */
132
  public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
133
  {
134
+ InputValidator::checkSourceAndDestination($source, $destination);
 
 
 
 
 
 
 
 
 
135
 
136
  $options = self::processOptions($options);
137
 
vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebPWithErrorHandling.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  namespace WebPConvert\Serve;
3
 
 
4
  use WebPConvert\Options\Options;
5
  use WebPConvert\Options\StringOption;
6
  use WebPConvert\Serve\Header;
@@ -68,7 +69,6 @@ class ServeConvertedWebPWithErrorHandling
68
  {
69
  self::addHeadersPreventingCaching();
70
 
71
- //Header::addLogHeader('Failure');
72
  Header::addLogHeader('Performing fail action: ' . $fail);
73
 
74
  switch ($fail) {
@@ -135,9 +135,10 @@ class ServeConvertedWebPWithErrorHandling
135
  $convertLogger = null,
136
  $serveClass = '\\WebPConvert\\Serve\\ServeConvertedWebP'
137
  ) {
138
- $options = self::processOptions($options);
139
 
 
140
  try {
 
141
  //ServeConvertedWebP::serve($source, $destination, $options, $serveLogger);
142
  call_user_func($serveClass . '::serve', $source, $destination, $options, $serveLogger, $convertLogger);
143
  } catch (\Exception $e) {
1
  <?php
2
  namespace WebPConvert\Serve;
3
 
4
+ use WebPConvert\Helpers\InputValidator;
5
  use WebPConvert\Options\Options;
6
  use WebPConvert\Options\StringOption;
7
  use WebPConvert\Serve\Header;
69
  {
70
  self::addHeadersPreventingCaching();
71
 
 
72
  Header::addLogHeader('Performing fail action: ' . $fail);
73
 
74
  switch ($fail) {
135
  $convertLogger = null,
136
  $serveClass = '\\WebPConvert\\Serve\\ServeConvertedWebP'
137
  ) {
 
138
 
139
+ $options = self::processOptions($options);
140
  try {
141
+ InputValidator::checkSourceAndDestination($source, $destination);
142
  //ServeConvertedWebP::serve($source, $destination, $options, $serveLogger);
143
  call_user_func($serveClass . '::serve', $source, $destination, $options, $serveLogger, $convertLogger);
144
  } catch (\Exception $e) {
vendor/rosell-dk/webp-convert/src/Serve/ServeFile.php CHANGED
@@ -2,6 +2,7 @@
2
  namespace WebPConvert\Serve;
3
 
4
  //use WebPConvert\Serve\Report;
 
5
  use WebPConvert\Options\ArrayOption;
6
  use WebPConvert\Options\BooleanOption;
7
  use WebPConvert\Options\Options;
@@ -78,10 +79,19 @@ class ServeFile
78
  */
79
  public static function serve($filename, $contentType, $options = [])
80
  {
 
 
 
 
 
 
 
 
 
81
  if (!file_exists($filename)) {
82
  Header::addHeader('X-WebP-Convert-Error: Could not read file');
83
  throw new ServeFailedException('Could not read file');
84
- }
85
 
86
  $options = self::processOptions($options);
87
 
2
  namespace WebPConvert\Serve;
3
 
4
  //use WebPConvert\Serve\Report;
5
+ use WebPConvert\Helpers\InputValidator;
6
  use WebPConvert\Options\ArrayOption;
7
  use WebPConvert\Options\BooleanOption;
8
  use WebPConvert\Options\Options;
79
  */
80
  public static function serve($filename, $contentType, $options = [])
81
  {
82
+ // Check mimetype - this also checks that path is secure and file exists
83
+ InputValidator::checkMimeType($filename, [
84
+ 'image/jpeg',
85
+ 'image/png',
86
+ 'image/webp',
87
+ 'image/gif'
88
+ ]);
89
+
90
+ /*
91
  if (!file_exists($filename)) {
92
  Header::addHeader('X-WebP-Convert-Error: Could not read file');
93
  throw new ServeFailedException('Could not read file');
94
+ }*/
95
 
96
  $options = self::processOptions($options);
97
 
vendor/rosell-dk/webp-convert/tests/Convert/Converters/AbstractConverterTest.php CHANGED
@@ -12,14 +12,22 @@ use PHPUnit\Framework\TestCase;
12
  class AbstractConverterTest extends TestCase
13
  {
14
 
15
- private static $imgDir = __DIR__ . '/../../images';
 
 
 
 
 
 
 
 
16
 
17
 
18
  public function testConvert()
19
  {
20
  SuccessGuaranteedConverter::convert(
21
- self::$imgDir . '/test.jpg',
22
- self::$imgDir . '/test.webp'
23
  );
24
  $this->addToAssertionCount(1);
25
  }
@@ -31,13 +39,22 @@ class AbstractConverterTest extends TestCase
31
  //$this->assertEquals('image/png', ExposedConverter::exposedGetMimeType(self::$imgDir . '/test.png'));
32
  //$mimeTypeMaybeDetected = ExposedConverter::exposedGetMimeType(self::$imgDir . '/png-without-extension');
33
 
34
- $successConverterJpeg = SuccessGuaranteedConverter::createInstance(self::$imgDir . '/test.jpg', '');
 
 
 
35
  $this->assertEquals('image/jpeg', $successConverterJpeg->getMimeTypeOfSource());
36
 
37
- $successConverterPng = SuccessGuaranteedConverter::createInstance(self::$imgDir . '/test.png', '');
 
 
 
38
  $this->assertEquals('image/png', $successConverterPng->getMimeTypeOfSource());
39
 
40
- $successConverterPngMaybeDetected = SuccessGuaranteedConverter::createInstance(self::$imgDir . '/png-without-extension', '');
 
 
 
41
 
42
  $mimeTypeMaybeDetected = $successConverterPngMaybeDetected->getMimeTypeOfSource();
43
 
@@ -54,8 +71,8 @@ class AbstractConverterTest extends TestCase
54
  public function testDefaultOptions()
55
  {
56
  $converter = new SuccessGuaranteedConverter(
57
- self::$imgDir . '/test.jpg',
58
- self::$imgDir . '/test.webp'
59
  );
60
 
61
  $exposer = new AbstractConverterExposer($converter);
@@ -72,8 +89,8 @@ class AbstractConverterTest extends TestCase
72
  public function testOptionMerging()
73
  {
74
  $converter = new SuccessGuaranteedConverter(
75
- self::$imgDir . '/test.jpg',
76
- self::$imgDir . '/test.webp',
77
  [
78
  'quality' => 80
79
  ]
12
  class AbstractConverterTest extends TestCase
13
  {
14
 
15
+ public static function getImageFolder()
16
+ {
17
+ return realpath(__DIR__ . '/../../images');
18
+ }
19
+
20
+ public static function getImagePath($image)
21
+ {
22
+ return self::getImageFolder() . '/' . $image;
23
+ }
24
 
25
 
26
  public function testConvert()
27
  {
28
  SuccessGuaranteedConverter::convert(
29
+ self::getImagePath('test.jpg'),
30
+ self::getImagePath('test.webp')
31
  );
32
  $this->addToAssertionCount(1);
33
  }
39
  //$this->assertEquals('image/png', ExposedConverter::exposedGetMimeType(self::$imgDir . '/test.png'));
40
  //$mimeTypeMaybeDetected = ExposedConverter::exposedGetMimeType(self::$imgDir . '/png-without-extension');
41
 
42
+ $successConverterJpeg = SuccessGuaranteedConverter::createInstance(
43
+ self::getImagePath('test.jpg'),
44
+ self::getImagePath('test.jpg.webp')
45
+ );
46
  $this->assertEquals('image/jpeg', $successConverterJpeg->getMimeTypeOfSource());
47
 
48
+ $successConverterPng = SuccessGuaranteedConverter::createInstance(
49
+ self::getImagePath('test.png'),
50
+ self::getImagePath('test.png.webp')
51
+ );
52
  $this->assertEquals('image/png', $successConverterPng->getMimeTypeOfSource());
53
 
54
+ $successConverterPngMaybeDetected = SuccessGuaranteedConverter::createInstance(
55
+ self::getImagePath('png-without-extension'),
56
+ self::getImagePath('png-without-extension.webp')
57
+ );
58
 
59
  $mimeTypeMaybeDetected = $successConverterPngMaybeDetected->getMimeTypeOfSource();
60
 
71
  public function testDefaultOptions()
72
  {
73
  $converter = new SuccessGuaranteedConverter(
74
+ self::getImagePath('test.jpg'),
75
+ self::getImagePath('test.jpg.webp')
76
  );
77
 
78
  $exposer = new AbstractConverterExposer($converter);
89
  public function testOptionMerging()
90
  {
91
  $converter = new SuccessGuaranteedConverter(
92
+ self::getImagePath('test.jpg'),
93
+ self::getImagePath('test.webp'),
94
  [
95
  'quality' => 80
96
  ]
vendor/rosell-dk/webp-convert/tests/Convert/Converters/BaseTraits/AutoQualityTraitTest.php CHANGED
@@ -10,13 +10,21 @@ use PHPUnit\Framework\TestCase;
10
  class AutoQualityTraitTest extends TestCase
11
  {
12
 
13
- private static $imgDir = __DIR__ . '/../../../images';
 
 
 
 
 
 
 
 
14
 
15
  public function testFixedQuality()
16
  {
17
  $converter = SuccessGuaranteedConverter::createInstance(
18
- self::$imgDir . '/small-q61.jpg',
19
- self::$imgDir . '/small-q61.jpg.webp',
20
  [
21
  'max-quality' => 80,
22
  'quality' => 75,
@@ -55,8 +63,8 @@ class AutoQualityTraitTest extends TestCase
55
  public function testAutoQuality()
56
  {
57
  $converter = SuccessGuaranteedConverter::createInstance(
58
- self::$imgDir . '/small-q61.jpg',
59
- self::$imgDir . '/small-q61.jpg.webp',
60
  [
61
  'max-quality' => 80,
62
  'quality' => 'auto',
@@ -75,8 +83,8 @@ class AutoQualityTraitTest extends TestCase
75
  public function testAutoQualityMaxQuality()
76
  {
77
  $converter = SuccessGuaranteedConverter::createInstance(
78
- self::$imgDir . '/small-q61.jpg',
79
- self::$imgDir . '/small-q61.jpg.webp',
80
  [
81
  'max-quality' => 60,
82
  'quality' => 'auto',
@@ -96,8 +104,8 @@ class AutoQualityTraitTest extends TestCase
96
  public function testAutoQualityMaxQualityOnNonJpeg()
97
  {
98
  $converter = SuccessGuaranteedConverter::createInstance(
99
- self::$imgDir . '/test.png',
100
- self::$imgDir . '/test.png.webp',
101
  [
102
  'max-quality' => 60,
103
  'quality' => 'auto',
@@ -135,8 +143,8 @@ class AutoQualityTraitTest extends TestCase
135
  public function testAutoQualityOnQualityDetectionFail2()
136
  {
137
  $converter = SuccessGuaranteedConverter::createInstance(
138
- self::$imgDir . '/text-with-jpg-extension.jpg',
139
- self::$imgDir . '/text-with-jpg-extension.jpg.webp',
140
  [
141
  'max-quality' => 70,
142
  'quality' => 'auto',
@@ -144,7 +152,7 @@ class AutoQualityTraitTest extends TestCase
144
  ]
145
  );
146
 
147
- $this->assertFalse(file_exists(self::$imgDir . '/non-existing.jpg'));
148
 
149
  // We are using the lenient MimeType guesser.
150
  // So we get "image/jpeg" even though the file is not a jpeg file
10
  class AutoQualityTraitTest extends TestCase
11
  {
12
 
13
+ public static function getImageFolder()
14
+ {
15
+ return realpath(__DIR__ . '/../../../images');
16
+ }
17
+
18
+ public static function getImagePath($image)
19
+ {
20
+ return self::getImageFolder() . '/' . $image;
21
+ }
22
 
23
  public function testFixedQuality()
24
  {
25
  $converter = SuccessGuaranteedConverter::createInstance(
26
+ self::getImagePath('small-q61.jpg'),
27
+ self::getImagePath('small-q61.jpg.webp'),
28
  [
29
  'max-quality' => 80,
30
  'quality' => 75,
63
  public function testAutoQuality()
64
  {
65
  $converter = SuccessGuaranteedConverter::createInstance(
66
+ self::getImagePath('small-q61.jpg'),
67
+ self::getImagePath('small-q61.jpg.webp'),
68
  [
69
  'max-quality' => 80,
70
  'quality' => 'auto',
83
  public function testAutoQualityMaxQuality()
84
  {
85
  $converter = SuccessGuaranteedConverter::createInstance(
86
+ self::getImagePath('small-q61.jpg'),
87
+ self::getImagePath('small-q61.jpg.webp'),
88
  [
89
  'max-quality' => 60,
90
  'quality' => 'auto',
104
  public function testAutoQualityMaxQualityOnNonJpeg()
105
  {
106
  $converter = SuccessGuaranteedConverter::createInstance(
107
+ self::getImagePath('test.png'),
108
+ self::getImagePath('test.png.webp'),
109
  [
110
  'max-quality' => 60,
111
  'quality' => 'auto',
143
  public function testAutoQualityOnQualityDetectionFail2()
144
  {
145
  $converter = SuccessGuaranteedConverter::createInstance(
146
+ self::getImagePath('text-with-jpg-extension.jpg'),
147
+ self::getImagePath('text-with-jpg-extension.jpg.webp'),
148
  [
149
  'max-quality' => 70,
150
  'quality' => 'auto',
152
  ]
153
  );
154
 
155
+ $this->assertFalse(file_exists(self::getImagePath('non-existing.jpg')));
156
 
157
  // We are using the lenient MimeType guesser.
158
  // So we get "image/jpeg" even though the file is not a jpeg file
vendor/rosell-dk/webp-convert/tests/Convert/Converters/ConverterTestHelper.php CHANGED
@@ -15,7 +15,8 @@ use WebPConvert\Convert\Exceptions\ConversionFailed\UnhandledException;
15
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperationalException;
16
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperational\SystemRequirementsNotMetException;
17
  use WebPConvert\Convert\Exceptions\ConversionFailed\FileSystemProblems\CreateDestinationFolderException;
18
- use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\TargetNotFoundException;
 
19
 
20
  class ConverterTestHelper
21
  {
@@ -44,6 +45,16 @@ class ConverterTestHelper
44
  }
45
  }
46
  */
 
 
 
 
 
 
 
 
 
 
47
  private static function callConvert($converterClassName, $source, $destination, $converterOptions)
48
  {
49
  return call_user_func(
@@ -66,7 +77,7 @@ class ConverterTestHelper
66
  $testCase->expectException(CreateDestinationFolderException::class);
67
 
68
  try {
69
- $source = (__DIR__ . '/../../test.jpg');
70
  $destination = '/you-can-delete-me/';
71
  $result = self::callConvert($converterClassName, $source, $destination);
72
  } catch (ConverterNotOperationalException $e) {
@@ -104,7 +115,12 @@ class ConverterTestHelper
104
  $testCase->expectException(TargetNotFoundException::class);
105
 
106
  try {
107
- $result = self::callConvert($converterClassName, __DIR__ . '/i-dont-exist.jpg', __DIR__ . '/i-dont-exist.webp', $converterOptions);
 
 
 
 
 
108
  } catch (ConverterNotOperationalException $e) {
109
  // Converter not operational, and that is ok!
110
  // We shall pretend that the expected exception was thrown, by throwing it!
@@ -123,8 +139,8 @@ class ConverterTestHelper
123
  {
124
 
125
  try {
126
- $source = (__DIR__ . '/../../' . $src);
127
- $destination = (__DIR__ . '/../../' . $src . '.webp');
128
 
129
  $result = self::callConvert($converterClassName, $source, $destination, $converterOptions);
130
 
15
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperationalException;
16
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperational\SystemRequirementsNotMetException;
17
  use WebPConvert\Convert\Exceptions\ConversionFailed\FileSystemProblems\CreateDestinationFolderException;
18
+ //use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\TargetNotFoundException;
19
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
20
 
21
  class ConverterTestHelper
22
  {
45
  }
46
  }
47
  */
48
+ public static function getImageFolder()
49
+ {
50
+ return realpath(__DIR__ . '/../../images');
51
+ }
52
+
53
+ public static function getImagePath($image)
54
+ {
55
+ return self::getImageFolder() . '/' . $image;
56
+ }
57
+
58
  private static function callConvert($converterClassName, $source, $destination, $converterOptions)
59
  {
60
  return call_user_func(
77
  $testCase->expectException(CreateDestinationFolderException::class);
78
 
79
  try {
80
+ $source = self::getImagePath('test.jpg');
81
  $destination = '/you-can-delete-me/';
82
  $result = self::callConvert($converterClassName, $source, $destination);
83
  } catch (ConverterNotOperationalException $e) {
115
  $testCase->expectException(TargetNotFoundException::class);
116
 
117
  try {
118
+ $result = self::callConvert(
119
+ $converterClassName,
120
+ __DIR__ . '/i-dont-exist.jpg',
121
+ __DIR__ . '/i-dont-exist.webp',
122
+ $converterOptions
123
+ );
124
  } catch (ConverterNotOperationalException $e) {
125
  // Converter not operational, and that is ok!
126
  // We shall pretend that the expected exception was thrown, by throwing it!
139
  {
140
 
141
  try {
142
+ $source = self::getImagePath($src);
143
+ $destination = self::getImagePath($src . '.webp');
144
 
145
  $result = self::callConvert($converterClassName, $source, $destination, $converterOptions);
146
 
vendor/rosell-dk/webp-convert/tests/Convert/Converters/CwebpTest.php CHANGED
@@ -24,7 +24,15 @@ use PHPUnit\Framework\TestCase;
24
  class CwebpTest extends TestCase
25
  {
26
 
27
- public static $imageDir = __DIR__ . '/../..';
 
 
 
 
 
 
 
 
28
 
29
  public function testConvert()
30
  {
@@ -33,7 +41,7 @@ class CwebpTest extends TestCase
33
 
34
  public function testSource()
35
  {
36
- $source = self::$imageDir . '/test.png';
37
  $cwebp = new Cwebp($source, $source . '.webp');
38
  $cwebpExposer = new CwebpExposer($cwebp);
39
 
@@ -46,7 +54,7 @@ class CwebpTest extends TestCase
46
  */
47
  public function testCreateCommandLineOptions()
48
  {
49
- $source = self::$imageDir . '/test.png';
50
  $options = [
51
  'quality' => 'auto',
52
  'method' => 3,
@@ -93,7 +101,7 @@ class CwebpTest extends TestCase
93
  */
94
  public function testCreateCommandLineOptions2()
95
  {
96
- $source = self::$imageDir . '/test.png';
97
  $options = [
98
  'quality' => 70,
99
  'method' => 3,
@@ -124,7 +132,7 @@ class CwebpTest extends TestCase
124
  */
125
  public function testCreateCommandLineOptions3()
126
  {
127
- $source = self::$imageDir . '/test.png';
128
  $options = [
129
  'encoding' => 'lossless',
130
  'near-lossless' => 75,
@@ -153,7 +161,7 @@ class CwebpTest extends TestCase
153
  */
154
  public function testCreateCommandLineOptions4()
155
  {
156
- $source = self::$imageDir . '/test.png';
157
  $options = [
158
  'encoding' => 'lossless',
159
  'near-lossless' => 100,
@@ -182,7 +190,7 @@ class CwebpTest extends TestCase
182
  */
183
  public function testOperatinalityException()
184
  {
185
- $source = self::$imageDir . '/test.png';
186
  $options = [
187
  'try-supplied-binary-for-os' => false,
188
  'try-common-system-paths' => false,
@@ -194,7 +202,7 @@ class CwebpTest extends TestCase
194
 
195
  public function testUsingSuppliedBinaryForOS()
196
  {
197
- $source = self::$imageDir . '/test.png';
198
  $options = [
199
  'try-supplied-binary-for-os' => true,
200
  'try-common-system-paths' => false,
24
  class CwebpTest extends TestCase
25
  {
26
 
27
+ public static function getImageFolder()
28
+ {
29
+ return realpath(__DIR__ . '/../../images');
30
+ }
31
+
32
+ public static function getImagePath($image)
33
+ {
34
+ return self::getImageFolder() . '/' . $image;
35
+ }
36
 
37
  public function testConvert()
38
  {
41
 
42
  public function testSource()
43
  {
44
+ $source = self::getImagePath('test.png');
45
  $cwebp = new Cwebp($source, $source . '.webp');
46
  $cwebpExposer = new CwebpExposer($cwebp);
47
 
54
  */
55
  public function testCreateCommandLineOptions()
56
  {
57
+ $source = self::getImagePath('test.png');
58
  $options = [
59
  'quality' => 'auto',
60
  'method' => 3,
101
  */
102
  public function testCreateCommandLineOptions2()
103
  {
104
+ $source = self::getImagePath('test.png');
105
  $options = [
106
  'quality' => 70,
107
  'method' => 3,
132
  */
133
  public function testCreateCommandLineOptions3()
134
  {
135
+ $source = self::getImagePath('test.png');
136
  $options = [
137
  'encoding' => 'lossless',
138
  'near-lossless' => 75,
161
  */
162
  public function testCreateCommandLineOptions4()
163
  {
164
+ $source = self::getImagePath('test.png');
165
  $options = [
166
  'encoding' => 'lossless',
167
  'near-lossless' => 100,
190
  */
191
  public function testOperatinalityException()
192
  {
193
+ $source = self::getImagePath('test.png');
194
  $options = [
195
  'try-supplied-binary-for-os' => false,
196
  'try-common-system-paths' => false,
202
 
203
  public function testUsingSuppliedBinaryForOS()
204
  {
205
+ $source = self::getImagePath('test.png');
206
  $options = [
207
  'try-supplied-binary-for-os' => true,
208
  'try-common-system-paths' => false,
vendor/rosell-dk/webp-convert/tests/Convert/Converters/EwwwTest.php CHANGED
@@ -17,7 +17,15 @@ use WebPConvert\Tests\Convert\TestConverters\ExtendedConverters\EwwwExtended;
17
  class EwwwTest extends TestCase
18
  {
19
 
20
- public $imageDir = __DIR__ . '/../../images/';
 
 
 
 
 
 
 
 
21
 
22
  public function testConvert()
23
  {
@@ -30,7 +38,7 @@ class EwwwTest extends TestCase
30
  {
31
  $this->expectException(InvalidApiKeyException::class);
32
 
33
- $source = $this->imageDir . '/test.png';
34
  Ewww::convert($source, $source . '.webp', [
35
  'api-key' => 'wrong-key!'
36
  ]);
@@ -42,7 +50,7 @@ class EwwwTest extends TestCase
42
 
43
  $wrongKeyRightLength = 'invalid-key-but-hasright-length';
44
 
45
- $source = $this->imageDir . '/test.png';
46
  Ewww::convert($source, $source . '.webp', [
47
  'api-key' => $wrongKeyRightLength
48
  ]);
@@ -54,7 +62,7 @@ class EwwwTest extends TestCase
54
 
55
  $wrongKeyRightLength = 'invalid-key-but-hasright-length';
56
 
57
- $source = $this->imageDir . '/test.png';
58
 
59
  $ee = EwwwExtended::createInstance($source, $source . '.webp', [
60
  'api-key' => $wrongKeyRightLength
17
  class EwwwTest extends TestCase
18
  {
19
 
20
+ public static function getImageFolder()
21
+ {
22
+ return realpath(__DIR__ . '/../../images');
23
+ }
24
+
25
+ public static function getImagePath($image)
26
+ {
27
+ return self::getImageFolder() . '/' . $image;
28
+ }
29
 
30
  public function testConvert()
31
  {
38
  {
39
  $this->expectException(InvalidApiKeyException::class);
40
 
41
+ $source = self::getImagePath('test.png');
42
  Ewww::convert($source, $source . '.webp', [
43
  'api-key' => 'wrong-key!'
44
  ]);
50
 
51
  $wrongKeyRightLength = 'invalid-key-but-hasright-length';
52
 
53
+ $source = self::getImagePath('test.png');
54
  Ewww::convert($source, $source . '.webp', [
55
  'api-key' => $wrongKeyRightLength
56
  ]);
62
 
63
  $wrongKeyRightLength = 'invalid-key-but-hasright-length';
64
 
65
+ $source = self::getImagePath('test.png');
66
 
67
  $ee = EwwwExtended::createInstance($source, $source . '.webp', [
68
  'api-key' => $wrongKeyRightLength
vendor/rosell-dk/webp-convert/tests/Convert/Converters/GdTest.php CHANGED
@@ -12,6 +12,16 @@ use PHPUnit\Framework\TestCase;
12
  class GdTest extends TestCase
13
  {
14
 
 
 
 
 
 
 
 
 
 
 
15
  public function __construct()
16
  {
17
 
@@ -25,7 +35,7 @@ class GdTest extends TestCase
25
 
26
  private function createGd($src)
27
  {
28
- $source = self::$imageDir . '/' . $src;
29
  $this->assertTrue(file_exists($source), 'source does not exist:' . $source);
30
 
31
  return new Gd($source, $source . '.webp');
@@ -110,12 +120,10 @@ class GdTest extends TestCase
110
  $pretend['functionsNotExisting'] = [];
111
  }
112
 
113
- public static $imageDir = __DIR__ . '/../../images';
114
-
115
  public function testSource()
116
  {
117
 
118
- $source = self::$imageDir . '/test.png';
119
  $gd = new Gd($source, $source . '.webp');
120
 
121
  self::resetPretending();
12
  class GdTest extends TestCase
13
  {
14
 
15
+ public static function getImageFolder()
16
+ {
17
+ return realpath(__DIR__ . '/../../images');
18
+ }
19
+
20
+ public static function getImagePath($image)
21
+ {
22
+ return self::getImageFolder() . '/' . $image;
23
+ }
24
+
25
  public function __construct()
26
  {
27
 
35
 
36
  private function createGd($src)
37
  {
38
+ $source = self::getImagePath($src);
39
  $this->assertTrue(file_exists($source), 'source does not exist:' . $source);
40
 
41
  return new Gd($source, $source . '.webp');
120
  $pretend['functionsNotExisting'] = [];
121
  }
122
 
 
 
123
  public function testSource()
124
  {
125
 
126
+ $source = self::getImagePath('test.png');
127
  $gd = new Gd($source, $source . '.webp');
128
 
129
  self::resetPretending();
vendor/rosell-dk/webp-convert/tests/Convert/Converters/GraphicsMagickTest.php CHANGED
@@ -21,7 +21,15 @@ use PHPUnit\Framework\TestCase;
21
  class GraphicsMagickTest extends TestCase
22
  {
23
 
24
- public $imageDir = __DIR__ . '/../../images/';
 
 
 
 
 
 
 
 
25
 
26
  public function testConvert()
27
  {
@@ -48,7 +56,7 @@ class GraphicsMagickTest extends TestCase
48
  }
49
 
50
  public function testWithNice() {
51
- $source = $this->imageDir . '/test.png';
52
  $options = [
53
  'use-nice' => true,
54
  'lossless' => true,
21
  class GraphicsMagickTest extends TestCase
22
  {
23
 
24
+ public static function getImageFolder()
25
+ {
26
+ return realpath(__DIR__ . '/../../images');
27
+ }
28
+
29
+ public static function getImagePath($image)
30
+ {
31
+ return self::getImageFolder() . '/' . $image;
32
+ }
33
 
34
  public function testConvert()
35
  {
56
  }
57
 
58
  public function testWithNice() {
59
+ $source = self::getImagePath('test.png');
60
  $options = [
61
  'use-nice' => true,
62
  'lossless' => true,
vendor/rosell-dk/webp-convert/tests/Convert/Converters/ImageMagickTest.php CHANGED
@@ -17,7 +17,15 @@ use PHPUnit\Framework\TestCase;
17
  class ImageMagickTest extends TestCase
18
  {
19
 
20
- public $imageDir = __DIR__ . '/../../images/';
 
 
 
 
 
 
 
 
21
 
22
  public function testConvert()
23
  {
@@ -44,7 +52,7 @@ class ImageMagickTest extends TestCase
44
  }
45
 
46
  public function testWithNice() {
47
- $source = $this->imageDir . '/test.png';
48
  $options = [
49
  'use-nice' => true,
50
  'encoding' => 'lossless',
17
  class ImageMagickTest extends TestCase
18
  {
19
 
20
+ public static function getImageFolder()
21
+ {
22
+ return realpath(__DIR__ . '/../../images');
23
+ }
24
+
25
+ public static function getImagePath($image)
26
+ {
27
+ return self::getImageFolder() . '/' . $image;
28
+ }
29
 
30
  public function testConvert()
31
  {
52
  }
53
 
54
  public function testWithNice() {
55
+ $source = self::getImagePath('test.png');
56
  $options = [
57
  'use-nice' => true,
58
  'encoding' => 'lossless',
vendor/rosell-dk/webp-convert/tests/Convert/Converters/StackTest.php CHANGED
@@ -11,6 +11,16 @@ use PHPUnit\Framework\TestCase;
11
  class StackTest extends TestCase
12
  {
13
 
 
 
 
 
 
 
 
 
 
 
14
  public function testConvert()
15
  {
16
  //ConverterTestHelper::runAllConvertTests($this, 'Stack');
@@ -21,8 +31,8 @@ class StackTest extends TestCase
21
  $this->expectException(ConverterNotFoundException::class);
22
 
23
  Stack::convert(
24
- __DIR__ . '/../../test.jpg',
25
- __DIR__ . '/../../test.webp',
26
  [
27
  'converters' => ['invalid-id']
28
  ]
@@ -32,8 +42,8 @@ class StackTest extends TestCase
32
  public function testCustomConverter()
33
  {
34
  Stack::convert(
35
- __DIR__ . '/../../test.jpg',
36
- __DIR__ . '/../../test.webp',
37
  [
38
  'converters' => [
39
  '\\WebPConvert\\Tests\\Convert\\TestConverters\\SuccessGuaranteedConverter'
11
  class StackTest extends TestCase
12
  {
13
 
14
+ public static function getImageFolder()
15
+ {
16
+ return realpath(__DIR__ . '/../../images');
17
+ }
18
+
19
+ public static function getImagePath($image)
20
+ {
21
+ return self::getImageFolder() . '/' . $image;
22
+ }
23
+
24
  public function testConvert()
25
  {
26
  //ConverterTestHelper::runAllConvertTests($this, 'Stack');
31
  $this->expectException(ConverterNotFoundException::class);
32
 
33
  Stack::convert(
34
+ self::getImagePath('test.jpg'),
35
+ self::getImagePath('test.webp'),
36
  [
37
  'converters' => ['invalid-id']
38
  ]
42
  public function testCustomConverter()
43
  {
44
  Stack::convert(
45
+ self::getImagePath('test.jpg'),
46
+ self::getImagePath('test.webp'),
47
  [
48
  'converters' => [
49
  '\\WebPConvert\\Tests\\Convert\\TestConverters\\SuccessGuaranteedConverter'
vendor/rosell-dk/webp-convert/tests/Convert/Converters/VipsTest.php CHANGED
@@ -16,6 +16,16 @@ use PHPUnit\Framework\TestCase;
16
  class VipsTest extends TestCase
17
  {
18
 
 
 
 
 
 
 
 
 
 
 
19
  public function __construct()
20
  {
21
  //require_once('pretend.inc');
@@ -33,11 +43,10 @@ class VipsTest extends TestCase
33
  ConverterTestHelper::runAllConvertTests($this, 'Vips', $options);
34
  }
35
 
36
- public static $imageDir = __DIR__ . '/../..';
37
 
38
  private function createVips($src, $options = [])
39
  {
40
- $source = self::$imageDir . '/' . $src;
41
  $this->assertTrue(file_exists($source), 'source does not exist:' . $source);
42
 
43
  return new Vips($source, $source . '.webp', $options);
@@ -101,7 +110,7 @@ class VipsTest extends TestCase
101
  return;
102
  }
103
 
104
- $source = self::$imageDir . '/non-existing';
105
  $vips = new Vips($source, $source . '.webp', []);
106
  $vipsExposer = new VipsExposer($vips);
107
 
16
  class VipsTest extends TestCase
17
  {
18
 
19
+ public function getImageFolder()
20
+ {
21
+ return realpath(__DIR__ . '/../../images');
22
+ }
23
+
24
+ public function getImagePath($image)
25
+ {
26
+ return $this->getImageFolder() . '/' . $image;
27
+ }
28
+
29
  public function __construct()
30
  {
31
  //require_once('pretend.inc');
43
  ConverterTestHelper::runAllConvertTests($this, 'Vips', $options);
44
  }
45
 
 
46
 
47
  private function createVips($src, $options = [])
48
  {
49
+ $source = $this->getImagePath($src);
50
  $this->assertTrue(file_exists($source), 'source does not exist:' . $source);
51
 
52
  return new Vips($source, $source . '.webp', $options);
110
  return;
111
  }
112
 
113
+ $source = $this->getImagePath('non-existing');
114
  $vips = new Vips($source, $source . '.webp', []);
115
  $vipsExposer = new VipsExposer($vips);
116
 
vendor/rosell-dk/webp-convert/tests/Convert/Converters/WPCTest.php CHANGED
@@ -24,8 +24,15 @@ use PHPUnit\Framework\TestCase;
24
  class WpcTest extends TestCase
25
  {
26
 
 
 
 
 
27
 
28
- public $imageDir = __DIR__ . '/../../images/';
 
 
 
29
 
30
  /* public function testApi0()
31
  {
@@ -75,7 +82,8 @@ class WpcTest extends TestCase
75
  return;
76
  }
77
 
78
- $source = $this->imageDir . '/test.png';
 
79
  $options = [
80
  'api-version' => 0,
81
  'api-url' => getenv('WEBPCONVERT_WPC_API_URL_API0'),
@@ -93,7 +101,7 @@ class WpcTest extends TestCase
93
  return;
94
  }
95
 
96
- $source = $this->imageDir . '/test.png';
97
  $options = [
98
  'api-version' => 1,
99
  'crypt-api-key-in-transfer' => true,
@@ -109,7 +117,7 @@ class WpcTest extends TestCase
109
  return;
110
  }
111
 
112
- $source = $this->imageDir . '/test.png';
113
  $options = [
114
  'api-version' => 1,
115
  'crypt-api-key-in-transfer' => true,
@@ -124,10 +132,14 @@ class WpcTest extends TestCase
124
  {
125
  $this->expectException(ConverterNotOperationalException::class);
126
 
127
- Wpc::convert($this->imageDir . '/test.png', $this->imageDir . '/test.webp', [
128
- 'api-url' => 'badurl!',
129
- 'secret' => 'bad dog!',
130
- ]);
 
 
 
 
131
  }
132
 
133
  public function test404()
@@ -135,10 +147,14 @@ class WpcTest extends TestCase
135
  //$this->expectException(ConversionFailedException::class);
136
 
137
  try {
138
- Wpc::convert($this->imageDir . '/test.png', $this->imageDir . '/test.webp', [
139
- 'api-url' => 'https://google.com/hello',
140
- 'secret' => 'bad dog!',
141
- ]);
 
 
 
 
142
  $this->fail('Expected an exception');
143
 
144
  } catch (ConversionFailedException $e) {
@@ -155,10 +171,14 @@ class WpcTest extends TestCase
155
  //$this->expectException(ConversionFailedException::class);
156
 
157
  try {
158
- Wpc::convert($this->imageDir . '/test.png', $this->imageDir . '/test.webp', [
159
- 'api-url' => 'https://www.google.com/',
160
- 'secret' => 'bad dog!',
161
- ]);
 
 
 
 
162
  $this->fail('Expected an exception');
163
 
164
  } catch (ConversionFailedException $e) {
24
  class WpcTest extends TestCase
25
  {
26
 
27
+ public function getImageFolder()
28
+ {
29
+ return realpath(__DIR__ . '/../../images');
30
+ }
31
 
32
+ public function getImagePath($image)
33
+ {
34
+ return $this->getImageFolder() . '/' . $image;
35
+ }
36
 
37
  /* public function testApi0()
38
  {
82
  return;
83
  }
84
 
85
+
86
+ $source = $this->getImagePath('test.png');
87
  $options = [
88
  'api-version' => 0,
89
  'api-url' => getenv('WEBPCONVERT_WPC_API_URL_API0'),
101
  return;
102
  }
103
 
104
+ $source = $this->getImagePath('test.png');
105
  $options = [
106
  'api-version' => 1,
107
  'crypt-api-key-in-transfer' => true,
117
  return;
118
  }
119
 
120
+ $source = $this->getImagePath('test.png');
121
  $options = [
122
  'api-version' => 1,
123
  'crypt-api-key-in-transfer' => true,
132
  {
133
  $this->expectException(ConverterNotOperationalException::class);
134
 
135
+ Wpc::convert(
136
+ $this->getImagePath('test.png'),
137
+ $this->getImagePath('test.webp'),
138
+ [
139
+ 'api-url' => 'badurl!',
140
+ 'secret' => 'bad dog!',
141
+ ]
142
+ );
143
  }
144
 
145
  public function test404()
147
  //$this->expectException(ConversionFailedException::class);
148
 
149
  try {
150
+ Wpc::convert(
151
+ $this->getImagePath('test.png'),
152
+ $this->getImagePath('test.webp'),
153
+ [
154
+ 'api-url' => 'https://google.com/hello',
155
+ 'secret' => 'bad dog!',
156
+ ]
157
+ );
158
  $this->fail('Expected an exception');
159
 
160
  } catch (ConversionFailedException $e) {
171
  //$this->expectException(ConversionFailedException::class);
172
 
173
  try {
174
+ Wpc::convert(
175
+ $this->getImagePath('test.png'),
176
+ $this->getImagePath('test.webp'),
177
+ [
178
+ 'api-url' => 'https://www.google.com/',
179
+ 'secret' => 'bad dog!',
180
+ ]
181
+ );
182
  $this->fail('Expected an exception');
183
 
184
  } catch (ConversionFailedException $e) {
vendor/rosell-dk/webp-convert/tests/Serve/ServeConvertedWebPTest.php CHANGED
@@ -3,6 +3,9 @@
3
  namespace WebPConvert\Tests\Serve;
4
 
5
  use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
 
 
 
6
  use WebPConvert\Serve\ServeConvertedWebP;
7
  use WebPConvert\Serve\MockedHeader;
8
  use WebPConvert\Serve\Exceptions\ServeFailedException;
@@ -18,14 +21,22 @@ use PHPUnit\Framework\TestCase;
18
  class ServeConvertedWebPTest extends TestCase
19
  {
20
 
21
- public static $imageFolder = __DIR__ . '/../images';
 
 
 
 
 
 
 
 
22
 
23
  /**
24
  * @covers ::serveOriginal
25
  */
26
  public function testServeOriginal()
27
  {
28
- $source = self::$imageFolder . '/test.png';
29
  $this->assertTrue(file_exists($source), 'source file does not exist:' . $source);
30
 
31
  $destination = $source . '.webp';
@@ -58,9 +69,9 @@ class ServeConvertedWebPTest extends TestCase
58
  */
59
  public function testServeOriginalNotAnImage()
60
  {
61
- $this->expectException(ServeFailedException::class);
62
 
63
- $source = self::$imageFolder . '/text.txt';
64
  $this->assertTrue(file_exists($source), 'source file does not exist');
65
 
66
  $contentType = ImageMimeTypeGuesser::lenientGuess($source);
@@ -86,9 +97,9 @@ class ServeConvertedWebPTest extends TestCase
86
  */
87
  public function testServeOriginalNotAnImage2()
88
  {
89
- $this->expectException(ServeFailedException::class);
90
 
91
- $source = self::$imageFolder . '/text';
92
  $this->assertTrue(file_exists($source), 'source file does not exist');
93
 
94
  $contentType = ImageMimeTypeGuesser::lenientGuess($source);
@@ -114,7 +125,7 @@ class ServeConvertedWebPTest extends TestCase
114
  */
115
  public function testServeReconvert()
116
  {
117
- $source = self::$imageFolder . '/test.png';
118
  $this->assertTrue(file_exists($source));
119
 
120
  $destination = $source . '.webp';
@@ -146,7 +157,7 @@ class ServeConvertedWebPTest extends TestCase
146
  */
147
  public function testServeServeOriginal()
148
  {
149
- $source = self::$imageFolder . '/test.png';
150
  $this->assertTrue(file_exists($source));
151
 
152
  $destination = $source . '.webp';
@@ -179,7 +190,7 @@ class ServeConvertedWebPTest extends TestCase
179
  */
180
  public function testServeDestination()
181
  {
182
- $source = self::$imageFolder . '/test.png';
183
  $this->assertTrue(file_exists($source));
184
 
185
  // create fake webp at destination
@@ -214,7 +225,7 @@ class ServeConvertedWebPTest extends TestCase
214
  */
215
  public function testEmptySourceArg()
216
  {
217
- $this->expectException(ServeFailedException::class);
218
 
219
  ob_start();
220
  $options = [
@@ -227,19 +238,20 @@ class ServeConvertedWebPTest extends TestCase
227
  ]
228
  ];
229
 
230
- $this->assertEmpty('');
231
- ServeConvertedWebP::serve('', self::$imageFolder . '/test.png.webp', $options);
 
232
  $result = ob_get_clean();
233
  }
234
 
235
  /**
236
  * @covers ::serve
237
  */
238
- public function testInvalidDestinationArg()
239
  {
240
- $this->expectException(ServeFailedException::class);
241
 
242
- $source = self::$imageFolder . '/test.png';
243
  $this->assertTrue(file_exists($source));
244
 
245
  $destination = '';
@@ -263,9 +275,9 @@ class ServeConvertedWebPTest extends TestCase
263
  */
264
  public function testNoFileAtSource()
265
  {
266
- $this->expectException(ServeFailedException::class);
267
 
268
- $source = self::$imageFolder . '/i-do-not-exist.png';
269
  $this->assertFalse(file_exists($source));
270
 
271
  $destination = '';
@@ -289,7 +301,7 @@ class ServeConvertedWebPTest extends TestCase
289
  */
290
  public function testServeReport()
291
  {
292
- $source = self::$imageFolder . '/test.png';
293
  $this->assertTrue(file_exists($source));
294
  $destination = $source . '.webp';
295
 
@@ -318,7 +330,7 @@ class ServeConvertedWebPTest extends TestCase
318
 
319
  public function testSourceIsLighter()
320
  {
321
- $source = self::$imageFolder . '/plaintext-with-jpg-extension.jpg';
322
 
323
  // create fake webp at destination, which is larger than the fake jpg
324
  file_put_contents($source . '.webp', 'aotehu aotnehuatnoehutaoehu atonse uaoehu');
@@ -343,12 +355,12 @@ class ServeConvertedWebPTest extends TestCase
343
 
344
  public function testExistingOutDated()
345
  {
346
- $source = self::$imageFolder . '/test.jpg';
347
  $this->assertTrue(file_exists($source));
348
 
349
  $destination = $source . '.webp';
350
  @unlink($destination);
351
- copy(self::$imageFolder . '/pre-converted/test.webp', $destination);
352
 
353
  // set modification date earlier than source
354
  touch($destination, filemtime($source) - 1000);
@@ -379,7 +391,7 @@ class ServeConvertedWebPTest extends TestCase
379
 
380
  public function testNoFileAtDestination()
381
  {
382
- $source = self::$imageFolder . '/test.jpg';
383
  $this->assertTrue(file_exists($source));
384
 
385
  $destination = $source . '.webp';
3
  namespace WebPConvert\Tests\Serve;
4
 
5
  use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
6
+ use WebPConvert\Exceptions\InvalidInputException;
7
+ use WebPConvert\Exceptions\InvalidInput\InvalidImageTypeException;
8
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
9
  use WebPConvert\Serve\ServeConvertedWebP;
10
  use WebPConvert\Serve\MockedHeader;
11
  use WebPConvert\Serve\Exceptions\ServeFailedException;
21
  class ServeConvertedWebPTest extends TestCase
22
  {
23
 
24
+ public function getImageFolder()
25
+ {
26
+ return realpath(__DIR__ . '/../images');
27
+ }
28
+
29
+ public function getImagePath($image)
30
+ {
31
+ return $this->getImageFolder() . '/' . $image;
32
+ }
33
 
34
  /**
35
  * @covers ::serveOriginal
36
  */
37
  public function testServeOriginal()
38
  {
39
+ $source = $this->getImagePath('test.png');
40
  $this->assertTrue(file_exists($source), 'source file does not exist:' . $source);
41
 
42
  $destination = $source . '.webp';
69
  */
70
  public function testServeOriginalNotAnImage()
71
  {
72
+ $this->expectException(InvalidImageTypeException::class);
73
 
74
+ $source =$this->getImagePath('text.txt');
75
  $this->assertTrue(file_exists($source), 'source file does not exist');
76
 
77
  $contentType = ImageMimeTypeGuesser::lenientGuess($source);
97
  */
98
  public function testServeOriginalNotAnImage2()
99
  {
100
+ $this->expectException(InvalidImageTypeException::class);
101
 
102
+ $source = $this->getImagePath('text');
103
  $this->assertTrue(file_exists($source), 'source file does not exist');
104
 
105
  $contentType = ImageMimeTypeGuesser::lenientGuess($source);
125
  */
126
  public function testServeReconvert()
127
  {
128
+ $source = $this->getImagePath('test.png');
129
  $this->assertTrue(file_exists($source));
130
 
131
  $destination = $source . '.webp';
157
  */
158
  public function testServeServeOriginal()
159
  {
160
+ $source = $this->getImagePath('test.png');
161
  $this->assertTrue(file_exists($source));
162
 
163
  $destination = $source . '.webp';
190
  */
191
  public function testServeDestination()
192
  {
193
+ $source = $this->getImagePath('/test.png');
194
  $this->assertTrue(file_exists($source));
195
 
196
  // create fake webp at destination
225
  */
226
  public function testEmptySourceArg()
227
  {
228
+ $this->expectException(InvalidInputException::class);
229
 
230
  ob_start();
231
  $options = [
238
  ]
239
  ];
240
 
241
+ $source = '';
242
+ $this->assertEmpty($source);
243
+ ServeConvertedWebP::serve($source, $this->getImagePath('test.png.webp'), $options);
244
  $result = ob_get_clean();
245
  }
246
 
247
  /**
248
  * @covers ::serve
249
  */
250
+ public function testEmptyDestinationArg()
251
  {
252
+ $this->expectException(InvalidInputException::class);
253
 
254
+ $source = $this->getImagePath('test.png');
255
  $this->assertTrue(file_exists($source));
256
 
257
  $destination = '';
275
  */
276
  public function testNoFileAtSource()
277
  {
278
+ $this->expectException(TargetNotFoundException::class);
279
 
280
+ $source = $this->getImagePath('i-do-not-exist.png');
281
  $this->assertFalse(file_exists($source));
282
 
283
  $destination = '';
301
  */
302
  public function testServeReport()
303
  {
304
+ $source = $this->getImagePath('test.png');
305
  $this->assertTrue(file_exists($source));
306
  $destination = $source . '.webp';
307
 
330
 
331
  public function testSourceIsLighter()
332
  {
333
+ $source = $this->getImagePath('plaintext-with-jpg-extension.jpg');
334
 
335
  // create fake webp at destination, which is larger than the fake jpg
336
  file_put_contents($source . '.webp', 'aotehu aotnehuatnoehutaoehu atonse uaoehu');
355
 
356
  public function testExistingOutDated()
357
  {
358
+ $source = $this->getImagePath('test.jpg');
359
  $this->assertTrue(file_exists($source));
360
 
361
  $destination = $source . '.webp';
362
  @unlink($destination);
363
+ copy($this->getImagePath('pre-converted/test.webp'), $destination);
364
 
365
  // set modification date earlier than source
366
  touch($destination, filemtime($source) - 1000);
391
 
392
  public function testNoFileAtDestination()
393
  {
394
+ $source = $this->getImagePath('test.jpg');
395
  $this->assertTrue(file_exists($source));
396
 
397
  $destination = $source . '.webp';
vendor/rosell-dk/webp-convert/tests/Serve/ServeFileTest.php CHANGED
@@ -4,18 +4,31 @@ namespace WebPConvert\Tests\Serve;
4
 
5
  use WebPConvert\Serve\ServeFile;
6
  use WebPConvert\Serve\MockedHeader;
7
- use WebPConvert\Serve\Exceptions\ServeFailedException;
 
 
 
8
 
9
  use PHPUnit\Framework\TestCase;
10
 
11
  class ServeFileTest extends TestCase
12
  {
13
 
 
 
 
 
 
 
 
 
 
 
14
  public function testServeDefaultOptions()
15
  {
16
  MockedHeader::reset();
17
 
18
- $filename = __DIR__ . '/../images/plaintext-with-jpg-extension.jpg';
19
  $this->assertTrue(file_exists($filename));
20
 
21
  ob_start();
@@ -49,7 +62,7 @@ class ServeFileTest extends TestCase
49
 
50
  $this->assertEquals(0, MockedHeader::getNumHeaders());
51
 
52
- $filename = __DIR__ . '/../images/plaintext-with-jpg-extension.jpg';
53
  $this->assertTrue(file_exists($filename));
54
 
55
  $options = [
@@ -73,7 +86,7 @@ class ServeFileTest extends TestCase
73
 
74
  $this->assertEquals(0, MockedHeader::getNumHeaders());
75
 
76
- $filename = __DIR__ . '/../images/plaintext-with-jpg-extension.jpg';
77
  $this->assertTrue(file_exists($filename));
78
 
79
  $options = [
@@ -119,7 +132,7 @@ class ServeFileTest extends TestCase
119
  public function testServeCustomCacheControl()
120
  {
121
  MockedHeader::reset();
122
- $filename = __DIR__ . '/../images/plaintext-with-jpg-extension.jpg';
123
  $this->assertTrue(file_exists($filename));
124
 
125
  $options = [
@@ -140,7 +153,7 @@ class ServeFileTest extends TestCase
140
  public function testServeCustomCacheControlNoMaxAge()
141
  {
142
  MockedHeader::reset();
143
- $filename = __DIR__ . '/../images/plaintext-with-jpg-extension.jpg';
144
  $this->assertTrue(file_exists($filename));
145
  $options = [
146
  'headers' => [
@@ -161,10 +174,10 @@ class ServeFileTest extends TestCase
161
  {
162
  MockedHeader::reset();
163
 
164
- $filename = __DIR__ . '/i-dont-exist';
165
  $this->assertFalse(file_exists($filename));
166
 
167
- $this->expectException(ServeFailedException::class);
168
 
169
  ob_start();
170
  ServeFile::serve($filename, 'image/webp', []);
4
 
5
  use WebPConvert\Serve\ServeFile;
6
  use WebPConvert\Serve\MockedHeader;
7
+ use WebPConvert\Exceptions\InvalidInpuException;
8
+ use WebPConvert\Exceptions\InvalidInput\InvalidImageTypeException;
9
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
10
+ //use WebPConvert\Serve\Exceptions\ServeFailedException;
11
 
12
  use PHPUnit\Framework\TestCase;
13
 
14
  class ServeFileTest extends TestCase
15
  {
16
 
17
+ public function getImageFolder()
18
+ {
19
+ return realpath(__DIR__ . '/../images');
20
+ }
21
+
22
+ public function getImagePath($image)
23
+ {
24
+ return $this->getImageFolder() . '/' . $image;
25
+ }
26
+
27
  public function testServeDefaultOptions()
28
  {
29
  MockedHeader::reset();
30
 
31
+ $filename = self::getImagePath('plaintext-with-jpg-extension.jpg');
32
  $this->assertTrue(file_exists($filename));
33
 
34
  ob_start();
62
 
63
  $this->assertEquals(0, MockedHeader::getNumHeaders());
64
 
65
+ $filename = self::getImagePath('plaintext-with-jpg-extension.jpg');
66
  $this->assertTrue(file_exists($filename));
67
 
68
  $options = [
86
 
87
  $this->assertEquals(0, MockedHeader::getNumHeaders());
88
 
89
+ $filename = self::getImagePath('plaintext-with-jpg-extension.jpg');
90
  $this->assertTrue(file_exists($filename));
91
 
92
  $options = [
132
  public function testServeCustomCacheControl()
133
  {
134
  MockedHeader::reset();
135
+ $filename = self::getImagePath('plaintext-with-jpg-extension.jpg');
136
  $this->assertTrue(file_exists($filename));
137
 
138
  $options = [
153
  public function testServeCustomCacheControlNoMaxAge()
154
  {
155
  MockedHeader::reset();
156
+ $filename = self::getImagePath('plaintext-with-jpg-extension.jpg');
157
  $this->assertTrue(file_exists($filename));
158
  $options = [
159
  'headers' => [
174
  {
175
  MockedHeader::reset();
176
 
177
+ $filename = __DIR__ . '/i-dont-exist-no';
178
  $this->assertFalse(file_exists($filename));
179
 
180
+ $this->expectException(TargetNotFoundException::class);
181
 
182
  ob_start();
183
  ServeFile::serve($filename, 'image/webp', []);
vendor/rosell-dk/webp-convert/tests/WebPConvertTest.php CHANGED
@@ -11,7 +11,8 @@ namespace WebPConvert\Tests;
11
 
12
  use WebPConvert\WebPConvert;
13
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperationalException;
14
- use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\TargetNotFoundException;
 
15
  use WebPConvert\Convert\Exceptions\ConversionFailed\FileSystemProblems\CreateDestinationFolderException;
16
 
17
  use PHPUnit\Framework\TestCase;
11
 
12
  use WebPConvert\WebPConvert;
13
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperationalException;
14
+ //use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\TargetNotFoundException;
15
+ use WebPConvert\Exceptions\InvalidInput\TargetNotFoundException;
16
  use WebPConvert\Convert\Exceptions\ConversionFailed\FileSystemProblems\CreateDestinationFolderException;
17
 
18
  use PHPUnit\Framework\TestCase;
webp-express.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WebP Express
4
  * Plugin URI: https://github.com/rosell-dk/webp-express
5
  * Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
- * Version: 0.14.4
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2
3
  * Plugin Name: WebP Express
4
  * Plugin URI: https://github.com/rosell-dk/webp-express
5
  * Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
+ * Version: 0.14.5
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2
wod/webp-on-demand.php CHANGED
@@ -70,7 +70,14 @@ function loadConfig($configFilename) {
70
  return json_decode($json, true);
71
  }
72
 
73
- function getSource() {
 
 
 
 
 
 
 
74
  global $wodOptions;
75
  global $docRoot;
76
 
@@ -95,7 +102,10 @@ function getSource() {
95
  }
96
  }
97
 
98
- // Then querystring (full path)
 
 
 
99
  if (isset($_GET['xsource'])) {
100
  return substr($_GET['xsource'], 1); // No url decoding needed as $_GET is already decoded
101
  } elseif (isset($_GET['source'])) {
@@ -143,6 +153,12 @@ function getSource() {
143
  exitWithError('webp-on-demand.php was not passed any filename to convert');
144
  }
145
 
 
 
 
 
 
 
146
  function getWpContentRel() {
147
  // Passed in env variable?
148
  $wpContentDirRel = getEnvPassedInRewriteRule('WPCONTENT');
@@ -160,8 +176,14 @@ function getWpContentRel() {
160
  }
161
 
162
  $docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
163
- $webExpressContentDirAbs = $docRoot . '/' . getWpContentRel() . '/webp-express';
 
 
164
  $options = loadConfig($webExpressContentDirAbs . '/config/wod-options.json');
 
 
 
 
165
  $wodOptions = $options['wod'];
166
  $serveOptions = $options['webp-convert'];
167
  $convertOptions = &$serveOptions['convert'];
70
  return json_decode($json, true);
71
  }
72
 
73
+ /**
74
+ * Get absolute path to source file.
75
+ *
76
+ * The path can be passed to this file from the .htaccess file / nginx config in various ways.
77
+ *
78
+ * @return string Absolute path to source (unsanitized! - call sanitizeAbsFilePath immidiately after calling this method)
79
+ */
80
+ function getSourceUnsanitized() {
81
  global $wodOptions;
82
  global $docRoot;
83
 
102
  }
103
  }
104
 
105
+ // Then querystring (full path).
106
+ // PS: The parameters in $_GET are already url decoded. Sanitizing happens on the result
107
+
108
+ // TODO: perhaps only allow passing absolute path on nginx?
109
  if (isset($_GET['xsource'])) {
110
  return substr($_GET['xsource'], 1); // No url decoding needed as $_GET is already decoded
111
  } elseif (isset($_GET['source'])) {
153
  exitWithError('webp-on-demand.php was not passed any filename to convert');
154
  }
155
 
156
+ function getSource() {
157
+ return ConvertHelperIndependent::sanitizeAbsFilePath(
158
+ getSourceUnsanitized()
159
+ );
160
+ }
161
+
162
  function getWpContentRel() {
163
  // Passed in env variable?
164
  $wpContentDirRel = getEnvPassedInRewriteRule('WPCONTENT');
176
  }
177
 
178
  $docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
179
+
180
+ // PS: the following sanitizing will remove any "../" (which is good)
181
+ $webExpressContentDirAbs = ConvertHelperIndependent::sanitizeAbsFilePath($docRoot . '/' . getWpContentRel() . '/webp-express');
182
  $options = loadConfig($webExpressContentDirAbs . '/config/wod-options.json');
183
+
184
+ // TODO:
185
+ // Exit here, if not configured to redirect to conversion script
186
+
187
  $wodOptions = $options['wod'];
188
  $serveOptions = $options['webp-convert'];
189
  $convertOptions = &$serveOptions['convert'];
wod/webp-realizer.php CHANGED
@@ -75,7 +75,7 @@ function getDestinationRealPath($dest) {
75
  }
76
  }*/
77
 
78
- function getDestination() {
79
  global $docRoot;
80
 
81
  // First check if it is in an environment variable - thats the safest way
@@ -127,6 +127,12 @@ function getDestination() {
127
  return $dest;
128
  }
129
 
 
 
 
 
 
 
130
  function getWpContentRel() {
131
  // Passed in env variable?
132
  $wpContentDirRel = getEnvPassedInRewriteRule('WPCONTENT');
75
  }
76
  }*/
77
 
78
+ function getDestinationUnsanitized() {
79
  global $docRoot;
80
 
81
  // First check if it is in an environment variable - thats the safest way
127
  return $dest;
128
  }
129
 
130
+ function getDestination() {
131
+ return ConvertHelperIndependent::sanitizeAbsFilePath(
132
+ getDestinationUnsanitized()
133
+ );
134
+ }
135
+
136
  function getWpContentRel() {
137
  // Passed in env variable?
138
  $wpContentDirRel = getEnvPassedInRewriteRule('WPCONTENT');