ColdFusion CFImage Bug - Font Size Data Type Casting

Posted February 11, 2008 at 7:04 AM by Ben Nadel

Tags: ColdFusion

Normally, I am hesitant to call anything in ColdFusion a bug, but since ColdFusion is a dynamically typed language that can cast all simple values to strings, I have to come right out and say that this is a bug. Take a look at the following code:

  • <!--- Loop over font sizes. --->
  • <cfloop
  • index="intFontSize"
  • from="10"
  • to="50"
  • step="10">
  •  
  • <!--- Create ColdFusion image canvas. --->
  • <cfset objImage = ImageNew( "", 500, 150, "rgb" ) />
  •  
  • <!--- Create font properties. --->
  • <cfset objFontProperties = {
  • Font = "Courier New",
  • Size = intFontSize,
  • Style = "normal"
  • } />
  •  
  • <!--- Draw text. --->
  • <cfset ImageDrawText(
  • objImage,
  • "Test Font (#intFontSize#pt)",
  • 10,
  • (intFontSize + 20),
  • objFontProperties
  • ) />
  •  
  • <!--- Draw image. --->
  • <cfimage
  • action="writetobrowser"
  • source="#objImage#"
  • />
  •  
  • </cfloop>

Notice here that we are just looping over different font sizes so that we can see how they look on the canvas. Pretty simple, right. Well, when you run this code, you get the following ColdFusion error:

java.lang.Double cannot be cast to java.lang.String. Error casting an object of type java.lang.Double cannot be cast to java.lang.String to an incompatible type. This usually indicates a programming error in Java, although it could also mean you have tried to use a foreign object in a different way than it was designed.

This error, while explicit, is not obvious. If you look at the code above, all the string values are text and all the numeric values are, well, numeric. So, how did I fix this error? When setting up the font properties struct, I had to cast the font size to a string:

  • <!--- Create font properties. --->
  • <cfset objFontProperties = {
  • Font = "Courier New",
  • Size = ToString( intFontSize ),
  • Style = "normal"
  • } />

Notice that the Size property value is now wrapped in a ToString() method. This is because the CFLoop tag is creating an index value of type Double and for some reason ColdFusion cannot cast this Double value to a String value which is clearly what the ImageDrawText() function needs. I have to put my foot down and say that this is definitely a bug. Part of the reason that I am so adamant about this being a bug is that I discovered it while writing a ColdFusion user defined function for Image creation. In the UDF, I had an argument for FontSize and the Type attribute of the CFArgument tag was set to "String". The value I was passing in clearly validated against the Type checking of the CFArgument tag but then threw a type casting error when used within the CFFunction to draw image text.

In general, I am going to say that any time ColdFusion cannot cast a simple value to a string, it is a bug.



Reader Comments

Feb 13, 2008 at 12:46 AM // reply »
8 Comments

Ben,

I would not be so fast to call it a bug. I may be deadly wrong but for me ColdFusion is doing things this way:

1. You call your UDF and pass a clearly numeric type (as defined directly by the CFLOOP);

2. Your UDF tries to validate it - so, CF converts numeric type to string successfully and goes on.
BUT WAIT - CF didn't convert the VARIABLE - only the value! And for validation purposes. The variable still IS a numeric type, as defined by the loop that created it;

3. You pass the argument received to a CF function, which is JAVA and therefore doesn't convert anything, so you get the error.

Now, I can see how you thought - and I'm not certain if you're wrong - this is a bug. If my UDF needs a STRING, CF should not only test it but rather convert it directly, right?

Well, that's a question beyond my developer skills ;) but as I was trapped in errors like this one so many times, I would like to share the process I went through to find a solution and see if any CF-related developer went down here to enlighten us :)

Best wishes and continues with your really great blogging! I don't miss one of your posts.

Fernando


Feb 13, 2008 at 7:16 AM // reply »
10,640 Comments

@Fernando,

I think the whole fact that CFArgument validates a ColdFusion and then doesn't have it work properly in later calls is enough to say it is a bug. I could understand if we were passing this value directly to a Java method and therefore needed to do some sort of JavaCast() call, but the fact is, we are passing the value to a ColdFusion function which should never require a JavaCast() since CF should automatically be able to handle simple data type conversions.


Jul 16, 2010 at 1:29 PM // reply »
1 Comments

You are the best... I owe you at least 1000 hours of my life!


Jul 18, 2010 at 11:37 AM // reply »
10,640 Comments

@Anthony,

No worries - it's my pleasure.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »