Tutorials: About Using Flash Player 10 to Verify The Files Type (FileReference)

favorites-128x128 Now you could load files which you choose into memory to continue the following operation by the way load which new add in class FileReference Flashplayer 10. Then we could determine the type of files by FileReference.load().

*The FileReference class provides a means to upload and download files between a user’s computer and a server

Search-256x256 Demo | DownloadDownload Full Project

The common header code as following:

  1. JPEG (jpg),header:FFD8FF
  2.  
  3. PNG (png),header:89504E47
  4.  
  5. GIF (gif),header:47494638
  6.  
  7. TIFF (tif),header:49492A00
  8.  
  9. Windows Bitmap (bmp),header:424D
  10.  
  11. CAD (dwg),header:41433130
  12.  
  13. Adobe Photoshop (psd),header:38425053
  14.  
  15. Rich Text Format (rtf),header:7B5C727466
  16.  
  17. XML (xml),header:3C3F786D6C
  18.  
  19. HTML (html),header:68746D6C3E
  20.  
  21. MS Word/Excel (xls.or.doc),header:D0CF11E0
  22.  
  23. MS Access (mdb),header:5374616E64617264204A
  24.  
  25. WordPerfect (wpd),header:FF575043
  26.  
  27. Adobe Acrobat (pdf),header:255044462D312E
  28.  
  29. ZIP Archive (zip),header:504B0304
  30.  
  31. Gzip Archive File(.gz;.tar;.tgz), header:1F8B
  32.  
  33. JAR Archive File(jar), header:5F27A889
  34.  
  35. RAR Archive (rar),header:52617221
  36.  
  37. Wave (wav),header:57415645
  38.  
  39. AVI (avi),header:41564920
  40.  
  41. Real Audio (ram),header:2E7261FD
  42.  
  43. Real Media (rm),header:2E524D46
  44.  
  45. MPEG (mpg),header:000001BA
  46.  
  47. MPEG (mpg),header:000001B3
  48.  
  49. Quicktime (mov),header:6D6F6F76
  50.  
  51. Windows Media (asf),header:3026B2758E66CF11
  52.  
  53. MIDI (mid),header:4D546864

First, we new add an ActionScript Project:

1

The Project name as FileHeaderTest.

Use a specific SDK: we choose Flex 4 (4.0.0.4121 Sat Nov 15, 2008)

image

Next click Configure Flex SDKs and revise the ActionScript Compiler:

image

PS, your browser should install Flash player 10 debug version.

Then specify the basic attributes of the generate SWF in FileHeaderTest.as

  1. package {
  2. import flash.display.Sprite;
  3.  
  4. [SWF(width="222", height="286", backgroundColor="#333333", framerate="30")]
  5.  
  6. public class FileHeaderTest extends Sprite
  7.  
  8. {
  9. public function FileHeaderTest()
  10. {
  11. }
  12. }
  13. }

The Stage is 222×286, backgroundColor is #333333, framerate is 30.

New add document com.kingnare.file

3

New add class FileType, and modifiers is public

4

Then complete the call FileType. First claim the static variable: fileHeaders and createHeader as following.

  1. public static var FileHeaders:Array = createHeaders();
  2.  
  3. public static function createHeaders():Array
  4. {
  5.  
  6. var headers:Array = [];
  7.  
  8. headers.push({header:“89504E47″, ext:“png});
  9. headers.push({header:“FFD8FF”, ext:“jpg});
  10. headers.push({header:“47494638″, ext:“gif});
  11.  
  12. return headers;
  13.  
  14. }

Initialize the fileheader and paired array of header. ( It use PNG, JPG, GIF in this example )

The process of file verification is very simple. Read the files in memory by byte and change into hexadecimal compare with header then we could get the type of files.

Now we start to write the process of file verification. New add static function checkFileExt, return the file actual type, if didn’t file the paired type in FileHeaders then return the character string: unknown.

  1. public static function checkFileExt(file:FileReference):String
  2. {
  3. returnunknown”;
  4. }

Next read the file data into the variable bytes.

  1. public static function checkFileExt(file:FileReference):String
  2. {
  3. var bytes:ByteArray = new ByteArray();
  4.  
  5. file.data.position = 0;
  6. file.data.readBytes(bytes);
  7.  
  8. returnunknown”;
  9. }

How to do the comparison? We could create a copy of FileHeaders, read the data to filter the copy until the last element of the copy and the length of file header is same as the current location of the pointer, then we could sure the match is success. Then we need filterLetters to definite the way of filter the copy.

  1. public static function filterLetters(doubleLetters:String, headerArray:Array, deep:uint):Array
  2. {
  3. var tmpArray:Array = [];
  4.  
  5. if(headerArray.length<0)
  6. {
  7. return tmpArray;
  8. }
  9.  
  10. for(var i:uint=0;i<headerArray.length;i++)
  11. {
  12.  
  13. var tmp:String = headerArray[i].header.toLocaleUpperCase();
  14.  
  15. if(tmp.length<=deep+1) continue;
  16.  
  17. var tmpStr:String = tmp.charAt(deep)+tmp.charAt(deep+1);
  18.  
  19. if(doubleLetters == tmpStr)
  20. {
  21. tmpArray.push(headerArray[i]);
  22. }
  23. }
  24.  
  25. return tmpArray;
  26.  
  27. }

Parameter doubleLetters is the byte value of the current location of file pointer. headerArray is the array of the copy. Deep is the index value of matched position.

Compare every element of header’s deep to deep+2 with doubleLetters,if same then remain the element. After comparing all the element return to the new copy array.

Now let see example for the first byte. Create the copy of FileHeaders.

  1. var tmpArray:Array = FileHeaders.slice(0);

Read the data:

  1. var byte:uint;
  2. try
  3. {
  4. byte = bytes.readByte();
  5. }
  6. catch(e:Error)
  7. {
  8. break;
  9. }

Transfer to the hex string.

  1. var bstr:String = byte.toString(16);

Get the last two significant character:

  1. bstr = bstr.slice(bstr.length-2).toUpperCase();

If less than two cover with 0.

  1. bstr = bstr.length<2 ? “0″+bstr : bstr;

After comparing, return to the FileHeaders copy:

  1. tmpArray = filterLetters(bstr, tmpArray, 0);

If only leaving one element in the copy and the element length of header just the position of current pointer, then it found and return. If else continue until found or the return array is blank.

  1. if(tmpArray.length == 1 && tmpArray[0].header.length == i+2)
  2. {
  3. return tmpArray[0].ext;
  4. }
  5.  
  6. if(tmpArray.length == 0)
  7. {
  8. break;
  9. }

The whole checkFileExt as following:

  1. public static function checkFileExt(file:FileReference):String
  2. {
  3. var bytes:ByteArray = new ByteArray();
  4.  
  5. file.data.position = 0;
  6. file.data.readBytes(bytes);
  7.  
  8. var len:uint = Math.floor(bytes.length/2);
  9.  
  10. var tmpArray:Array = FileHeaders.slice(0);
  11.  
  12. for(var i:uint=0;i<len;i+=2)
  13. {
  14. var byte:uint;
  15.  
  16. try
  17. {
  18. byte = bytes.readByte();
  19. }
  20. catch(e:Error)
  21. {
  22. break;
  23. }
  24.  
  25. var bstr:String = byte.toString(16);
  26.  
  27. bstr = bstr.slice(bstr.length-2).toUpperCase();
  28. bstr = bstr.length<2 ? “0″+bstr : bstr;
  29. tmpArray = filterLetters(bstr, tmpArray, i);
  30.  
  31. if(tmpArray.length == 1 && tmpArray[0].header.length == i+2)
  32. {
  33. return tmpArray[0].ext;
  34. }
  35.  
  36. if(tmpArray.length == 0)
  37. {
  38. break;
  39. }
  40. }
  41.  
  42. //
  43. return “unknown”;
  44. }

Ok, Let’s integrate these two methods to this class.

1) It determines whether the file exists in the extension of FileFilte by FileFilter.

  1. public static function checkFileHeader(file:FileReference, filter:FileFilter):Boolean
  2. {
  3. var ext:String = filter.extension.toLocaleLowerCase();
  4. var chkExt:String = checkFileExt(file);
  5.  
  6. return filter.extension.indexOf(“*.”+chkExt) != -1;
  7. }

2) According the parameter type to determine:

  1. public static function checkSingleFileHeader(file:FileReference, type:String):Boolean
  2. {
  3. var ext:String = type.toLocaleLowerCase();
  4. var chkExt:String = checkFileExt(file);
  5.  
  6. return ext == chkExt;
  7. }

Then the class FileType has been finished. Let’s check whether it could work normally.

Return to the FileHeaderTest and new add two private variable:

  1. //File reference
  2. private var fr:FileReference;
  3.  
  4. //File extension
  5. private var ext:FileFilter;

Then initialize these two variable in constructive method

  1. public function FileHeaderTest()
  2. {
  3. ext = new FileFilter(Images”, “*.jpg;*.gif;*.png)
  4. fr = new FileReference();
  5. }

Register the fr and stage in constructive method

1) Event of Choose file

  1. fr.addEventListener(Event.SELECT, selectHandler);

2) Event of File load finished

  1. fr.addEventListener(Event.COMPLETE, completeHandler);

3) Event of Stage click

  1. this.stage.addEventListener(MouseEvent.CLICK, browserHandler);

We call fr.browser to open optional dialog box in browserHandler then call fr.load to load file in selectHandler. At last deal with the data in completeHandler.

  1. private function browserHandler(event:MouseEvent):void
  2. {
  3. fr.browse([ext]);
  4. }
  5.  
  6. private function selectHandler(event:Event):void
  7. {
  8. fr.load();
  9. }
  10.  
  11. private function completeHandler(event:Event):void
  12. {
  13. parseFile(event.target as FileReference);
  14. }

parseFile is the way we add to deal with files. The code as following:

  1. private function parseFile(file:FileReference):void
  2. {
  3. trace(png?”,FileType.checkSingleFileHeader(file, “png)?“Yes”:“No”, “You choose a(an) “+FileType.checkFileExt(file)+” file.”); if(FileType.checkFileHeader(file, ext))
  4. {
  5. //trace(FileType.checkFileExt(file));
  6. }
  7. else
  8. {
  9. trace(You can only choose JPG, PNG, GIF format.”);
  10. }
  11. }

F11 compile and run the program, click the stage of SWF and it will show file selective dialog box. If choose JPG file then you will get as following in output.

png? No You choose a(an) jpg file.

If choose a ZIP file:

png? No You choose a(an) unknown file.

You can only choose JPG, PNG, GIF format.

It is because didn’t add the header code of ZIP file to the FileHeaders array.

We could add them into createHeaders of TileType.

  1. headers.push({header:“504B0304″, ext:“zip});

png? No You choose a(an) zip file.

You can only choose JPG, PNG, GIF format.

We could make the program more perfect. For example add button and output textbox. Then it will be more convenient and easily to see.

New add private variable in FileHeaderTest

private var infoText:TextField;

New add relative method

1)Create text

  1. private function createInfoText():TextField
  2. {
  3. var txt:TextField = new TextField();
  4. txt.autoSize = TextFieldAutoSize.LEFT;
  5. txt.x = 10;
  6. txt.y = 40;
  7. txt.defaultTextFormat = createTextFormat(10, 0xFFFFFF);
  8. txt.width = 200;
  9. txt.wordWrap = true;
  10.  
  11. return txt;
  12. }

2)Create text format

  1. private function createTextFormat(size:uint, color:uint):TextFormat
  2. {
  3. var newFormat:TextFormat = new TextFormat();
  4.  
  5. newFormat.color = color;
  6. newFormat.font = “Verdana”;
  7. newFormat.leading = 5;
  8. newFormat.size = size;
  9.  
  10. return newFormat;
  11. }

3) New add button ( KButton is the come with the button, code is in the com.kingnare,skins.KButton)

We remove the event stage and add click event in the KButton:

  1. private function showBtn():void
  2. {
  3. var openBtn:KButton = new KButton(90, 22, “Open File…”);
  4.  
  5. openBtn.x = 10;
  6. openBtn.y = 10;
  7. openBtn.addEventListener(MouseEvent.CLICK, browserHandler);
  8.  
  9. addChild(openBtn);
  10. }

Then add following code into construction method:

  1. infoText = createInfoText();
  2. infoText.text = “Please click the button and select a file.”;
  3. addChild(infoText);
  4. //
  5. showBtn();

Then change the output of parseFile into infoTest:

private

  1. private function parseFile(file:FileReference):void
  2. {
  3. infoText.text = “File:”+file.name+“\n”;
  4. infoText.appendText(You choose a(an) “+FileType.checkFileExt(file).toUpperCase()+” file.\n);
  5.  
  6. if(FileType.checkFileHeader(file, ext))
  7. {
  8. //
  9. }
  10. else
  11. {
  12. infoText.appendText(You can only choose JPG, PNG, GIF format.”);
  13. }
  14. }

Click here to see the whole code of FileHeaderTest.

F11 after compiled as following image shown:

image

It can do further test, for example in this sample change the yahoo.zip to yahoo.jpg.

Then let’s do the test.

image

OK, the tutorial of detecting files is finished. We could use it to help users to correct the wrong choose files and prevent users to deliberately revised files type for the purpose of deceive uploading.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • Reddit
  • Technorati
  • StumbleUpon
  • Twitter
RSS Enjoy this Post? Subscribe to Ntt.cc

RSS Feed   RSS Feed     Email Feed  Email Feed Follow us Follow us
You can leave a response, or trackback from your own site.

3 Responses to “Tutorials: About Using Flash Player 10 to Verify The Files Type (FileReference)”

  1. [...] FileReference Verification of File Type Cool utility for detecting file types of uploaded assets using the FileReference [...]

  2. design king says:

    i dont usually comment, but after reading through so much info i had to say thanks

Leave a Reply