Forum Moderators: open

Message Too Old, No Replies

Form Validation

Preventing Spaces in a Filename

         

scuba_fan

5:04 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



I'm a complete rookie with Javascript so any help is so greatly appreciated. I'm working on a form and I want to prevent the user from uploading files that have spaces in the name. Below is the javascript I've got tested and working so far. But I can't seem to get a form validation test for spaces. The other noteable issue is that often, people will select a file from their hard drive that is in a folder that contains spaces in the name. That's ok, I just want to make sure the actual filename has no spaces...

You'll see that I've got a client side test to ensure that only the file type I've chosen can be selected. That works fine. And the last test makes sure there are not ' in the name. But when I change the ' to a space, it doesn't work.

I am sooooo stuck!

<script>
function onSubmitForm() {
var formDOMObj = document.frmSend;
if (formDOMObj.attach1.value == "" )
{
alert("Please press the browse button and pick a file.");
return false;
}
if (formDOMObj.attach1.value!= "")
if((formDOMObj.attach1.value.lastIndexOf(".jpg")==-1) && (formDOMObj.attach1.value.lastIndexOf(".gif")==-1) && (formDOMObj.attach1.value.lastIndexOf(".mp3")==-1) && (formDOMObj.attach1.value.lastIndexOf(".3gp")==-1) && (formDOMObj.attach1.value.lastIndexOf(".mtf")==-1) && (formDOMObj.attach1.value.lastIndexOf(".mid")==-1) && (formDOMObj.attach1.value.lastIndexOf(".jad")==-1) && (formDOMObj.attach1.value.lastIndexOf(".jar")==-1))
{
alert("You can upload only GIF, JPG, ,JAR, JAD, MP3, 3GP, MTF and MID files");
return false;
}
if (formDOMObj.attach1.value!= "")
if (formDOMObj.attach1.value.lastIndexOf("'")!= -1)
{
alert("PLEASE READ THE IMPORTANT NOTICE!\n\n NO SPACES or APOSTROPHES ALLOWED\n\n Rename your file and try again");
return false;
}
return true;
}
</script>

DrDoc

5:11 pm on Mar 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Welcome to Webmaster World!

I assume you also have something in place on the server that will rename the file if it contains disallowed characters..?

scuba_fan

6:15 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



I have some server side ASP VBSCript that will strip/convert unix characters.

I'm trying to do some client side work first to minimize the load on the server and reduce the round trips necessary during the exchange. Client side javascript made the most sense to validate the form fields before they get processed at the server.

john_k

6:44 pm on Mar 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This is not tested and I'm certain to have overlooked something, but this might help:

var sFile=(formDOMObj.attach1.value).replace('/','\');
var path=sFile.split('\');
var pos=path[path.length-1].indexOf(' ');
if(pos>0)
{
//bad file name
}else{
//okay to keep going
}

A little off topic: Client-side validation should be viewed as a user convenience. Like you said, it can save on the number of trips to the server. However, regardless of what you do for client-side validation, any and all data submitted should ALWAYS be validated at the server. It's simply too easy to spoof a form or URL with parameters.

scuba_fan

7:40 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



Thanks for the script snip. Ill give it a try. In an effort to understand, let me see if I get this right...

var sFile=(formDOMObj.attach1.value).replace('/','\'); //this is replacing all forward slashes with back slashes

var path=sFile.split('\'); //this is splitting the path at each backslash and storing the chunks in the variable called path? or is this setting the var to just the stuff after the last backslash?

var pos=path[path.length-1].indexOf(' '); //this looks for a space and sets the var to the length (adjusted to zero basis) of the string remaining after the space. So if there are no spaces, it should be zero

if(pos>0) //test if it is in fact zero
{
//bad file name
}else{
//okay to keep going
}

I'll give it a try. I was looking around for RegExp to do the work. It looks like my entire code base should and could be more efficient using RegExp. I could test for only the file extensions I allow and if spaces exist in the file name all at the same time.

Wondering if anyone here can assist or comment on that approach.

john_k

8:06 pm on Mar 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes. More correctly though, the split function is returning an array.

And yes, regex should be able to handle this. The trick will be in getting the pattern search to begin after the last backslash. My regular expression databank isn't what it used to be, but I think that it should be fairly easy. (On the other hand, my irregular expression databank is in an overflow state)

scuba_fan

8:13 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



Yep. I'm still learning, so this is getting me pretty frustrated. By the way, the script snip doesn't work. You can't use ' because javascript will return an error of unterminated string contant...

Still looking for answers...

Thanks again...

ajkimoto

8:17 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



scuba_fan

Here is a modification of john_k's code that uses a regular expression.

One important point--you need to represent the '\' as '\\' in the replace statement since javascript treats the backslash as a special character.

var sFile=(formDOMObj.attach1.value)
while( sFile.indexOf('/')!=-1){
sFile=sFile.replace('/','\\')
}
var path=sFile.split('\\');

//create regular expresssion
var Regex=/[' ]/

//check to see if "'" or " " is contained in the filename
if (Regex.test(path[path.length-1])){

//bad file name
}else{
//okay to keep going
}

scuba_fan

9:33 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



Works! Thank you so much for the help. Again, I'd like to understand what's happening to learn more.

var sFile=(formDOMObj.attach1.value) //I get it
while( sFile.indexOf('/')!=-1){ //while loop to replace all occurances of the forwardslash
sFile=sFile.replace('/','\\')
}
var path=sFile.split('\\'); //split the string into an array assigned to the var path.

//create regular expresssion
var Regex=/[' ]/ //RegExp containing a character set that will match against any one of the enclosed characters. So I could add illegal characters in this to expand the capability?

//check to see if "'" or " " is contained in the filename
if (Regex.test(path[path.length-1])){ //test the string for the presence of those in the Regex statement. I don't understand, see question at bottom.

//bad file name
}else{
//okay to keep going
}

What I don't understand is how the script took apart the string into the path variable and knew which part of the array was the file name stuff. Would you mind explaining it a bit?

Again. Thanks so much... I'll probably post some more stuff that I have working, but think there is a more eligant way to code it...

ajkimoto

9:54 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



scuba_fan,

the replace method of the string object replaces a substring with another substring

So if I had:

var myString='this is my string.'

myNewString=myString.replace('.','!')

would yield:

'this is my string!'

The split method of the string object breaks apart a string into an array of substrings--split occurs on the character in the parentheses.

so if I had:

myPath='c:\my dir\myfile.mp3'

var pathArray = myPath.split('\\')

would give me the array pathArray populated thusly:

pathArray[0]='c:'
pathArray[1]='my dir'
pathArray[2]='myfile.mp3'

You get the length of the array using array.length, so pathArray.length will return 3.

Since js arrays start at 0, to get the last element (the one containing the file name) you use something like:

pathArray[pathArray.length-1]

in other words, pathArray[2], which equals 'myfile.mp3'

Now, on to regular expressions

var Regex=/[' ]/

creates a new regular expression object called Regex

test is a method of the regular expression object. Essentially, it is doing pattern matching. I am by no means an expert on regular expressions--they can get very complex. The regular expression in the example above is a very simple one.

When the string is passed to the test method of the Regex object, it checks for the occurrance of one or more of the characters contained in the square brackets (So you can indeed expand the list to contain other illegal characters).

If one or more of the characters is found in the string, the method returns true, otherwise returns false.

Hope this helps,

ajkimoto

scuba_fan

10:06 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



ajkimoto-
That was an excellent explaination. Thank you kindly for taking the time to not only explain, but illustrate.

Best Regards.

DrDoc

10:33 pm on Mar 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



some server side ASP VBSCript that will strip/convert unix characters

What about stripping out single quotes or spaces?
...or disallowing certain file extensions?

You need to do that on the server side as well, in case they turn JavaScript off.

ajkimoto

10:42 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



Though I suppose that you could use the 'big hammer' approach and just prevent them from seeing the form if they have js turned off.

<script type="text/javascript">
function showForm(){
document.getElementById('myDiv').display="block"
document.getElementById('myJsDiv').display="none"
}
</script>
<body onload="showForm()">

<div id="myJsDiv" style="display:block;">
<p>You must have javascript enabled in order to use this form</p>
</div>

<div id='myDiv' style="display:none">
<form>
....
</form>
</div>

Not very nice, I suppose, but effective?

ajkimoto

john_k

10:54 pm on Mar 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You need to do that on the server side as well, in case they turn JavaScript off.

... or make their own form that uploads EmailYourDatabaseToMeThenFormatYourHardDrive.exe

ajkimoto

11:19 pm on Mar 23, 2004 (gmt 0)

10+ Year Member



BWAHAHAHAHA! Very evil john_k! Also very true. If we are talking about security, then JS is never the way to go anyway.

On the other hand, if this is just a polite way to 'encourage' users to upload only files of the listed types, then js would be appropriate.

ajkimoto

scuba_fan

12:29 am on Mar 24, 2004 (gmt 0)

10+ Year Member



ok, so now you've got me worried. How would I put the same protection on the server side?

I don't know the syntax, but something like

<script Language="Javascript 1.2" Runat=Server>

Do I need to change anything, and of course the big question...

The ASP page that generates the form (and this script), then also receives the input before it executes. So how do I validate at the server too?

I thought I was safe, I didn't think you could spoof the form since the necessary processing ASP code isn't there, and you can't enter the parms on the URL because it won't have the required class libraries and includes executed either.

So is this really necessary?

Purple Martin

12:59 am on Mar 24, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes it's necessary - I could write my own HTML document and upload it to my host. The form in my document has an action that points to your asp page - that's how I can upload whatever I like to your server.

So you look at all the checks you're currently doing in JavaScript, and you do all the same checks again in ASP. This way the checks get done no matter what I do.

There is at least one extra check that your ASP must do: removing any single or double quotes from anything submitted by any form. This is to prevent people exploiting a thing called "SQL Injection", which is a way of running SQL commands on your database by putting the commands after a quote in a string. You must prevent this, as people can do a lot of damage this way.

scuba_fan

1:57 am on Mar 24, 2004 (gmt 0)

10+ Year Member



Ok, but wouldn't your form also have to know the hidden form field trigger that is required to process?

For example, the upload form has something to the effect

If Request.Form("trigger")= "submitted" Then
upload code processes
else
Response.write "Stongly Worded Language"
End If

Yes? Doesn't this effectively control the access?

Purple Martin

4:50 am on Mar 24, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I simply view the source of your web page, and copy the hidden field into my form on my web page.

scuba_fan

6:21 am on Mar 24, 2004 (gmt 0)

10+ Year Member



As Homer Simpson says...Duuuhh, I forgot that hidden form fields display in the source code.

Fortunately, when I put together the upload processor I trapped single and double quotes and stripped them out. I've also converted most potential valid unix filename characters that are illegal on windows platforms and coverted those to underscores.

My next step is to recreate the file validation rules in vbscript. That ought to be some fun...