~ubuntu-branches/debian/sid/wordpress/sid

« back to all changes in this revision

Viewing changes to debian/missing-sources/plupload-1.5.4/flash/plupload/src/com/plupload/File.as

  • Committer: Package Import Robot
  • Author(s): Raphaël Hertzog
  • Date: 2013-09-04 23:18:58 UTC
  • mfrom: (1.2.28)
  • Revision ID: package-import@ubuntu.com-20130904231858-nljmn1buzswh63jk
Tags: 3.6+dfsg-1
* New upstream release.
* Improve wp-settings to verify that $_SERVER['HTTP_X_FORWARDED_PROTO']
  exists before accessing it (avoids a PHP notice).
  Thanks to Paul Dreik <slask@pauldreik.se> for the report and the patch.
* Document in README.Debian the need to login to /wp-admin/ to complete
  an upgrade.
* Drop useless debian/README.source
* Drop 008CVE2008-2392.patch since upstream now disables unfiltered
  uploads by default. See http://core.trac.wordpress.org/ticket/10692
* Drop 009CVE2008-6767.patch since the backto parameter is validated
  against a whitelist, and externally triggered upgrades are not a
  security problem as long as they work.
* Update debian/missing-sources with latest versions.
* Update upstream l10n.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * File.as
3
 
 *
4
 
 * Copyright 2009, Moxiecode Systems AB
5
 
 * Released under GPL License.
6
 
 *
7
 
 * License: http://www.plupload.com/license
8
 
 * Contributing: http://www.plupload.com/contributing
9
 
 */
10
 
 
11
 
package com.plupload {
12
 
        import com.formatlos.BitmapDataUnlimited;
13
 
        import com.formatlos.events.BitmapDataUnlimitedEvent;
14
 
        import flash.display.Bitmap;
15
 
        import flash.display.BitmapData;
16
 
        import flash.display.IBitmapDrawable;
17
 
        import flash.events.EventDispatcher;
18
 
        import flash.geom.Matrix;
19
 
        import flash.net.FileReference;
20
 
        import flash.events.Event;
21
 
        import flash.events.IOErrorEvent;
22
 
        import flash.events.HTTPStatusEvent;
23
 
        import flash.events.ProgressEvent;
24
 
        import flash.events.SecurityErrorEvent;
25
 
        import flash.events.DataEvent;
26
 
        import flash.net.FileReferenceList;
27
 
        import flash.net.URLLoader;
28
 
        import flash.net.URLRequest;
29
 
        import flash.net.URLRequestHeader;
30
 
        import flash.net.URLRequestMethod;
31
 
        import flash.net.URLStream;
32
 
        import flash.net.URLVariables;
33
 
        import flash.utils.ByteArray;
34
 
        import flash.utils.setTimeout;
35
 
        import flash.external.ExternalInterface;
36
 
        import com.mxi.image.events.ExifParserEvent;
37
 
        
38
 
        import com.mxi.image.Image;
39
 
        import com.mxi.image.events.ImageEvent;
40
 
        
41
 
        
42
 
        /**
43
 
         * Container class for file references, this handles upload logic for individual files.
44
 
         */
45
 
        public class File extends EventDispatcher {
46
 
                // Private fields
47
 
                private var _fileRef:FileReference, _urlStream:URLStream, _cancelled:Boolean;
48
 
                private var _uploadUrl:String, _uploadPath:String, _mimeType:String;
49
 
                private var _id:String, _fileName:String, _size:Number, _imageData:ByteArray;
50
 
                private var _multipart:Boolean, _fileDataName:String, _chunking:Boolean, _chunk:int, _chunks:int, _chunkSize:int, _postvars:Object;
51
 
                private var _headers:Object, _settings:Object;
52
 
                private var _removeAllListeners:Function;
53
 
                private var _removeAllURLStreamListeners:Function;
54
 
 
55
 
                /**
56
 
                 * Id property of file.
57
 
                 */
58
 
                public function get id():String {
59
 
                        return this._id;
60
 
                }
61
 
 
62
 
                /**
63
 
                 * File name for the file.
64
 
                 */
65
 
                public function get fileName():String {
66
 
                        return this._fileName;
67
 
                }
68
 
 
69
 
                /**
70
 
                 * File name for the file.
71
 
                 */
72
 
                public function set fileName(value:String):void {
73
 
                        this._fileName = value;
74
 
                }
75
 
 
76
 
                /**
77
 
                 * File size property.
78
 
                 */
79
 
                public function get size():Number {
80
 
                        return this._size;
81
 
                }
82
 
 
83
 
                /**
84
 
                 * Constructs a new file object.
85
 
                 *
86
 
                 * @param id Unique indentifier for the file.
87
 
                 * @param file_ref File reference for the selected file.
88
 
                 */
89
 
                public function File(id:String, file_ref:FileReference) {
90
 
                        this._id = id;
91
 
                        this._fileRef = file_ref;
92
 
                        this._size = file_ref.size;
93
 
                        this._fileName = file_ref.name;
94
 
                }
95
 
                
96
 
                /**
97
 
                 * Cancel current upload.
98
 
                 */
99
 
                public function cancelUpload(): void
100
 
                {
101
 
                        if (this.canUseSimpleUpload(this._settings)) {
102
 
                                this._fileRef.cancel();
103
 
                        } else if (!this._urlStream) {
104
 
                                // In case of a large file and before _fileRef.load#COMPLETE.
105
 
                                // Need to cancel() twice, not sure why.
106
 
                                // If single cancel(), #2037 will occurred at _fileRef.load().
107
 
                                this._fileRef.cancel();
108
 
                                this._fileRef.cancel();
109
 
                                this._removeAllListeners();
110
 
                        } else if (this._urlStream.connected) {
111
 
                                // just in case
112
 
                                this._removeAllURLStreamListeners();
113
 
 
114
 
                                this._urlStream.close();
115
 
 
116
 
                                // In case of a large file and after the first uploadNextChunk().
117
 
                                // #2174 will occur at _fileRef.load() and
118
 
                                // #2029 will occur at _urlStream.readUTFBytes as well
119
 
                                // after loading file is stopped before _fileRef.load#COMPLETE.
120
 
                
121
 
                                // Uploaded file will be broken as well if the following line does not exist.
122
 
                                this._urlStream = null;
123
 
                        } 
124
 
                }
125
 
 
126
 
                /**
127
 
                 * Uploads a the file to the specified url. This method will upload it as a normal
128
 
                 * multipart file upload if the file size is smaller than the chunk size. But if the file is to
129
 
                 * large it will be chunked into multiple requests.
130
 
                 *
131
 
                 * @param url Url to upload the file to.
132
 
                 * @param settings Settings object.
133
 
                 */
134
 
                public function upload(url:String, settings:Object):void {
135
 
                        this._settings = settings;
136
 
 
137
 
                        if (this.canUseSimpleUpload(settings)) {
138
 
                                this.simpleUpload(url, settings);
139
 
                        } else {
140
 
                                this.advancedUpload(url, settings);
141
 
                        }
142
 
                }
143
 
 
144
 
                // Private methods
145
 
 
146
 
                public function canUseSimpleUpload(settings:Object):Boolean {
147
 
                        var multipart:Boolean = new Boolean(settings["multipart"]);
148
 
                        var resize:Boolean = (settings["width"] || settings["height"] || settings["quality"]);
149
 
                        var chunking:Boolean = (settings["chunk_size"] > 0);
150
 
 
151
 
                        // Check if it's not an image, chunking is disabled, multipart enabled and the ref_upload setting isn't forced
152
 
                        return (!(/\.(jpeg|jpg|png)$/i.test(this._fileName)) || !resize) && multipart && !chunking && !settings.urlstream_upload && !settings.headers;
153
 
                }
154
 
 
155
 
                public function simpleUpload(url:String, settings:Object):void {
156
 
                        var file:File = this, request:URLRequest, postData:URLVariables, fileDataName:String;
157
 
                        var onProgress:Function, onUploadComplete:Function, onIOError:Function, onSecurityErrorEvent:Function;
158
 
                        var removeAllListeners:Function = function () : void {
159
 
                                        file._fileRef.removeEventListener(ProgressEvent.PROGRESS, onProgress);
160
 
                                        file._fileRef.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadComplete);
161
 
                                        file._fileRef.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
162
 
                                        file._fileRef.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorEvent);
163
 
                                };
164
 
                        
165
 
                        this._removeAllListeners = removeAllListeners;
166
 
                        
167
 
                        file._postvars = settings["multipart_params"];
168
 
                        file._chunk = 0;
169
 
                        file._chunks = 1;
170
 
 
171
 
                        postData = new URLVariables();
172
 
        
173
 
                        file._postvars["name"] = settings["name"];
174
 
 
175
 
                        for (var key:String in file._postvars) {
176
 
                                if (key != 'Filename') { // Flash will add it by itself, so we need to omit potential duplicate
177
 
                                        postData[key] = file._postvars[key];
178
 
                                }
179
 
                        }
180
 
 
181
 
                        request = new URLRequest();
182
 
                        request.method = URLRequestMethod.POST;
183
 
                        request.url = url;
184
 
                        request.data = postData;
185
 
 
186
 
                        fileDataName = new String(settings["file_data_name"]);
187
 
                        
188
 
                        onUploadComplete = function(e:DataEvent):void {
189
 
                                removeAllListeners();
190
 
                                
191
 
                                var pe:ProgressEvent = new ProgressEvent(ProgressEvent.PROGRESS, false, false, file._size, file._size);
192
 
                                dispatchEvent(pe);
193
 
                                
194
 
                                // Fake UPLOAD_COMPLETE_DATA event
195
 
                                var uploadChunkEvt:UploadChunkEvent = new UploadChunkEvent(
196
 
                                        UploadChunkEvent.UPLOAD_CHUNK_COMPLETE_DATA,
197
 
                                        false,
198
 
                                        false,
199
 
                                        e.data,
200
 
                                        file._chunk,
201
 
                                        file._chunks
202
 
                                );
203
 
                                
204
 
                                file._chunk++;
205
 
                                
206
 
                                dispatchEvent(uploadChunkEvt);
207
 
 
208
 
                                dispatchEvent(e);
209
 
                        };
210
 
                        file._fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadComplete);
211
 
 
212
 
                        // Delegate upload IO errors
213
 
                        onIOError = function(e:IOErrorEvent):void {
214
 
                                removeAllListeners();
215
 
                                dispatchEvent(e);
216
 
                        };
217
 
                        file._fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
218
 
 
219
 
                        // Delegate secuirty errors
220
 
                        onSecurityErrorEvent = function(e:SecurityErrorEvent):void {
221
 
                                removeAllListeners();
222
 
                                dispatchEvent(e);
223
 
                        };
224
 
                        file._fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorEvent);
225
 
 
226
 
                        // Delegate progress
227
 
                        onProgress = function(e:ProgressEvent):void {   
228
 
                                dispatchEvent(e);
229
 
                        };
230
 
                        file._fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress);
231
 
                        
232
 
                        file._fileRef.upload(request, fileDataName, false);
233
 
                }
234
 
 
235
 
                public function advancedUpload(url:String, settings:Object):void {
236
 
                        var file:File = this, width:int, height:int, quality:int, multipart:Boolean, chunking:Boolean, fileDataName:String;
237
 
                        var chunk:int, chunks:int, chunkSize:int, postvars:Object;
238
 
                        var onComplete:Function, onIOError:Function;
239
 
                        var removeAllListeners:Function = function() : void {
240
 
                                        file._fileRef.removeEventListener(Event.COMPLETE, onComplete);
241
 
                                        file._fileRef.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
242
 
                                };
243
 
 
244
 
                        // Setup internal vars
245
 
                        this._uploadUrl = url;
246
 
                        this._cancelled = false;
247
 
                        this._headers = settings.headers;
248
 
                        this._mimeType = settings.mime;
249
 
                        
250
 
                        // make it available for whole class (cancelUpload requires it for example)
251
 
                        this._removeAllListeners = removeAllListeners;
252
 
 
253
 
                        multipart = new Boolean(settings["multipart"]);
254
 
                        fileDataName = new String(settings["file_data_name"]);
255
 
                        chunkSize = settings["chunk_size"];
256
 
                        chunking = chunkSize > 0;
257
 
                        postvars = settings["multipart_params"];
258
 
                        chunk = 0;
259
 
 
260
 
                        // When file is loaded start uploading
261
 
                        onComplete = function(e:Event):void {
262
 
                                removeAllListeners();
263
 
                                
264
 
                                var startUpload:Function = function() : void
265
 
                                {
266
 
                                        if (chunking) {
267
 
                                                chunks = Math.ceil(file._size / chunkSize);
268
 
 
269
 
                                                // Force at least 4 chunks to fake progress. We need to fake this since the URLLoader
270
 
                                                // doesn't have a upload progress event and we can't use FileReference.upload since it
271
 
                                                // doesn't support cookies, breaks on HTTPS and doesn't support custom data so client
272
 
                                                // side image resizing will not be possible.
273
 
                                                if (chunks < 4 && file._size > 1024 * 32) {
274
 
                                                        chunkSize = Math.ceil(file._size / 4);
275
 
                                                        chunks = 4;
276
 
                                                }
277
 
                                        } else {
278
 
                                                // If chunking is disabled then upload file in one huge chunk
279
 
                                                chunkSize = file._size;
280
 
                                                chunks = 1;
281
 
                                        }
282
 
 
283
 
                                        // Start uploading the scaled down image
284
 
                                        file._multipart = multipart;
285
 
                                        file._fileDataName = fileDataName;
286
 
                                        file._chunking = chunking;
287
 
                                        file._chunk = chunk;
288
 
                                        file._chunks = chunks;
289
 
                                        file._chunkSize = chunkSize;
290
 
                                        file._postvars = postvars;
291
 
 
292
 
                                        file.uploadNextChunk();
293
 
                                }
294
 
                                                                
295
 
                                if (/\.(jpeg|jpg|png)$/i.test(file._fileName) && (settings["width"] || settings["height"] || settings["quality"])) {
296
 
                                        var image:Image = new Image(file._fileRef.data);
297
 
                                        image.addEventListener(ImageEvent.COMPLETE, function(e:ImageEvent) : void 
298
 
                                        {
299
 
                                                image.removeAllEventListeners();
300
 
                                                if (image.imageData) {
301
 
                                                        file._imageData = image.imageData;
302
 
                                                        file._imageData.position = 0;
303
 
                                                        file._size = image.imageData.length;
304
 
                                                }
305
 
                                                startUpload();
306
 
                                        });
307
 
                                        image.addEventListener(ImageEvent.ERROR, function(e:ImageEvent) : void
308
 
                                        {
309
 
                                                image.removeAllEventListeners();
310
 
                                                file.dispatchEvent(e);
311
 
                                        });
312
 
                                        image.addEventListener(ExifParserEvent.EXIF_DATA, function(e:ExifParserEvent) : void
313
 
                                        {
314
 
                                                file.dispatchEvent(e);
315
 
                                        });
316
 
                                        image.addEventListener(ExifParserEvent.GPS_DATA, function(e:ExifParserEvent) : void
317
 
                                        {
318
 
                                                file.dispatchEvent(e);
319
 
                                        });
320
 
                                        image.scale(settings["width"], settings["height"], settings["quality"]);
321
 
                                } else {
322
 
                                        startUpload();
323
 
                                }                                       
324
 
                        };
325
 
                        this._fileRef.addEventListener(Event.COMPLETE, onComplete);
326
 
 
327
 
                        // File load IO error
328
 
                        onIOError = function(e:Event):void {
329
 
                                removeAllListeners();
330
 
                                dispatchEvent(e);
331
 
                        };
332
 
                        this._fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
333
 
 
334
 
                        // Start loading local file
335
 
                        this._fileRef.load();
336
 
                }
337
 
 
338
 
                /**
339
 
                 * Uploads the next chunk or terminates the upload loop if all chunks are done.
340
 
                 */
341
 
                public function uploadNextChunk():Boolean {
342
 
                        var file:File = this, fileData:ByteArray, chunkData:ByteArray, req:URLRequest, url:String;
343
 
                        var onComplete:Function, onIOError:Function, onSecurityError:Function;
344
 
                        var removeAllEventListeners:Function = function() : void {
345
 
                                        file._urlStream.removeEventListener(Event.COMPLETE, onComplete);
346
 
                                        file._urlStream.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
347
 
                                        file._urlStream.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
348
 
                                };
349
 
                                
350
 
                        this._removeAllURLStreamListeners = removeAllEventListeners;
351
 
 
352
 
                        // All chunks uploaded?
353
 
                        if (this._chunk >= this._chunks) {
354
 
                                // Clean up memory
355
 
                                if(this._fileRef.data) {
356
 
                                        this._fileRef.data.clear();
357
 
                                }
358
 
                                this._imageData = null;
359
 
 
360
 
                                return false;
361
 
                        }
362
 
 
363
 
                        // Slice out a chunk
364
 
                        chunkData = new ByteArray();
365
 
 
366
 
                        // Use image data if it exists, will exist if the image was resized
367
 
                        if (this._imageData != null)
368
 
                                fileData = this._imageData;
369
 
                        else
370
 
                                fileData = this._fileRef.data;
371
 
 
372
 
                        fileData.readBytes(chunkData, 0, fileData.position + this._chunkSize > fileData.length ? fileData.length - fileData.position : this._chunkSize);
373
 
 
374
 
                        // Setup URL stream
375
 
                        file._urlStream = null;
376
 
                        file._urlStream = new URLStream();
377
 
 
378
 
                        // Wait for response and dispatch it
379
 
                        onComplete = function(e:Event):void {
380
 
                                
381
 
 
382
 
                                var response:String = file._urlStream.readUTFBytes(file._urlStream.bytesAvailable);
383
 
                                
384
 
                                // Fake UPLOAD_COMPLETE_DATA event
385
 
                                var uploadChunkEvt:UploadChunkEvent = new UploadChunkEvent(
386
 
                                        UploadChunkEvent.UPLOAD_CHUNK_COMPLETE_DATA,
387
 
                                        false,
388
 
                                        false,
389
 
                                        response,
390
 
                                        file._chunk,
391
 
                                        file._chunks
392
 
                                );
393
 
 
394
 
                                file._chunk++;
395
 
                                dispatchEvent(uploadChunkEvt);
396
 
 
397
 
                                // Fake progress event since Flash doesn't have a progress event for streaming data up to the server
398
 
                                var pe:ProgressEvent = new ProgressEvent(ProgressEvent.PROGRESS, false, false, fileData.position, file._size);
399
 
                                dispatchEvent(pe);
400
 
 
401
 
                                // Clean up memory
402
 
                                file._urlStream.close();
403
 
                                removeAllEventListeners();
404
 
                                chunkData.clear();
405
 
                        };
406
 
                        file._urlStream.addEventListener(Event.COMPLETE, onComplete);
407
 
 
408
 
                        // Delegate upload IO errors
409
 
                        onIOError = function(e:IOErrorEvent):void {
410
 
                                removeAllEventListeners();
411
 
                                dispatchEvent(e);
412
 
                        };
413
 
                        file._urlStream.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
414
 
 
415
 
                        // Delegate secuirty errors
416
 
                        onSecurityError = function(e:SecurityErrorEvent):void {
417
 
                                removeAllEventListeners();
418
 
                                dispatchEvent(e);
419
 
                        };
420
 
                        file._urlStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
421
 
 
422
 
                        // Setup URL
423
 
                        url = this._uploadUrl;
424
 
 
425
 
                        // Add name and chunk/chunks to URL if we use direct streaming method
426
 
                        if (!this._multipart) {
427
 
                                if (url.indexOf('?') == -1)
428
 
                                        url += '?';
429
 
                                else
430
 
                                        url += '&';
431
 
 
432
 
                                url += "name=" + encodeURIComponent(this._settings["name"]);
433
 
 
434
 
                                if (this._chunking) {
435
 
                                        url += "&chunk=" + this._chunk + "&chunks=" + this._chunks;
436
 
                                }
437
 
                        }
438
 
 
439
 
                        // Setup request
440
 
                        req = new URLRequest(url);
441
 
                        req.method = URLRequestMethod.POST;
442
 
 
443
 
                        // Add custom headers
444
 
                        if (this._headers) {
445
 
                                for (var headerName:String in this._headers) {
446
 
                                        req.requestHeaders.push(new URLRequestHeader(headerName, this._headers[headerName]));
447
 
                                }
448
 
                        }
449
 
 
450
 
                        // Build multipart request
451
 
                        if (this._multipart) {
452
 
                                var boundary:String = '----pluploadboundary' + new Date().getTime(),
453
 
                                        dashdash:String = '--', crlf:String = '\r\n', multipartBlob: ByteArray = new ByteArray();
454
 
 
455
 
                                req.requestHeaders.push(new URLRequestHeader("Content-Type", 'multipart/form-data; boundary=' + boundary));
456
 
 
457
 
                                this._postvars["name"] = this._settings["name"];
458
 
 
459
 
                                // Add chunking parameters if needed
460
 
                                if (this._chunking) {
461
 
                                        this._postvars["chunk"] = this._chunk;
462
 
                                        this._postvars["chunks"] = this._chunks;
463
 
                                }
464
 
 
465
 
                                // Append mutlipart parameters
466
 
                                for (var name:String in this._postvars) {
467
 
                                        multipartBlob.writeUTFBytes(
468
 
                                                dashdash + boundary + crlf +
469
 
                                                'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf +
470
 
                                                this._postvars[name] + crlf
471
 
                                        );
472
 
                                }
473
 
 
474
 
                                // Add file header
475
 
                                multipartBlob.writeUTFBytes(
476
 
                                        dashdash + boundary + crlf +
477
 
                                        'Content-Disposition: form-data; name="' + this._fileDataName + '"; filename="' + this._fileName + '"' + crlf +
478
 
                                        'Content-Type: ' + this._mimeType + crlf + crlf
479
 
                                );
480
 
 
481
 
                                // Add file data
482
 
                                multipartBlob.writeBytes(chunkData, 0, chunkData.length);
483
 
 
484
 
                                // Add file footer
485
 
                                multipartBlob.writeUTFBytes(crlf + dashdash + boundary + dashdash + crlf);
486
 
                                req.data = multipartBlob;
487
 
                        } else {
488
 
                                req.requestHeaders.push(new URLRequestHeader("Content-Type", "application/octet-stream"));
489
 
                                req.data = chunkData;
490
 
                        }
491
 
 
492
 
                        // Make request
493
 
                        setTimeout(function() : void { // otherwise URLStream eventually hangs for Chrome+Flash (as of FP11.2 r202)
494
 
                                file._urlStream.load(req);
495
 
                        }, 1);
496
 
                        return true;
497
 
                }
498
 
        }
499
 
}