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
The common header code as following:
JPEG (jpg),header:FFD8FF PNG (png),header:89504E47 GIF (gif),header:47494638 TIFF (tif),header:49492A00 Windows Bitmap (bmp),header:424D CAD (dwg),header:41433130 Adobe Photoshop (psd),header:38425053 Rich Text Format (rtf),header:7B5C727466 XML (xml),header:3C3F786D6C HTML (html),header:68746D6C3E MS Word/Excel (xls.or.doc),header:D0CF11E0 MS Access (mdb),header:5374616E64617264204A WordPerfect (wpd),header:FF575043 Adobe Acrobat (pdf),header:255044462D312E ZIP Archive (zip),header:504B0304 Gzip Archive File(.gz;.tar;.tgz), header:1F8B JAR Archive File(jar), header:5F27A889 RAR Archive (rar),header:52617221 Wave (wav),header:57415645 AVI (avi),header:41564920 Real Audio (ram),header:2E7261FD Real Media (rm),header:2E524D46 MPEG (mpg),header:000001BA MPEG (mpg),header:000001B3 Quicktime (mov),header:6D6F6F76 Windows Media (asf),header:3026B2758E66CF11 MIDI (mid),header:4D546864
First, we new add an ActionScript Project:
The Project name as FileHeaderTest.
Use a specific SDK: we choose Flex 4 (4.0.0.4121 Sat Nov 15, 2008)
Next click Configure Flex SDKs and revise the ActionScript Compiler:
PS, your browser should install Flash player 10 debug version.
Then specify the basic attributes of the generate SWF in FileHeaderTest.as
package {
import flash.display.Sprite;
[SWF(width="222", height="286", backgroundColor="#333333", framerate="30")]
public class FileHeaderTest extends Sprite
{
public function FileHeaderTest()
{
}
}
}
The Stage is 222×286, backgroundColor is #333333, framerate is 30.
New add document com.kingnare.file
New add class FileType, and modifiers is public
Then complete the call FileType. First claim the static variable: fileHeaders and createHeader as following.
public static var FileHeaders:Array = createHeaders();
public static function createHeaders():Array
{
var headers:Array = [];
headers.push({header:“89504E47″, ext:“png”});
headers.push({header:“FFD8FF”, ext:“jpg”});
headers.push({header:“47494638″, ext:“gif”});
return headers;
}
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.
public static function checkFileExt(file:FileReference):String
{
return “unknown”;
}
Next read the file data into the variable bytes.
public static function checkFileExt(file:FileReference):String
{
var bytes:ByteArray = new ByteArray();
file.data.position = 0;
file.data.readBytes(bytes);
return “unknown”;
}
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.
public static function filterLetters(doubleLetters:String, headerArray:Array, deep:uint):Array
{
var tmpArray:Array = [];
if(headerArray.length<0)
{
return tmpArray;
}
for(var i:uint=0;i<headerArray.length;i++)
{
var tmp:String = headerArray[i].header.toLocaleUpperCase();
if(tmp.length<=deep+1) continue;
var tmpStr:String = tmp.charAt(deep)+tmp.charAt(deep+1);
if(doubleLetters == tmpStr)
{
tmpArray.push(headerArray[i]);
}
}
return tmpArray;
}
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.
var tmpArray:Array = FileHeaders.slice(0);
Read the data:
var byte:uint;
try
{
byte = bytes.readByte();
}
catch(e:Error)
{
break;
}
Transfer to the hex string.
var bstr:String = byte.toString(16);
Get the last two significant character:
bstr = bstr.slice(bstr.length-2).toUpperCase();
If less than two cover with 0.
bstr = bstr.length<2 ? “0″+bstr : bstr;
After comparing, return to the FileHeaders copy:
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.
if(tmpArray.length == 1 && tmpArray[0].header.length == i+2)
{
return tmpArray[0].ext;
}
if(tmpArray.length == 0)
{
break;
}
The whole checkFileExt as following:
public static function checkFileExt(file:FileReference):String
{
var bytes:ByteArray = new ByteArray();
file.data.position = 0;
file.data.readBytes(bytes);
var len:uint = Math.floor(bytes.length/2);
var tmpArray:Array = FileHeaders.slice(0);
for(var i:uint=0;i<len;i+=2)
{
var byte:uint;
try
{
byte = bytes.readByte();
}
catch(e:Error)
{
break;
}
var bstr:String = byte.toString(16);
bstr = bstr.slice(bstr.length-2).toUpperCase();
bstr = bstr.length<2 ? “0″+bstr : bstr;
tmpArray = filterLetters(bstr, tmpArray, i);
if(tmpArray.length == 1 && tmpArray[0].header.length == i+2)
{
return tmpArray[0].ext;
}
if(tmpArray.length == 0)
{
break;
}
}
//
return “unknown”;
}
Ok, Let’s integrate these two methods to this class.
1) It determines whether the file exists in the extension of FileFilte by FileFilter.
public static function checkFileHeader(file:FileReference, filter:FileFilter):Boolean
{
var ext:String = filter.extension.toLocaleLowerCase();
var chkExt:String = checkFileExt(file);
return filter.extension.indexOf(“*.”+chkExt) != -1;
}
2) According the parameter type to determine:
public static function checkSingleFileHeader(file:FileReference, type:String):Boolean
{
var ext:String = type.toLocaleLowerCase();
var chkExt:String = checkFileExt(file);
return ext == chkExt;
}
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:
//File reference private var fr:FileReference; //File extension private var ext:FileFilter;
Then initialize these two variable in constructive method
public function FileHeaderTest()
{
ext = new FileFilter(“Images”, “*.jpg;*.gif;*.png”)
fr = new FileReference();
}
Register the fr and stage in constructive method
1) Event of Choose file
fr.addEventListener(Event.SELECT, selectHandler);
2) Event of File load finished
fr.addEventListener(Event.COMPLETE, completeHandler);
3) Event of Stage click
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.
private function browserHandler(event:MouseEvent):void
{
fr.browse([ext]);
}
private function selectHandler(event:Event):void
{
fr.load();
}
private function completeHandler(event:Event):void
{
parseFile(event.target as FileReference);
}
parseFile is the way we add to deal with files. The code as following:
private function parseFile(file:FileReference):void
{
trace(“png?”,FileType.checkSingleFileHeader(file, “png”)?“Yes”:“No”, “You choose a(an) “+FileType.checkFileExt(file)+” file.”); if(FileType.checkFileHeader(file, ext))
{
//trace(FileType.checkFileExt(file));
}
else
{
trace(“You can only choose JPG, PNG, GIF format.”);
}
}
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.
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
private function createInfoText():TextField
{
var txt:TextField = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.x = 10;
txt.y = 40;
txt.defaultTextFormat = createTextFormat(10, 0xFFFFFF);
txt.width = 200;
txt.wordWrap = true;
return txt;
}
2)Create text format
private function createTextFormat(size:uint, color:uint):TextFormat
{
var newFormat:TextFormat = new TextFormat();
newFormat.color = color;
newFormat.font = “Verdana”;
newFormat.leading = 5;
newFormat.size = size;
return newFormat;
}
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:
private function showBtn():void
{
var openBtn:KButton = new KButton(90, 22, “Open File…”);
openBtn.x = 10;
openBtn.y = 10;
openBtn.addEventListener(MouseEvent.CLICK, browserHandler);
addChild(openBtn);
}
Then add following code into construction method:
infoText = createInfoText(); infoText.text = “Please click the button and select a file.”; addChild(infoText); // showBtn();
Then change the output of parseFile into infoTest:
private
private function parseFile(file:FileReference):void
{
infoText.text = “File:”+file.name+“\n”;
infoText.appendText(“You choose a(an) “+FileType.checkFileExt(file).toUpperCase()+” file.\n”);
if(FileType.checkFileHeader(file, ext))
{
//
}
else
{
infoText.appendText(“You can only choose JPG, PNG, GIF format.”);
}
}
Click here to see the whole code of FileHeaderTest.
F11 after compiled as following image shown:
It can do further test, for example in this sample change the yahoo.zip to yahoo.jpg.
Then let’s do the test.
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.

November 21st, 2008
Ntt.cc
Posted in
Tags: 
RSS Feed
Email Feed
[...] FileReference Verification of File Type Cool utility for detecting file types of uploaded assets using the FileReference [...]
[...] 5. FileReference Verification of File Type [...]
i dont usually comment, but after reading through so much info i had to say thanks