airsdk / Adobe-Runtime-Support

Report, track and discuss issues in Adobe AIR. Monitored by Adobe - and HARMAN - and maintained by the AIR community.
201 stars 11 forks source link

WebService call converting string into Infinity integer #3268

Open Formability opened 4 months ago

Formability commented 4 months ago

Before reporting this issue:

Problem Description

Describe your problem in detail. Include the following information:

Steps to Reproduce

Use a web service to retrieve XML from a server and when the string "9e999" is received the result array treats it as an Integer and sets it to Infinity.

Give us a minimal example:

Web service call downloadResult.addEventListener(ResultEvent.RESULT,dataDownloadSuccess); downloadResult.token = MyWebService.getDownload(itemID);

XML Returned

`

123 9e999

`

dataDownloadSuccess Method

if (event.result.result == 'success') { if (event.result.items!= null && event.result.items.item != null) { var tmp:Object = event.result.items.item[0]; var displayData:String = tmp['name'] } }

displayData will have the word "Infinity" in it instead of the string "9e999"

ajwfrost commented 4 months ago

Interesting one! That doesn't appear to happen within the XML handling of the runtime, so presumably is related more to the service call and deserialisation / conversion of the data into the object there. Although checking the AMF serialisation, this also works fine...

When you say the 'XML returned' is that string with the 9e999 value, how are you showing that string i.e. where do you get the information from? Is that from something like

trace( event.result.toXMLString() );

(If not, can you check that value?)

I don't suppose you're able to set up a test case/environment for this? Plus: you're using Flex I assume, so I'm wondering if you have checked on the wire to see whether that is the string actually coming down from the server?

My guess is that this could be a Flex issue itself, but we can try to get a reproduction of it and see whereabouts the data goes wrong..

thanks

Formability commented 4 months ago

Yes were using Flex. To show me the returned XML I use a logging function that outputs to the console.

`protected function initLogging():void { var t:TraceTarget = new TraceTarget(); t.filters=['*']; t.level = LogEventLevel.ALL; t.includeDate = true; t.includeTime = true; t.includeCategory = true; t.includeLevel = true; Log.addTarget(t);

}`

and call it at the start of the app. I also can confirm the data returned in the Network Monitor in Flash Builder.

One thing we have found is if we add a period to the end of the offending data its converted OK and shows OK in the app. As soon as we remove the period, it goes back to showing Infinity.

I will try to set up a test for this and get back to you.

Formability commented 4 months ago

Here is a test app that calls for some test XML from our website. It's a Flash Builder project with a HTTP web service.

infinitytest.zip

ajwfrost commented 4 months ago

Thanks for the test case. Reproduced here, and tracked back where a "9e999" string is being converted to a number.. it happens within the below class: https://github.com/apache/flex-sdk/blob/release4.16.0/frameworks/projects/rpc/src/mx/rpc/xml/ComplexString.as

This internal utility class is used by SimpleXMLDecoder. The class is basically a dynamic version of the String class (other properties can be attached to it).

When you try to get the value of a ComplexString, we attempt to convert the value to a number or boolean before returning it.

And the conversion itself is in https://github.com/apache/flex-sdk/blob/release4.16.0/frameworks/projects/rpc/src/mx/rpc/xml/SimpleXMLDecoder.as

Pseudocode:

  1. if it's a zero-length string, just use that
  2. if it's "not a number", or it starts "0", or it starts "-0", or it ends "E", then check for a conversion to boolean, otherwise return the string
  3. otherwise just convert it to a number

The problem being, "9e999" is a valid string representation of a number, so "Number(val)" returns a valid number (albeit too large to fit in a double floating point hence 'infinity') and "isNaN" of this returns false. So we drop into the final block and convert it to the number, 9 x 10^999 = near enough infinity...

I guess your options here would be: a) Update the Flex class above and include that into your build, so that it isn't hitting this problem b) Reformat the string so that anything which the server sends that could be representative of a number, but isn't, is prefixed by something to ensure that "Number()" returns NaN...

Interesting case!

thanks