Skip to content

Commit fb8d657

Browse files
committed
Fixed small bug which allowed array keys to be referenceable, fixed dynamic object type and added ByteArray serialization
1 parent a538275 commit fb8d657

File tree

5 files changed

+82
-11
lines changed

5 files changed

+82
-11
lines changed

lib/ByteArray.php

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
namespace AMF;
3+
4+
/**
5+
* @author Danny Kopping <[email protected]>
6+
*/
7+
class ByteArray
8+
{
9+
private $data;
10+
11+
public function __construct($data)
12+
{
13+
$this->data = $data;
14+
}
15+
16+
/**
17+
* @param mixed $data
18+
*/
19+
public function setData($data)
20+
{
21+
$this->data = $data;
22+
}
23+
24+
/**
25+
* @return mixed
26+
*/
27+
public function getData()
28+
{
29+
return $this->data;
30+
}
31+
}

lib/Serializer.php

+30-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
namespace AMF;
33

44
use AMF\Exception\NotSupportedException;
5+
use AMF\Exception\SerializationException;
56
use DateTime;
67
use Exception;
78
use SimpleXMLElement;
@@ -59,6 +60,10 @@ public static function serialize($data, $includeType = true)
5960
self::serializeDate($data, $includeType);
6061
break;
6162

63+
case ($data instanceof ByteArray):
64+
self::serializeByteArray($data, $includeType);
65+
break;
66+
6267
case is_array($data):
6368
self::serializeArray($data, $includeType);
6469
break;
@@ -194,17 +199,18 @@ private static function serializeArray($data)
194199

195200
$isDense = Spec::isDenseArray($data);
196201
if ($isDense) {
197-
self::serializeInt((count($data) << 1) | 0x01, false);
202+
self::serializeInt((count($data) << 1) | Spec::REFERENCE_BIT, false);
198203
self::serializeString('', false);
199204

200205
foreach ($data as $element) {
201206
self::serialize($element);
202207
}
208+
203209
} else {
204210
self::serializeInt(1, false);
205211

206212
foreach ($data as $key => $value) {
207-
self::serializeString((string) $key, false);
213+
self::serializeString((string) $key, false, false);
208214
self::serialize($value);
209215
}
210216

@@ -240,23 +246,24 @@ private static function serializeObject($data)
240246
}
241247

242248
// write object info & class name
243-
self::serializeInt(($numProperties << 0x04) | ((int) $externalizable << 0x02) | 0x03, false);
244-
self::serializeString(self::getObjectClassname($data), false);
249+
if($dynamic) {
250+
self::serializeInt(0x0b, false);
251+
} else {
252+
self::serializeInt(($numProperties << 0x04) | ((int) $externalizable << 0x02) | 0x03, false);
253+
}
254+
255+
self::serializeString(self::getObjectClassname($data), false, false);
245256

246257
if ($dynamic) {
247258

248259
// write keys
249260
foreach ($properties as $key => $value) {
250261
self::serializeString($key, false, false);
251-
}
252-
253-
// write values
254-
foreach ($properties as $key => $value) {
255262
self::serialize($value);
256263
}
257264

258265
// close
259-
self::serializeInt(0x01, false);
266+
self::serializeInt(Spec::REFERENCE_BIT, false);
260267
} else {
261268

262269
/**
@@ -269,6 +276,20 @@ private static function serializeObject($data)
269276
}
270277
}
271278

279+
private static function serializeByteArray($data, $includeType = true)
280+
{
281+
if ($includeType) {
282+
self::writeBytes(Spec::TYPE_BYTE_ARRAY);
283+
}
284+
285+
if (!$data instanceof ByteArray) {
286+
throw new SerializationException('Invalid ByteArray data provided');
287+
}
288+
289+
self::serializeInt(strlen($data->getData()) << 1 | Spec::REFERENCE_BIT, false);
290+
self::writeBytes($data->getData(), true);
291+
}
292+
272293
private static function writeBytes($bytes, $raw = false)
273294
{
274295
self::$packet .= $raw ? $bytes : pack('c', $bytes);

lib/Spec.php

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class Spec
3535
const OBJECT_DYNAMIC = 0x00;
3636
const OBJECT_EXTERNALIZABLE = 0x01;
3737

38+
const REFERENCE_BIT = 0x01;
39+
3840
public static function getMaxInt()
3941
{
4042
return pow(2, 28) - 1;

tests/SerializationTest.php

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22
use AMF\AMF;
3+
use AMF\ByteArray;
34
use AMF\IExternalizable;
45
use AMF\Spec;
56
use AMF\Undefined;
@@ -63,7 +64,7 @@ public function testSerializeObject()
6364
$dyn->a = 'b';
6465
$dyn->b = array('123');
6566

66-
$this->assertEquals('0a230103610362060362090301060731323301', bin2hex(AMF::serialize($dyn)));
67+
$this->assertEquals('0a0b0103610603620362090301060731323301', bin2hex(AMF::serialize($dyn)));
6768

6869
// externalizable object
6970
$ext = new ExternalizableClass();
@@ -77,7 +78,23 @@ public function testSerializeObject()
7778

7879
// object with no properties
7980
$null = new stdClass();
80-
$this->assertEquals('0a030101', bin2hex(AMF::serialize($null)));
81+
$this->assertEquals('0a0b0101', bin2hex(AMF::serialize($null)));
82+
}
83+
84+
public function testSerializeBytes()
85+
{
86+
$bytes = new ByteArray('A');
87+
$this->assertEquals('0c0341', bin2hex(AMF::serialize($bytes)));
88+
89+
$bytes = new ByteArray('$1�2');
90+
$this->assertEquals('0c132431c3afc2bfc2bd32', bin2hex(AMF::serialize($bytes)));
91+
92+
$bytes = new ByteArray(0b11000011101010); // 12522
93+
$this->assertEquals('0c0b3132353232', bin2hex(AMF::serialize($bytes)));
94+
95+
$bytes = new ByteArray(file_get_contents(__DIR__.'/php.ico'));
96+
$this->assertEquals('0c8c6d424d360300000000000036000000280000001000000010000000010018000000000000030000c40e0000c40e00000000000000000000c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080d7d7d7d7d7d7d7d7d7c08080c08080c08080c08080c08080c08080c08080d7d7d7d7d7d7d7d7d7c08080c08080c08080d7d7d7000000d7d7d7c08080c08080c08080c08080c08080c08080c08080d7d7d7000000d7d7d7c08080c08080c08080d7d7d7000000d7d7d7d7d7d7c08080c08080d7d7d7c08080c08080d7d7d7d7d7d7000000d7d7d7d7d7d7c08080c08080d7d7d7000000000000000000d7d7d7d7d7d7000000d7d7d7d7d7d7000000d7d7d7000000000000000000d7d7d7d7d7d7d7d7d7000000d7d7d7d7d7d7000000d7d7d7000000d7d7d7d7d7d7000000d7d7d7000000d7d7d7d7d7d7000000d7d7d7d7d7d7000000d7d7d7d7d7d7000000d7d7d7000000d7d7d7d7d7d7000000d7d7d7000000d7d7d7d7d7d7000000d7d7d7d7d7d7000000d7d7d7d7d7d7000000d7d7d7000000d7d7d7d7d7d7000000d7d7d7000000d7d7d7d7d7d7000000d7d7d7d7d7d7000000000000000000d7d7d7d7d7d7000000000000000000d7d7d7d7d7d7000000000000000000d7d7d7d7d7d7c08080d7d7d7d7d7d7d7d7d7c08080d7d7d7000000d7d7d7d7d7d7c08080c08080d7d7d7d7d7d7d7d7d7c08080c08080c08080c08080c08080c08080c08080d7d7d7000000d7d7d7c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080d7d7d7d7d7d7d7d7d7c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080c08080',
97+
bin2hex(AMF::serialize($bytes)));
8198
}
8299
}
83100

tests/php.ico

822 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)