@@ -131,6 +131,66 @@ function ppom_create_thumb_for_meta( $file_name, $product_id, $cropped = false,
131
131
return apply_filters ( 'ppom_meta_file_thumb ' , $ ppom_html , $ file_name , $ product_id );
132
132
}
133
133
134
+ /**
135
+ * Create a new file name that contains a unique string.
136
+ *
137
+ * @param string $file_name The file name.
138
+ * @param string $file_ext The file extension.
139
+ *
140
+ * @return string The new file name.
141
+ */
142
+ function ppom_create_unique_file_name ( $ file_name , $ file_ext ) {
143
+ return $ file_name . ". " . base64_encode ( substr ( wp_hash_password ( $ file_name ), 0 , 8 ) ) . ". " . $ file_ext ;
144
+ }
145
+
146
+ final class UploadFileErrors {
147
+ const OPEN_INPUT = 'open_input ' ;
148
+ const OPEN_OUTPUT = 'open_output ' ;
149
+ const MISSING_TEMP_FILE = 'missing_temp_file ' ;
150
+ const OPEN_DIR = 'open_dir ' ;
151
+
152
+ static function get_message_response ( $ error_slug ) {
153
+ $ msg = array (
154
+ self ::OPEN_INPUT => '{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"} ' ,
155
+ self ::OPEN_OUTPUT => '{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"} ' ,
156
+ self ::MISSING_TEMP_FILE => '{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"} ' ,
157
+ self ::OPEN_DIR => '{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"} ' ,
158
+ );
159
+
160
+ return isset ( $ msg [$ error_slug ] ) ? $ msg [$ error_slug ] : false ;
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Move the content of the file to read to the given ppom file chunk.
166
+ *
167
+ * @param string $file_path_to_read The file to read.
168
+ * @param string $ppom_chunk_file_path The chunk file to write.
169
+ * @param string $mode The writing mode for the chunk file.
170
+ *
171
+ * @return false|string The error.
172
+ */
173
+ function ppom_create_chunk_file ( $ file_path_to_read , $ ppom_chunk_file_path , $ mode ) {
174
+ $ chunk_file = fopen ( $ ppom_chunk_file_path , $ mode );
175
+ if ( $ chunk_file ) {
176
+ // Read binary input stream and append it to temp file
177
+ $ temp_file = fopen ( $ file_path_to_read , 'rb ' );
178
+
179
+ if ( $ temp_file ) {
180
+ while ( $ buff = fread ( $ temp_file , 4096 ) ) {
181
+ fwrite ( $ chunk_file , $ buff );
182
+ }
183
+ } else {
184
+ return UploadFileErrors::OPEN_INPUT ;
185
+ }
186
+ fclose ( $ temp_file );
187
+ fclose ( $ chunk_file );
188
+ } else {
189
+ return UploadFileErrors::OPEN_OUTPUT ;
190
+ }
191
+
192
+ return false ;
193
+ }
134
194
135
195
function ppom_upload_file () {
136
196
@@ -140,7 +200,7 @@ function ppom_upload_file() {
140
200
header ( 'Cache-Control: post-check=0, pre-check=0 ' , false );
141
201
header ( 'Pragma: no-cache ' );
142
202
143
- $ ppom_nonce = $ _REQUEST ['ppom_nonce ' ];
203
+ $ ppom_nonce = sanitize_key ( $ _REQUEST ['ppom_nonce ' ] ) ;
144
204
$ file_upload_nonce_action = 'ppom_uploading_file_action ' ;
145
205
if ( ! wp_verify_nonce ( $ ppom_nonce , $ file_upload_nonce_action ) && apply_filters ( 'ppom_verify_upload_file ' , true ) ) {
146
206
$ response ['status ' ] = 'error ' ;
@@ -200,14 +260,17 @@ function ppom_upload_file() {
200
260
// Get parameters
201
261
$ chunk = isset ( $ _REQUEST ['chunk ' ] ) ? intval ( $ _REQUEST ['chunk ' ] ) : 0 ;
202
262
$ chunks = isset ( $ _REQUEST ['chunks ' ] ) ? intval ( $ _REQUEST ['chunks ' ] ) : 0 ;
263
+
203
264
// $file_name = isset ( $_REQUEST ["name"] ) ? sanitize_file_name($_REQUEST ["name"]) : '';
204
265
205
266
$ file_path_thumb = $ file_dir_path . 'thumbs ' ;
206
267
$ file_name = wp_unique_filename ( $ file_path_thumb , $ file_name );
207
268
$ file_name = strtolower ( $ file_name );
208
269
$ file_ext = pathinfo ( $ file_name , PATHINFO_EXTENSION );
209
- $ unique_hash = substr ( hash ( 'sha256 ' , wp_generate_password ( 8 , false , false ) ), 0 , 8 );
210
- $ file_name = str_replace ( ". $ file_ext " , ". $ unique_hash. $ file_ext " , $ file_name );
270
+ $ original_name = $ file_name ;
271
+ $ original_name = str_replace (". $ file_ext " , "" , $ original_name );
272
+ $ file_hash = substr ( hash ('haval192,5 ' , $ file_name ), 0 , 8 ) . '- ' . $ ppom_nonce ;
273
+ $ file_name = str_replace ( ". $ file_ext " , ". $ file_hash. $ file_ext " , $ file_name );
211
274
$ file_path = $ file_dir_path . $ file_name ;
212
275
213
276
// Make sure the fileName is unique but only if chunking is disabled
@@ -226,88 +289,72 @@ function ppom_upload_file() {
226
289
}
227
290
228
291
// Remove old temp files
229
- if ( $ cleanupTargetDir && is_dir ( $ file_dir_path ) && ( $ dir = opendir ( $ file_dir_path ) ) ) {
292
+ if ( is_dir ( $ file_dir_path ) && ( $ dir = opendir ( $ file_dir_path ) ) ) {
230
293
while ( ( $ file = readdir ( $ dir ) ) !== false ) {
231
- $ tmpfilePath = $ file_dir_path . $ file ;
294
+ $ tmp_file_path = $ file_dir_path . $ file ;
232
295
233
296
// Remove temp file if it is older than the max age and is not the current file
234
- if ( preg_match ( '/\.part$/ ' , $ file ) && ( filemtime ( $ tmpfilePath ) < time () - $ maxFileAge ) && ( $ tmpfilePath != "{$ file_path }.part " ) ) {
235
- @unlink ( $ tmpfilePath );
297
+ if (
298
+ preg_match ( '/\.part$/ ' , $ file ) &&
299
+ ( filemtime ( $ tmp_file_path ) < time () - $ maxFileAge ) &&
300
+ ( $ tmp_file_path != "$ file_path.part " )
301
+ ) {
302
+ @unlink ( $ tmp_file_path );
236
303
}
237
304
}
238
305
239
306
closedir ( $ dir );
240
307
} else {
241
- die ( ' {"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"} ' );
308
+ die ( UploadFileErrors:: get_message_response ( UploadFileErrors:: MISSING_TEMP_FILE ) );
242
309
}
243
310
244
-
311
+ $ http_content_type = '' ;
245
312
// Look for the content type header
246
313
if ( isset ( $ _SERVER ['HTTP_CONTENT_TYPE ' ] ) ) {
247
- $ contentType = $ _SERVER ['HTTP_CONTENT_TYPE ' ];
314
+ $ http_content_type = $ _SERVER ['HTTP_CONTENT_TYPE ' ];
248
315
}
249
316
250
317
if ( isset ( $ _SERVER ['CONTENT_TYPE ' ] ) ) {
251
- $ contentType = $ _SERVER ['CONTENT_TYPE ' ];
318
+ $ http_content_type = $ _SERVER ['CONTENT_TYPE ' ];
252
319
}
253
320
254
- // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
255
- if ( strpos ( $ contentType , 'multipart ' ) !== false ) {
256
- if ( isset ( $ _FILES ['file ' ] ['tmp_name ' ] ) && is_uploaded_file ( $ _FILES ['file ' ] ['tmp_name ' ] ) ) {
257
- // Open temp file
258
- $ out = fopen ( "{$ file_path }.part " , $ chunk == 0 ? 'wb ' : 'ab ' );
259
- if ( $ out ) {
260
- // Read binary input stream and append it to temp file
261
- $ in = fopen ( sanitize_text_field ( $ _FILES ['file ' ] ['tmp_name ' ] ), 'rb ' );
262
-
263
- if ( $ in ) {
264
- while ( $ buff = fread ( $ in , 4096 ) ) {
265
- fwrite ( $ out , $ buff );
266
- }
267
- } else {
268
- die ( '{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"} ' );
269
- }
270
- fclose ( $ in );
271
- fclose ( $ out );
272
- @unlink ( sanitize_text_field ( $ _FILES ['file ' ] ['tmp_name ' ] ) );
273
- } else {
274
- die ( '{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"} ' );
275
- }
276
- } else {
277
- die ( '{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"} ' );
278
- }
279
- } else {
280
- // Open temp file
281
- $ out = fopen ( "{$ file_path }.part " , $ chunk == 0 ? 'wb ' : 'ab ' );
282
- if ( $ out ) {
283
- // Read binary input stream and append it to temp file
284
- $ in = fopen ( 'php://input ' , 'rb ' );
285
-
286
- if ( $ in ) {
287
- while ( $ buff = fread ( $ in , 4096 ) ) {
288
- fwrite ( $ out , $ buff );
289
- }
290
- } else {
291
- die ( '{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"} ' );
292
- }
321
+ $ temp_file_name = isset ( $ _FILES ['file ' ]['tmp_name ' ] ) ? realpath ( $ _FILES ['file ' ]['tmp_name ' ] ) : '' ;
322
+ $ is_multipart = ! empty ( $ http_content_type ) && false !== strpos ( $ http_content_type , 'multipart ' );
293
323
294
- fclose ( $ in );
295
- fclose ( $ out );
296
- } else {
297
- die ( ' {"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"} ' );
298
- }
324
+ if (
325
+ $ is_multipart &&
326
+ ( empty ( $ temp_file_name ) || ! is_uploaded_file ( $ temp_file_name ) )
327
+ ) {
328
+ die ( UploadFileErrors:: get_message_response ( UploadFileErrors:: MISSING_TEMP_FILE ) );
299
329
}
300
330
301
- // Check if file has been uploaded
302
- if ( ! $ chunks || $ chunk == $ chunks - 1 ) {
303
- // Strip the temp .part suffix off
304
- rename ( "{$ file_path }.part " , $ file_path );
331
+ $ chunk_file_path = "$ file_path.part " ;
332
+ $ uploaded_file_path_to_read = $ is_multipart ? $ temp_file_name : 'php://input ' ;
333
+
334
+ $ error = ppom_create_chunk_file ( $ uploaded_file_path_to_read , $ chunk_file_path , $ chunk == 0 ? 'wb ' : 'ab ' );
335
+
336
+ if ( $ is_multipart ) {
337
+ @unlink ( $ temp_file_name );
338
+ }
339
+
340
+ if ( $ error ) {
341
+ die ( UploadFileErrors::get_message_response ( $ error ) );
342
+ }
343
+
344
+ // Check if the file has been uploaded completely.
345
+ if ( ! $ chunks || $ chunk === $ chunks - 1 ) {
346
+
347
+ // Give a unique name to prevent name collisions.
348
+ $ file_name = ppom_create_unique_file_name ( $ original_name , $ file_ext );
349
+ $ unique_file_path = $ file_dir_path . $ file_name ;
350
+
351
+ rename ( $ chunk_file_path , $ unique_file_path );
352
+ $ file_path = $ unique_file_path ;
305
353
306
354
$ product_id = intval ( $ _REQUEST ['product_id ' ] );
307
355
$ data_name = sanitize_key ( $ _REQUEST ['data_name ' ] );
308
356
$ file_meta = ppom_get_field_meta_by_dataname ( $ product_id , $ data_name );
309
357
310
-
311
358
// making thumb if images
312
359
if ( ppom_is_file_image ( $ file_path ) ) {
313
360
0 commit comments