Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CFML InputBaseN not returning expected value

When using Adobe ColdFusion and trying to convert a hex string to a decimal we don't seem to be getting the result we are wanting/expecting.

<cfset i = #InputBaseN("A1000050", 16)# >
<cfdump var="#i#">

it is outputting -1593835440 We were expecting 2701131856

In windows calculator when we convert A1000050 to dec qword it gives us our expected result. However, if we use dword it gives us the save value ColdFusion gives us.

In ColdFusion what are we doing wrong? How can we get the expected value?

Binary of expected value (according to windows calc programmer mode)

0000 0000 0000 0000 0000 0000 0000 0000
1010 0001 0000 0000 0000 0000 0101 0000

= 2701131856

Binary value we are actually getting

1010 0001 0000 0000 0000 0000 0101 0000

= -1593835440

like image 907
shaun Avatar asked Jan 31 '18 16:01

shaun


2 Answers

My guess is you are using CF10 or 11? This appears to be a bug in those versions that was fixed in CF2016, but would break backwards-compatibility in 10/11.

https://tracker.adobe.com/#/view/CF-3712098

https://tracker.adobe.com/#/view/CF-4175842

Those bug logs do contain workarounds that may work for you.

I was able to verify the behavior.

-1593835440

CF10: https://trycf.com/gist/ab0e93b1d690401778a57b443ff42a3e/acf?theme=monokai

CF11: https://trycf.com/gist/45db48930b2cfbeec600d6d840521470/acf11?theme=monokai

Railo 4.2: https://trycf.com/gist/dee04bec7b7983bfd97dac69ea3bc930/railo?theme=monokai

Lucee 4.5: https://trycf.com/gist/31497d2b3a35ed69e9c95081ea5bd83d/lucee?theme=monokai

2701131856

CF2016: https://trycf.com/gist/73b81b7184f47275503ab57d5ee5eeaa/acf2016?theme=monokai

Lucee 5: https://trycf.com/gist/f73bd8fbe652f5c5675c658d5cd356f3/lucee5?theme=monokai

like image 91
Shawn Avatar answered Oct 11 '22 00:10

Shawn


Just to expand on Shawn's answer that it is a bug... Traditionally, most (though not all) CF numeric functions were limited to 32 bit signed integers. CF 2016 changed that by having inputBaseN() return a 64 bit integer, or Long. Most of the workarounds mentioned in the bug reports are trying to do the opposite of what you need (replicate the old behavior under CF2016). To replicate the new behavior under CF10/11, try using Long.parseLong() instead:

// Option 1. Using javacast. Returns 2701131856
value = javacast("long", 0).parseLong("A1000050", 16);

// Option 2. Using createObject. Returns 2701131856
value = createObject("java", "java.lang.Long").parseLong("A1000050", 16);

For CF servers running Java8, technically you could also invoke toUnsignedLong() on the resulting Integer, but .. it's brittle. Only works with CF10/11 and Java8+.

// ONLY works under CF10/11 and Java8+. Returns -2701131856 
origValue = InputBaseN(input, 16);
newValue = origValue .toUnsignedLong(origValue );

Example on trycf.com

like image 1
SOS Avatar answered Oct 10 '22 22:10

SOS