Skip to main content
Ben Nadel at CF Summit West 2024 (Las Vegas) with: Ferd Ang
Ben Nadel at CF Summit West 2024 (Las Vegas) with: Ferd Ang

Encoding "FFFFFFFF" Into An INT In Adobe ColdFusion

By
Published in Comments (2)

In my previous post on using inputBaseN() to encode HEX colors into an INT in ColdFusion, I had been testing my code in Lucee CFML. This is because I've been using this logic to generate barcodes with Zxing for work, and we use Lucee CFML at work. Over the weekend, however, I participated in the Adobe ColdFusion (ACF) 2025 hackathon; and, when I went to generate a QR Code in ACF, I was getting an error. It turns out, strict ACF integers have to fit into a signed int. As such, I had to use the 2's complement.

First, let's demonstrate the issue. I'm going to use the inputBaseN() function to parse ffffffff into a 4-byte value with every bit enabled. Then, I'm going to try and cast that to a Java int:

<cfscript>

	// An int Is 4-bytes. A byte is 8-bits and can hold a max of 255 (ff).
	encodedValue = repeatString( "ff", 4 );

	// Parse hex-encoded value into a numeric value. Note that both Lucee CFML have Adobe
	// ColdFusion (2025) have no problem with this step and can represent large numbers
	// beyond an int ( "ff ff ff ff" == 4,294,967,295 ).
	numericValue = inputBaseN( encodedValue, 16 );

	// Lock numeric value down to a 4-byte int.
	intValue = javaCast( "int", numericValue );

	// Recode value back into hex for confirmation.
	recodedValue = formatBaseN( intValue, 16 );

	// Results:
	writeDump([
		numericValue,
		intValue,
		recodedValue
	]);

</cfscript>

Here, we're basically casting ffffffff into a Java int. And, in Lucee CFML, this code works fine, which is why I never ran into an issue generating barcodes at work. However, when you run this in Adobe ColdFusion, you get the error:

Cannot convert the value 4.294967295E9 to an integer because it cannot fit inside an integer.

I don't understand why this works in Lucee CFML and fails in ACF - there's probably a reasonable technical constraint that I don't understand because I'm not a Java developer.

Aside: this isn't the first time that I've run into this kind of issue. Back when I was generating random bytes, I had to deal with signed vs. unsigned issues as well.

That said, we can work around this in Adobe ColdFusion by using the "two's complement". I don't pretend to have a full understanding of what the 2's complement actually is; other than it represents negative numbers when the most significant bit is 1. Which, for our purposes, means that our ffffffff value needs to be represented as a negative value when casting it. To fix our code for Adobe ColdFusion, we're going to subtract MAX_INT (plus 1) from it before we call javaCast():

<cfscript>

	// An int Is 4-bytes. A byte is 8-bits and can hold a max of 255 (ff).
	encodedValue = repeatString( "ff", 4 );

	// Parse hex-encoded value into a numeric value. Note that both Lucee CFML have Adobe
	// ColdFusion (2025) have no problem with this step and can represent large numbers
	// beyond an int ( "ff ff ff ff" == 4,294,967,295 ).
	numericValue = inputBaseN( encodedValue, 16 );

	// Lock numeric value down to a 4-byte int (using 2's complement).
	intValue = javaCast(
		"int",
		( numericValue - 4294967296 /* 2^32 */ ) // Subtract (MAX_INTEGER + 1).
	);

	// Recode value back into hex for confirmation.
	recodedValue = formatBaseN( intValue, 16 );

	// Results:
	writeDump([
		numericValue,
		intValue,
		recodedValue
	]);

</cfscript>

Now, when we run this CFML code in either Adobe ColdFusion or Lucee CFML, we get the following output:

CFDump output of the debugging in both Lucee CFML and Adobe ColdFusion 2025.

Once we use the two's complement approach, both Lucee CFML and Adobe ColdFusion can safely cast ffffffff to a Java int and then back into a hex value.

Two's Complement Explanation From ChatGPT

In my Adobe ColdFusion 2025 hackathon write-up, I mentioned that I had to get ChatGPT to help me with the two's complement stuff. I left it at that; but, yesterday I was looking in my error logs and I saw that Chris G. was trying to post a comment with his ChatGPT transcript. Unfortunately, my validation logic was preventing his comment from being posted. As such, I will post it here:


From Chris G.:

I had to use ChatGPT to explain "two's compliment" to me. 🤣

Absolutely! Let's break down two's complement in simple terms — especially how it applies to your ColdFusion + ZXing issue.

🔢 What is Two's Complement?

Two's complement is a method for representing signed integers (both positive and negative) in binary. It's the most common way computers store integers.

Here's the idea:

Positive numbers are stored the same as usual binary.

Negative numbers are stored by flipping the bits (binary digits) of the positive version and adding 1.

But more practically for you...

🧠 Why This Matters in ACF 2025

ColdFusion's int type is a 32-bit signed integer, which means it can store values in the range:

-2,147,483,648 to 2,147,483,647

Now, when you try to use a color value like 0xFFCCCCCC (which equals 4,294,967,244), that number is too big to fit in a 32-bit signed int. So ColdFusion throws an error.

💡 The Workaround: Two's Complement Trick

To trick ColdFusion into accepting that number, you can convert it to its two's complement equivalent by subtracting 4294967296 (which is 2^32):

0xFFCCCCCC = 4291611852

Two's complement version = 4291611852 - 4294967296 = -3355444

So instead of passing 4291611852, you pass -3355444. ZXing (which reads it as an unsigned int internally) will interpret it correctly, but ColdFusion will accept it as a valid signed int.

🔁 Summary (TL;DR)

ColdFusion uses signed 32-bit integers.

Color values like 0xFFCCCCCC are unsigned and out of range.

Use two's complement to represent large unsigned ints as negative signed ints:

signedInt = unsignedInt - 2^32

ZXing will treat the number as if it were unsigned.


Chris, if you read this, the validation logic was blocking the <hr> (produced from the ---- markdown). I can probably add that to my AntiSamy allow-list. And, maybe this will motivate me to finally upgrade my sanitization logic to use JSoup instead.

Want to use code from this post? Check out the license.

Reader Comments

279 Comments

@Ben

Ahhh...I thought it was weird that my comment was being blocked. I spent a little time trying to figure out which part was blocking, then gave up. I thought all was lost and abandoned the comment entirely. Was surprised to see it survived. Nice! Thanks for clearing up the mystery!

16,055 Comments

@Chris,

No problem! Glad that it was still in the logs (I'm on the BugSnag free tier, so not sure how long that data sticks around).

Post A Comment — I'd Love To Hear From You!

Post a Comment

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel