neoxic / php-amf3

PHP AMF3 extension

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

在接收数据时候的问题。

mylovefly001 opened this issue · comments

有BUG的,在当AS3发送的参数中,有值为0,如:t=0,或者有值为浮点数如t=3.1415,这些值时,PHP会收不到POST过来的数据。
如果有值为大于100的数字如:t=386,这时候amf3_decode方法会自动把这些数字转换掉。。。

Sorry, can't understand Chinese well enough.

test as3 code:

var request=new URLRequest('http://test.xxx.com/index/test');
request.method = URLRequestMethod.POST;
var data = new URLVariables();
var bytes:ByteArray = new ByteArray();
bytes.objectEncoding = ObjectEncoding.AMF3;
//write an object into the bytearray
bytes.writeObject(
{ myString:"Hello World",age:5,money:10000}
);
data.data = bytes;
request.data = data;

var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(Event.COMPLETE, onCompleteHandler);
urlLoader.load(request);

function onCompleteHandler(evt:Event):void {
trace(evt.target.data);
}

php code: json_encode(amf3_decode($_POST["data"]));

test result:

1、as3 request param: { myString:"Hello World",age:5,money:10000}
php received param, amf3_decode:{"myString":"Hello World","money":1099536,"age":5}

2、as3 request param: { myString:"Hello World",age:5,money:1.41421}
php received param,amf3_decode:{"myString":"Hello World","money":1.16421,"age":5}

3、as3 request param: { myString:"Hello World",age:5,money:0}
php received param,amf3_decode:null

4、as3 request param:{ myString:"Hello World",age:5,money:"0", star:"99999"}
php received param,amf3_decode:amf3_decode:{"myString":"Hello World","age":5,"money":"0","star":"99999"}

1, 2 are not properly identify, will automatically be conversion value.
3 direct access to NULL
4 is AS3 send parameters, packaged into a string type, in order to get to the value.
Why can't identify large int, and float type data?

To identify your problem, I need to see the hex dump of the data on the PHP side. Can you dump what you feed to amf3_decode()? That is:

print bin2hex($_POST["data"]);

It looks like you're having a spurious data offset or type mismatch somewhere.

1、as3 request param: { myString:"Hello World",age:5,money:10000}
php received param

     print bin2hex($_POST['data'])

0a0b01076167650405116d79537472696e67061748656c6c6f20576f726c640b6d6f6e657904c38e1001

     amf3_decode:{"myString":"Hello World","money":1099536,"age":5}

2、as3 request param: { myString:"Hello World",age:5,money:1.41421}
php received param

    print bin2hex($_POST['data'])

0a0b01116d79537472696e67061748656c6c6f20576f726c640b6d6f6e6579053ff2a09aaa3ad18d07616765040501

     amf3_decode:{"myString":"Hello World","money":1.16421,"age":5}

3、as3 request param: { myString:"Hello World",age:5,money:0}
php received param

 print bin2hex($_POST['data']):

0a0b01116d79537472696e67061748656c6c6f20576f726c640b6d6f6e657904

     amf3_decode:null

4、as3 request param:{ myString:"Hello World",age:5,money:"0", star:"99999"}
php received param

   print bin2hex($_POST['data'])

0a0b01116d79537472696e67061748656c6c6f20576f726c640761676504050b6d6f6e65790603300973746172060b393939393901

amf3_decode:amf3_decode:{"myString":"Hello World","age":5,"money":"0","star":"99999"}

5、as3 request param:{ myString:"Hello World",age:5,money:"0", star:99999}
php received param

   print bin2hex($_POST['data'])

0a0b01116d79537472696e67061748656c6c6f20576f726c640761676504050b6d6f6e6579060330097374617204c286c28d1f01

Ok, to illustrate that the problem, whatever it is, is similar for all the cases and is on the encoding side, I will pick a couple of the cases and thoroughly disassemble them from the perspective of the decoder according to the AMF3 specification.


1.

{ myString:"Hello World",age:5,money:10000}

comes into

0a0b01076167650405116d79537472696e67061748656c6c6f20576f726c640b6d6f6e657904c38e1001

and decodes as

{"myString":"Hello World","money":1099536,"age":5}

Let's look at the data closer. Scroll to the right to see all the text.

0a 0b01 - anonymous object with zero static fields and a dynamic part following (string keys and values terminated by an empty string)

pair #1:
07 616765 - string length=(0x07/2)=3, data='age' --> this is the key "age"
04 05 - type=0x04 (INTEGER), value=5 --> this is the value 5

pair #2:
11 6d79537472696e67 - string length=(0x11/2)=8, data='myString' --> this is the key "myString"
06 17 48656c6c6f20576f726c64 - type=0x06 (STRING), string length=(0x17/2)=11, data='Hello World' --> this is the value "Hello World"

pair #3:
0b 6d6f6e6579 - string length=(0x0b/2)=5, data='money' --> this is the key "money"
04 c38e10 - type=0x04 (INTEGER), value=1099536 --> this is the value for "money" (see below)

end of dynamic part
01 - empty string

So, it looks like the object is perfectly valid from the point of decoder's view. The only culprit here is the value of the "money" key which is deemed to be wrong. Let's take a closer look. AMF3 stores integers in a special form called U29 where the length of the chunk is variable depending on the value itself. Only 29 bits are significant. The rest 3 bits are used to determine the length. Very much like in UTF8. Let's see what we have:

c3 8e 10 - 3 bytes in the chunk in network byte order (first is on the left, last on the right)
11000011 10001110 00010000 - binary view of the same bytes
1 1000011 1 0001110 0 0010000
^         ^         ^ - insignificant higher bits (first two tell that there is a next byte coming, the last is zero which means end of integer data)
1000011 0001110 0010000 - remaining significant 7-bit chunks

Since the value is stored as a big-endian sequence, we can get it just by glueing the above chunks in a code like this:

print 0b100001100011100010000."\n";

And we get

1099536

Hence this value has been encoded initially and is not an error result of the decoder.


2.

{ myString:"Hello World",age:5,money:0}

comes into

0a0b01116d79537472696e67061748656c6c6f20576f726c640b6d6f6e657904

and decodes as

NULL

Well, actually it doesn't decode as just NULL. It does indicate an error in the data being decoded. You probably have to look at your PHP error log or enable displaying errors to see error messages right away.

Warning: Insufficient integer data at position 32

So, let's look closer at the data

0a0b01 - the same object type as above

pair #1:
116d79537472696e67 061748656c6c6f20576f726c64 - "myString" => "Hello World"

pair #2:
0b6d6f6e6579 04 - "money" => type=0x04 (INTEGER) but no data after it! Hence the decoding error.

So this data is unfinished, thus invalid and cannot be properly decoded! It breaks in the middle of the second key-value pair as you can see.


To conclude, I don't know the root cause of your problem but it looks like something corrupts your data in between.