Status Update, And A Couple Of Neat Things You Should Know
I was going to post something a little more... substantial, but then fate intervened. OK, it wasn't fate, but rather a lack of preparation on my part. I recently had to format my hard drive, and when I reinstalled all of my programs, I forgot the most important ones: my dev environment! So... when I came to get a post ready on Friday, I wasn't setup to get anything prepared! Instead of updating my blog, I was stuck installing (CF)Eclipse, SQL Server 2005 (and banging my head on the new roles/privileges/schemas system), SVN, no-ip and the likes. By the time I was done, so was the day. Today, I had set aside some time to write that entry I had prepared. However, not all went according to plan.
Coldfusion and WSDL
Part of what I was preparing to talk about concerns WSDL, or Web Services Description Language. Basically, it is a description of how a web service provider identifies itself and the services it offers. In Coldfusion, a web service provider can be a CFC, and the services are its methods (more on that in the next post). The thing is, Coldfusion caches the WSDL for a web service the first time it is requested. The problem with this is that this cached WSDL will remain in memory until something else needs to take its place.
Why is this an issue, you might ask? Well, that all depends on a couple of factors. An important part of what is included in the WSDL is the returntype of the services (methods!). Now, imagine for a second that you're on a development environment, and you're still working on your methods. If at one point you change the returntype and try pinging your web service, you might get a message that looks like this:
org.xml.sax.SAXException: Bad types (class java.lang.String -> class [Ljava.lang.Object;)
This is Coldfusion's way of telling you it was expecting one data type (as per the WSDL) but received some other type. The first thing you might try is a couple of page refreshes, but chances are that's not going to work. The easiest way to solve this problem is to fire up Coldfusion Administrator. In the Data & Services section, click on Web Services. In the bottom of this page you'll find Active ColdFusion Web Services, which is a list of all requested web services on your server. Here you can Edit, Refresh and Delete any of the web services listed. Click on the appropriate Refresh button and voilà, your WSDL has just been updated!
Coldfusion and MySQL
As I was getting ready to get my example pages ready, I realized that the database on my host runs on MySQL. However, I normally work with MSSQL, which is what I had installed on my dev machine and was what I had written my scripts on. Obviously these scripts didn't work on MySQL, so I had to rewrite them. Here's the script:
COLUMN_A varchar ( 50 ),
COLUMN_B varchar ( 50 )
);
insert into data values ( 'A LITTLE BIT FROM', 'AND A LITTLE BIT FROM' );
insert into data values ( 'WHAT''S BEHIND DOOR NUMBER 1?', 'AND DOOR NUMBER 2?' );
insert into data values ( 'FOO', 'BAR' );
select * from data;
Notice the series of statements. Normally that's not a problem. However, it seems the MySQL driver that ships with Coldfusion doesn't allow for multiple statements per cfquery block by default (I run CF8, I don't know if it's an issue with the other versions). Fortunately, there's an easy fix for this. In the Coldfusion Administrator, go into Data Sources and edit the datasource that's causing the issues. Click on the Show Advanced Settings button and add allowMultiQueries=true to the Connection String field. Submit, save, and refresh. You'll see that the query now runs fine and returns the appropriate temporary table dataset.
Edit: Always be careful when allowing this type of query to pass. This query is static, as in it will never change and does not depend on user input, which makes it safe. However, a malicious user could take advantage of a query like "select * from users where id=#id#" and find a way to pass in "0; delete users;" as the value of id. When accepting user inputs, always use cfqueryparam tags to protect your variables!
If all goes well I should have that next post ready in the next couple of days, so stay tuned!
I make my own luck.


it's disabled for a good reason, it's one of the classic SQL injection approaches
Thanks, I had forgotten to mention that. From what I had read on the net prior to posting, the entire reason why the driver prevents multi-line queries by default is exactly for that, to prevent injection attacks.
The issue at hand is that most other DBs allow multi-line queries to pass, and leaves prevention up to the programmer. Luckily for us, CF provides the really neat cfqueryparam tags that basically renders SQL injection attacks harmless.
The script in the post is part of another entry which I'm about to write, so I guess I didn't provide enough information on it (which I'm about to edit in). Basically it's just to create and populate a dummy query, so no dynamic input is ever sent to the DB. However, I do try to put cfqueryparams wherever I can.
Let me know what you think.