From c9198dbbb8422306cb2d3b05b232ee114317e3f6 Mon Sep 17 00:00:00 2001
From: Shuhei Tanuma <chobieee@gmail.com>
Date: Thu, 17 Dec 2015 11:35:31 +0900
Subject: [PATCH] (PHP) fixes getting indirect table, also fixes getInt method
 on 32bit machine.

---
 php/ByteBuffer.php               |   9 +++++++--
 src/idl_gen_php.cpp              |   8 +++++++-
 tests/MyGame/Example/Monster.php |   4 ++--
 tests/generate_code.bat          |   1 +
 tests/generate_code.sh           |   1 +
 tests/monsterdata_indirect.json  |   6 ++++++
 tests/monsterdata_indirect.mon   | Bin 0 -> 156 bytes
 tests/phpTest.php                |  13 ++++++++++++-
 8 files changed, 36 insertions(+), 6 deletions(-)
 create mode 100644 tests/monsterdata_indirect.json
 create mode 100644 tests/monsterdata_indirect.mon

diff --git a/php/ByteBuffer.php b/php/ByteBuffer.php
index 9ab9717a..9929a7df 100644
--- a/php/ByteBuffer.php
+++ b/php/ByteBuffer.php
@@ -399,8 +399,13 @@ class ByteBuffer
         $sign = $index + (ByteBuffer::isLittleEndian() ? 3 : 0);
         $issigned = isset($this->_buffer[$sign]) && ord($this->_buffer[$sign]) & 0x80;
 
-        // 4294967296 = 1 << 32 = Maximum unsigned 32-bit int
-        return $issigned ? $result - 4294967296 : $result;
+        if (PHP_INT_SIZE > 4) {
+            // 4294967296 = 1 << 32 = Maximum unsigned 32-bit int
+            return $issigned ? $result - 4294967296 : $result;
+        } else {
+            // 32bit / Windows treated number as signed integer.
+            return $result;
+        }
     }
 
     /**
diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp
index 2aa7e222..2488b1d1 100644
--- a/src/idl_gen_php.cpp
+++ b/src/idl_gen_php.cpp
@@ -249,7 +249,13 @@ namespace php {
         NumToString(field.value.offset) +
         ");\n";
       code += Indent + Indent;
-      code += "return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : ";
+      code += "return $o != 0 ? $obj->init(";
+	  if (field.value.type.struct_def->fixed)
+      {
+        code += "$o + $this->bb_pos, $this->bb) : ";
+      } else {
+        code += "$this->__indirect($o + $this->bb_pos), $this->bb) : ";
+      }
       code += GenDefaultValue(field.value) + ";\n";
       code += Indent + "}\n\n";
     }
diff --git a/tests/MyGame/Example/Monster.php b/tests/MyGame/Example/Monster.php
index 94a0df7d..6c1d34a0 100644
--- a/tests/MyGame/Example/Monster.php
+++ b/tests/MyGame/Example/Monster.php
@@ -188,7 +188,7 @@ class Monster extends Table
     {
         $obj = new Monster();
         $o = $this->__offset(28);
-        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
     }
 
     /**
@@ -214,7 +214,7 @@ class Monster extends Table
     {
         $obj = new Stat();
         $o = $this->__offset(32);
-        return $o != 0 ? $obj->init($o + $this->bb_pos, $this->bb) : 0;
+        return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
     }
 
     /**
diff --git a/tests/generate_code.bat b/tests/generate_code.bat
index 75ac1433..c46d10af 100644
--- a/tests/generate_code.bat
+++ b/tests/generate_code.bat
@@ -1,2 +1,3 @@
 ..\flatc.exe -c -j -n -g -b -p --php -s --gen-mutable --no-includes monster_test.fbs monsterdata_test.json
 ..\flatc.exe -b --schema monster_test.fbs
+..\flatc.exe -b .\monster_test.fbs .\monsterdata_indirect.json
\ No newline at end of file
diff --git a/tests/generate_code.sh b/tests/generate_code.sh
index 91661f30..de736da5 100644
--- a/tests/generate_code.sh
+++ b/tests/generate_code.sh
@@ -1,2 +1,3 @@
 ../flatc --cpp --java --csharp --go --binary --python --js --php --gen-mutable --no-includes monster_test.fbs monsterdata_test.json
 ../flatc --binary --schema monster_test.fbs
+../flatc --binary monster_test.fbs monsterdata_indirect.json
\ No newline at end of file
diff --git a/tests/monsterdata_indirect.json b/tests/monsterdata_indirect.json
new file mode 100644
index 00000000..297c1721
--- /dev/null
+++ b/tests/monsterdata_indirect.json
@@ -0,0 +1,6 @@
+{
+  "name": "Gob",
+  "enemy": {
+    "name": "Awk"
+  }
+}
\ No newline at end of file
diff --git a/tests/monsterdata_indirect.mon b/tests/monsterdata_indirect.mon
new file mode 100644
index 0000000000000000000000000000000000000000..f6262f32d7ef8ca17f248065de056846ffb8b24f
GIT binary patch
literal 156
zcmZ=@U|{g|_X}oVFk|2YvO$0aLLreHNNiN58IT(Q#5Q1IGX|JSOfyjRA@e|HfYdVs
Ov155Qn0C)kVgLYoBLz(W

literal 0
HcmV?d00001

diff --git a/tests/phpTest.php b/tests/phpTest.php
index e91e47a1..027780cc 100644
--- a/tests/phpTest.php
+++ b/tests/phpTest.php
@@ -74,6 +74,9 @@ function main()
     fuzzTest1($assert);
 //    testUnicode($assert);
 
+
+    testIndirectBuffer($assert);
+
     echo 'FlatBuffers php test: completed successfully' . PHP_EOL;
 }
 
@@ -587,7 +590,15 @@ function testByteBuffer(Assert $assert) {
     $assert->Equal(0x0D0C0B0A, $uut->readLittleEndian(0, 4, true));
 
 }
-
+function testIndirectBuffer(Assert $assert)
+{
+    $js = json_decode(file_get_contents('monsterdata_indirect.json'), true);
+    $data = file_get_contents('monsterdata_indirect.mon');
+    $bb = Google\FlatBuffers\ByteBuffer::wrap($data);
+    $mons = \MyGame\Example\Monster::getRootAsMonster($bb);
+    $assert->Equal($js["name"], $mons->getName());
+    $assert->Equal($js["enemy"]["name"], $mons->getEnemy()->getName());
+}
 class Assert {
     public function ok($result, $message = "") {
         if (!$result){
-- 
GitLab