Search code examples
foreachscopeasp-classic

For each in by reference or value


I have the following code:

dim key
for each key in Request.Querystring
  'do something
  key = sanitized_param(key)
next

My question for you classic-asp connoisseur, does classic-asp, or asp in general, pass the variables as references(memory), or by value? Trying to figure out if I sanitize the key variable and pass it back to itself, is it just "alive" for that loop, or does the new value get passed to the original QueryString?


Solution

  • Request.QueryString retrieves the query string parameters by value from the page headers.

    You can only make changes to a query string once its been retrieved via Request.QueryString, but you can't make changes directly to Request.QueryString as it's read-only (If you could make changes you would presumably use Response.QueryString, but this isn't a valid response command).

    I'm guessing you're trying to sanitize all your query strings in one go? This isn't really possible or indeed necessary. You would typically sanitize a query string as and when you request it:

    Response.Write(sanitized_param(Request.QueryString("myQS")))
    

    Or to assign the query string to a variable first then sanitize it:

    Dim myQS
    
    myQS = Request.QueryString("myQS")
    myQS = sanitized_param(myQS)
    
    ' or
    
    myQS = sanitized_param(Request.QueryString("myQS"))
    

    Once the query string has been assigned to a variable and sanitized you're able to reference that variable as often as you like without having to pass it to your sanitize function again.

    Also, your example code doesn't make much sense. The key value in your for each loop is referencing just the names of your query strings and not their values. If Response.QueryString was a valid ASP command you would do:

    Response.QueryString(key) = sanitized_param(Request.QueryString(key))

    But again, this isn't possible.


    EDIT: This solution might be what you're looking for:

    Create a dictionary object, call it "QueryString" for example. Loop through all your query strings and add a sanitized version to the dictionary object.

    Dim QueryString : Set QueryString = Server.CreateObject("Scripting.Dictionary")
    
    For Each Item In Request.QueryString
        QueryString.Add Item,sanitized_param(Request.QueryString(Item))
    next
    

    Now, to retrieve a sanitized version of a query string just use:

    QueryString.Item("query_string_name")
    

    Or for the original unsanitized version you could still use:

    Request.QueryString("query_string_name")
    

    Just like Request.QueryString, the dictionary object is forgiving and won't return an error if you ask for a query string that doesn't exist.


    You could also create a function for retrieving sanitized query strings, for example:

    Function SanitizedQS(ByVal qsName)
        SanitizedQS = sanitized_param(Request.QueryString(qsName))
    End Function
    

    And rather than using Request.QueryString("query_string_name") just use SanitizedQS("query_string_name").