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 »
11,246 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 »
11,246 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
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 24, 2013 at 5:39 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam Oops! My mistake! I hadn't gotten that far in my testing - I'm still baby stepping my way through the process. ... read »
May 24, 2013 at 5:13 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
Hi Jason, Thanks for checking up on that, but I still stand firm on my position. :) There are actually two listLast()'s in use, and you're right that the one using a space as a delimiter is fine. ... read »
May 24, 2013 at 4:45 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Ben I have been lurking your site for quite some time, and haven't stepped up to comment until today. Thanks for all the great info - keep it up! @Adam I believe you are mistaken... as the commen ... read »
May 24, 2013 at 11:21 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, Ha ha, let's us never speak of justifying "##" notation again :P ... read »
May 24, 2013 at 11:18 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Ah, so it was indeed how I vaguely remembered it to be: A direct assignment value = users.id[ i ] causes value to retain the sticky datatype of the query column. Although unnecessary in ... read »
May 24, 2013 at 9:11 AM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Brandon, Hi, No, I haven't been able to do that. I have just kept it as it is. ... read »
May 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools