Ok, so I know "Validate Your Form Fields" is one of the ten commandments of web development, but even Jedis can screw this up at times. Here is a great, and maybe a bit subtle, example of something I screwed up in BlogCFC.
Over the weekend a slew of error emails came in to our blog at work and then this morning another user reported the same error. The error was:
The SUBSCRIBE argument passed to the addComment function is not of type boolean.
This came from the Add Comment code. When you post a comment to my blogware, there is a subscribe checkbox. The checkbox will pass a true value, and since it is a checkbox, nothing at all will be passed if you leave it be. Therefore this code:
<cfparam name="form.subscribe" default="false">
Will handle setting that state to false. That works fine until some spammer/script kiddie does a form post with subscribe set to a non-boolean value.
I fixed this easily enough (BlogCFC users can download the fix in about 5 minutes) by adding:
<!--- validate boolean --->
<cfif not isBoolean(form.subscribe)>
<cfset form.subscribe = false>
</cfif>
<cfif not isBoolean(form.rememberme)>
<cfset form.rememberme = false>
</cfif>
Pretty simple mistake on my part. What's interesting/sad is that this is exactly the same type of thing I've had to worry about since I started ColdFusion development 10+ years ago!
Archived Comments
That's actually the reason why I never use true/false for a boolean checkbox or radio button input. Instead I use 0 and 1 so that on the pages where the value is submitted instead of checking for isBoolean() I just reset the value
<cfparam name="attributes.bool" default="0" />
<cfset attributes.bool = val(attributes.bool) />
I've also noticed that when saving a blog entry, the category input seems to be required only if the entry was previously saved. If it's a new entry it seems to allow me to create it with no category though. It's funny because then if I edit that entry I notice that I never categorized it because it tells me I can't save the edit until I categorize it. ;)
Um, that's a feature. Really. (Duck...)
Cheers Ray!
@ike, blogCFC is giving me an error when trying to save a new Entry without a category.
I use the following to put it into a single line of code. If it's not Boolean, it will evaluate to false. If it is Boolean, it will then take the true/false value of the form.subscribe field.
<cfset form.subscribe = (isBoolean(form.subscribe) AND form.subscribe)>
@ray - oh well that's a horse of a different color then. :)
@kumar - it may have already been fixed. I'm using the copy that runs the RIAForge blogs, which I think Ray had to modify to swap out the db for different projects and such... probably a few other things... and I don't think it gets upgraded to new versions of BlogCFC very often because of the merging issue.
Incidentally, the aforementioned merging issue is negated when using the onTap framework to develop applications. :)
@Rick: elegant!
Ray, thanks for posting this. I started getting these error messages over the weekend and was like: "What the crap!" I haven't had time to look into the error emails and now I don't have to! I just need to apply the fix to my super old version of BlogCFC.
Also, cfparam can enforce the data type to be boolean ONLY.
<cfparam name="form.subscribe" default="false" type="boolean" />
@Dipak - the reason why I avoid using type="boolean" on a cfparam when the variable is in the form scope, is because it gives you no control over the error handling. It simply throws up a big ole' ugly error message that's completely meaningless to the user. It's a pretty message for us because we're programmers, but to the user it's trash-city, this website blows, I'm going somewhere else!
This will only ever cause problems, because the best case scenario is that you get a bunch more tech-support calls asking you what's wrong with the page. The worst case scenario is that you don't get any tech support calls on it.
So I always opt for an alternative that either gracefully ignores the fact that the user typed the value "sandwich" into a bolean parameter in the url, or if that's not possible at all then I will switch to a pretty, user-friendly message that says, "I'm sorry, I don't understand what you want me to do with this 'sandwich'." and then provides them with an explanation of how to resolve the problem and continue.
If the param is on a variable in some other scope like custom tag attributes, then I'm all for specifying it as a boolean.