Cast as integer in ColdFusion; sanitizing variables

13,450

Solution 1

I would use cfparam. I'd also scope explicitly, but that's not necessary. I wouldn't use the IIF() function, because it makes use of evaluate(), which can be problematic, I'd also avoid DE() for the same reason. In this case, it won't be an issue, but I avoid them on general principle in any situation where it's not absolutely necessary. I've been using CF for a few years now, and it hasn't been necessary yet.

<cfparam name="url.id" default="0" />

<cfif isNumeric(url.id)>
    <cfset local.id = int(url.id) />
<cfelse>
    <cfset local.id = 0 />
</cfif>

Solution 2

Recent versions of ColdFusion also have a ternary conditional operator:

<cfset id = (structKeyExists(URL, "id") and isNumeric(URL.id)) ? int(URL.id) : 0>

Solution 3

Apologies for raising an old thread but came up with this same question and found a simple solution that might help others with this issue

NumberFormat(URL.id)

There are also various masks that you can specify in different scenarios

ColdFusion Reference

A formatted number value:

If no mask is specified, returns the value as an integer with a thousands separator. If the parameter value is "" (an empty string), returns 0.

http://help.adobe.com/livedocs/coldfusion/8/htmldocs/help.html?content=functions_m-r_08.html

Solution 4

To me, the simplest way to ensure your variable is an integer is to wrap the variable in val().

It attempts to parse the string and extract any integer found (at the beginning of the string). If none is found it returns 0.

  • If TestValue = "234A56?7'", Val(TestValue) returns 234.
  • If TestValue = "234'5678'9?'", Val(TestValue) returns 234.
  • If TestValue = "BG234", Val(TestValue) returns the value 0, (not an error).
  • If TestValue = "0", Val(TestValue) returns the value 0, (not an error).

See http://cfquickdocs.com/cf8/#Val

Share:
13,450
artlung
Author by

artlung

Programmer for hire | Indieweb | Toy robot collector | Bodysurfer | Respiratory | Bad drawing | Peace, love, resistance @artlung | [email protected] | artlung.com

Updated on June 24, 2022

Comments

  • artlung
    artlung almost 2 years

    I'm rusty at ColdFusion, I've been used to PHP for so long. What I want to do is something like this:

    <?php
      $id = (isset($_GET['id'])) ? (int)$_GET['id'] : 0;
    ?>
    

    Basically, check for a url parameter called id and if it exists make sure it's an integer so I can safely use it in database queries. If it ends up zero, that's fine too.

    I have:

    <cfscript>
    if (IsDefined("URL.id") AND IsNumeric(URL.id)) {
        id = int(URL.id);
    } else {
        id = 0;
    }
    </cfscript>
    

    This is working, but is awfully messy. Is there a better way to do this?

  • artlung
    artlung over 13 years
    Yes! It's been a long time. I didn't recognize DE: adobe.com/livedocs/coldfusion/7/htmldocs/wwhelp/wwhimpl/comm‌​on/… Thanks! Seems to be working nicely!
  • Ben Doom
    Ben Doom over 13 years
    I've not tested it, but IIF is widely regarded as an efficiency sink.
  • PPShein
    PPShein over 13 years
    What my advice is correct, please dun forget to tick my post as right answer. :)
  • Stephen Moretti
    Stephen Moretti over 13 years
    You can't use IIF in this instance. IIF evaluates all parts everytime. This means if you use this and URL.Id doesn't exist it will throw an error trying to process Int(URL.Id) in the second part of IIF()
  • PPShein
    PPShein over 13 years
    I don't think IIF make efficiency sink. Please let me specific information to proof about that problem.
  • Adam Tuttle
    Adam Tuttle over 13 years
    While your solution is not wrong, I think Rick O's is more elegant and closer to the original question; so I'm down-voting you to bump his up, at least for now.
  • Sergey Galashyn
    Sergey Galashyn over 13 years
    Bad solution: put the invalid value in the url.id and you'll fire the exception, handling one looks like overhead here.
  • Sergey Galashyn
    Sergey Galashyn over 13 years
    Notes: ?: wont work before CF8, also isNumeric(url.id) can be replaced with more strict isValid("integer", url.id).
  • Sergey Galashyn
    Sergey Galashyn over 13 years
    IMO, IIF is one of the most unreadable features of CFML -- this is enough to avoid using it.
  • Stephen Moretti
    Stephen Moretti over 13 years
    for a cf8 version of this ---- variables.id = 0; if (structKeyExists(url,"id) && isValid("integer",url.id)) variables.id = url.id;
  • Ken Redler
    Ken Redler over 13 years
    Sergii, I understand where you're coming from, but as to whether it's "bad," I think it depends. If having an empty or malformed url.id does in fact constitute an exception in his app, I think it's fair to handle it as such (i.e. within a try/catch block, where it can be logged, handled, etc). "Swallowing" the exceptional behavior by specifically programming for it conditionally works, of course, although it blurs the line between an exception and an expected operating state of the app.
  • Ken Redler
    Ken Redler over 13 years
    I don't think this warrants a downvote -- it is after all a language feature (albeit ugly), in the precise spirit of the first php snippet, and older versions of CF don't have the ternary operator.
  • Leigh
    Leigh about 9 years
    Every situation is different, but a couple things worth noting. NumberFormat is really designed for presentation. Technically, it returns a string, not an integer. Also, it throws an exception when passed a non-numeric value. So it does not satisfy all of the requirements of the original question, ie sanitize the value (and verify the variable exists).