This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit db0995ea20121a7e0490627592367473248266f9
Author: greg-dove <greg.d...@gmail.com>
AuthorDate: Thu May 28 16:36:51 2020 +1200

    AMF improvements: Coverage for ignoring custom namespaces and also cases 
where Transient fields are still deserialized. They are only skipped during 
local serialization.
---
 .../royale/net/remoting/amf/AMFBinaryData.as       |  41 +++++---
 .../network/AMFBinaryDataTesterTest.as             | 109 ++++++++++++++++++++-
 .../flexUnitTests/network/support/TestClass6.as    |  72 ++++++++++++++
 .../flexUnitTests/network/support/TestClass7a.as   |  51 ++++++++++
 .../flexUnitTests/network/support/TestClass7b.as   |  49 +++++++++
 .../flexUnitTests/network/support/testnamespace.as |  26 +++++
 6 files changed, 334 insertions(+), 14 deletions(-)

diff --git 
a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFBinaryData.as
 
b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFBinaryData.as
index 3eb6955..89350f4 100644
--- 
a/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFBinaryData.as
+++ 
b/frameworks/projects/Network/src/main/royale/org/apache/royale/net/remoting/amf/AMFBinaryData.as
@@ -499,6 +499,7 @@ class SerializationContext extends BinaryData  implements 
IDataInput, IDataOutpu
                var l:uint;
                var metas:Array;
                var exclude:Boolean;
+               var transient:Boolean;
                var fieldName:String;
                const into:Array = localTraits.props;
                
@@ -509,9 +510,11 @@ class SerializationContext extends BinaryData  implements 
IDataInput, IDataOutpu
                        if (fieldName.indexOf('::') != -1) continue;
                        var field:Object = fieldSet[fieldName];
                        exclude = false;
+                       transient = false;
+                       var alreadyPresent:Boolean = into.indexOf(fieldName) != 
-1 ;
                        if (asAccessors) {
                                exclude = field.access != 'readwrite';
-                               if (exclude && into.indexOf(fieldName) == -1) { 
//<-- if at some level we already have read-write access, then that wins
+                               if (exclude && !alreadyPresent) { //<-- if at 
some level we already have read-write access, then that wins
                                        //check: does it combine to provide 
'readwrite' permissions via accessChecks through inheritance chain
                                        if (accessChecks[fieldName] && 
accessChecks[fieldName] != field.access) {
                                                //readonly or writeonly 
overridde at one level and different at another == readwrite
@@ -524,21 +527,18 @@ class SerializationContext extends BinaryData  implements 
IDataInput, IDataOutpu
                                        }
                                }
                        }
-                       if (!exclude && excludeTransient && field.metadata != 
null) {
-                               //exclude anything marked as Transient
+                       //if a subclass override does not redeclare the field 
as transient, then it is already considered explicitly 'non-transient'
+                       if (!exclude && !alreadyPresent && excludeTransient && 
field.metadata != null) {
+                               //we need to mark Transient fields as special 
case
                                metas = field.metadata();
                                l = metas.length;
                                while (l--) {
                                        if (metas[l].name == 'Transient') {
-                                               exclude = true;
+                                               transient = true;
+                                               Traits.markTransient(fieldName, 
localTraits);
+                                               break;
                                        }
                                }
-                               if (exclude && into.indexOf(fieldName) != -1) {
-                                       //?possible case where it is marked 
transient on an ancestor but not in a subclass override
-                                       //it will not have been excluded when 
processing the subclass, which occurs first, so remove it now
-                                       //@todo untested : check this scenario, 
assume it should be removed
-                                       into.splice(into.indexOf(fieldName), 1);
-                               }
                        }
                        if (!exclude) {
                                //set up null/undefined value lookups for 
undefined field values (when encoding)
@@ -554,7 +554,10 @@ class SerializationContext extends BinaryData  implements 
IDataInput, IDataOutpu
                                } else {
                                        nullValues[fieldName] = null;
                                }
-                               into.push(fieldName);
+                               if (alreadyPresent) {
+                                       into.splice(into.indexOf(fieldName), 1);
+                               }
+                               if (!transient) into.push(fieldName);
                                if (asAccessors) {
                                        localTraits.getterSetters[fieldName] = 
Traits.createInstanceAccessorGetterSetter(fieldName);
                                } else {
@@ -610,6 +613,9 @@ class SerializationContext extends BinaryData  implements 
IDataInput, IDataOutpu
                                        classInfo = 
c.constructor.superClass_.ROYALE_CLASS_INFO;
                                        c = c.constructor.superClass_;
                                }
+                               //sometimes flash native seriazliation 
double-counts props and outputs some props data twice.
+                               //this can happen with overrides (it was 
noticed with Transient overrides)
+                               //it may mean that js amf output can sometimes 
be more compact, but should always deserialize to the same result.
                                localTraits.count = localTraits.props.length;
                                //not required, but useful when testing:
                                localTraits.props.sort();
@@ -632,7 +638,6 @@ class SerializationContext extends BinaryData  implements 
IDataInput, IDataOutpu
                        }
                        //not required, but useful when testing:
                        localTraits.props.sort();
-                       
                }
                return localTraits;
        }
@@ -1102,7 +1107,7 @@ class SerializationContext extends BinaryData  implements 
IDataInput, IDataOutpu
                                for (var i:uint = 0; i < l; i++) {
                                        var fieldValue:* = readObject();
                                        var prop:String = 
decodedTraits.props[i];
-                                       hasProp = localTraits &&  
(localTraits.hasProp(prop) || localTraits.isDynamic);
+                                       hasProp = localTraits &&  
(localTraits.hasProp(prop) || localTraits.isDynamic || 
localTraits.isTransient(prop));
                                        if (hasProp) {
                                                
localTraits.getterSetters[prop].setValue(obj, fieldValue);
                                        } else {
@@ -1319,6 +1324,11 @@ class Traits {
                        }
                };
        }
+
+       public static function markTransient(fieldName:String, 
traits:Traits):void{
+               if (!traits.transients) traits.transients={};
+               traits.transients[fieldName] = true;
+       }
        
        private static var _emtpy_object:Traits;
        
@@ -1362,10 +1372,15 @@ class Traits {
        public var nullValues:Object = {};
        
        public var getterSetters:Object = {};
+       public var transients:Object ;
        
        public function hasProp(prop:String):Boolean {
                return props.indexOf(prop) != -1;
        }
+
+       public function isTransient(prop:String):Boolean {
+               return transients && prop in transients;
+       }
        
        public function toString():String {
                if (goog.DEBUG) {
diff --git 
a/frameworks/projects/Network/src/test/royale/flexUnitTests/network/AMFBinaryDataTesterTest.as
 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/AMFBinaryDataTesterTest.as
index 144d034..1cca14c 100644
--- 
a/frameworks/projects/Network/src/test/royale/flexUnitTests/network/AMFBinaryDataTesterTest.as
+++ 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/AMFBinaryDataTesterTest.as
@@ -27,7 +27,9 @@ package flexUnitTests.network
     import flexUnitTests.network.support.TestClass3;
     import flexUnitTests.network.support.TestClass4;
     import flexUnitTests.network.support.DynamicTestClass;
-    
+    import flexUnitTests.network.support.TestClass6;
+    import flexUnitTests.network.support.TestClass7a;
+    import flexUnitTests.network.support.TestClass7b;
     import org.apache.royale.test.asserts.*;
     
     import org.apache.royale.net.remoting.amf.AMFBinaryData;
@@ -532,6 +534,111 @@ package flexUnitTests.network
             //javascript toXMLString pretty printing does not match exactly 
flash...
             assertTrue( xml.toXMLString() === xml2.toXMLString(), "XML 
round-tripping failed");
         }
+
+
+        [Test]
+        public function testWithCustomNS():void
+        {
+            var ba:AMFBinaryData = new AMFBinaryData();
+            var test:TestClass6 = new TestClass6();
+            ba.writeObject(test);
+            ba.position = 0;
+            assertEquals(ba.length, 50, 'unexpected serialized content with 
custom namespaces');
+            //cover variation in order
+            const validOptions:Array = [
+                
'0a23010b6d79566172156d794163636573736f7206177075626c69634d79566172061f7075626c6963206163636573736f72',
+                
'0a2301156d794163636573736f720b6d79566172061f7075626c6963206163636573736f7206177075626c69634d79566172'
+            ];
+
+            assertTrue(validOptions.indexOf(getBytesOut(ba)) != -1, 
'unexpected byte content with custom namespace content');
+
+           /* var restored:Object = ba.readObject();
+
+            var json:String = JSON.stringify(restored)*/
+            //order may be different... need json object check here for: 
{"myAccessor":"public accessor","myVar":"publicMyVar"}
+        }
+
+        [Test]
+        public function testTransientAndBindable():void{
+            var ba:AMFBinaryData = new AMFBinaryData();
+            registerClassAlias('TestClass7a', TestClass7a);
+            registerClassAlias('TestClass7b', TestClass7b);
+            var test1:TestClass7a = new TestClass7a();
+            test1.something = 'whatever';
+            ba.writeObject(test1);
+
+            ba.position = 0;
+
+            var retrieved:Object = ba.readObject();
+
+            assertTrue(retrieved is TestClass7a, 'unexpected deserialization');
+
+            var test2:TestClass7b = new TestClass7b();
+            test1.something = 'whatever';
+            ba.length = 0;
+            ba.writeObject(test2);
+
+            ba.position = 0;
+            retrieved = ba.readObject();
+
+            assertTrue(retrieved is TestClass7b, 'unexpected deserialization');
+
+        }
+
+
+        [Test]
+        public function testTransientDeserialized():void{
+            //if a transient field is already serialized, then we do 
deserialize it
+            //this means it can be sent from the server (for example) but is 
not sent to the server
+
+            //to test this we will use TestClass7b (where 'something' is not 
Transient) which will serialize the 'something' field with an alias that matches
+            //a subsequent deserialization to a TestClass7a instance (where 
'something' is Transient);
+            //the expected result will be that the Transient field is still 
deserialized
+
+            var ba:AMFBinaryData = new AMFBinaryData();
+            registerClassAlias('TestClass7a', TestClass7b);
+            var test1:TestClass7b = new TestClass7b();
+            test1.something = 'something interesting';
+            ba.length = 0;
+            //non-transient inbound:
+            ba.writeObject(test1);
+
+            //The bytes for the above can differ between swf and js. 54 vs. 57 
bytes length
+            //It is possible to correct that. But it is the swf output that is 
serializing the 'something' field twice
+            // (second time is string ref for both field and value, so quite 
compact, but still unnecessary)
+            //so not trying to match that exactly, because it is redundant 
data.
+
+            ba.position = 0;
+
+            //read it back as TestClass7a
+            registerClassAlias('TestClass7a', TestClass7a);
+
+            var retrieved:Object = ba.readObject();
+
+
+            assertTrue(retrieved is TestClass7a, 'unexpected deserialization');
+            assertEquals(retrieved.something , 'something interesting', 
'unexpected deserialization');
+            assertEquals(retrieved.test , 'test', 'unexpected 
deserialization');
+
+            //this time round it won't be read out because it is Transient for 
serialization/inbound:
+            ba.position = 0;
+            ba.length=0;
+            ba.writeObject(retrieved);
+            ba.position = 0;
+            retrieved = ba.readObject();
+            assertTrue(retrieved is TestClass7a, 'unexpected deserialization');
+            assertEquals(retrieved.something , null, 'unexpected 
deserialization');
+            assertEquals(retrieved.test , 'test', 'unexpected 
deserialization');
+        }
+
+
+        private function getBytesOut(bytes:AMFBinaryData):String{
+            var out:Array = [];
+            for each(var byte:uint in bytes) {
+                out.push(('0'+byte.toString(16)).substr(-2));
+            }
+            return out.join('');
+        }
         
     }
 }
diff --git 
a/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass6.as
 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass6.as
new file mode 100644
index 0000000..42a1e3c
--- /dev/null
+++ 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass6.as
@@ -0,0 +1,72 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flexUnitTests.network.support
+{
+   
+    import flexUnitTests.network.support.testnamespace;
+    
+    /**
+     * @royalesuppresspublicvarwarning
+     */
+    public class TestClass6
+    {
+        //Note: do not change this test class unless you change the related 
tests to
+        //support any changes that might appear when testing reflection into it
+        
+        public function TestClass6()
+        {
+        
+        }
+        
+        
+        public var myVar:String = 'publicMyVar';
+        
+        testnamespace var myVar:String = 'testnamespaceMyVar';
+        
+        public function myMethod():String{
+            return 'public myMethod';
+        }
+    
+        testnamespace function myMethod():String{
+            return 'testnamespace myMethod';
+        }
+    
+        private var _v:String = 'public accessor';
+        public function get myAccessor():String{
+            return _v;
+        }
+    
+        public function set myAccessor(value:String):void{
+            _v = value;
+        }
+        
+        private var _v2:String = 'testnamespace accessor';
+        testnamespace function get myAccessor():String{
+            return _v2;
+        }
+    
+        testnamespace function set myAccessor(value:String):void{
+            _v2 = value;
+        }
+        
+        
+    }
+    
+    
+}
diff --git 
a/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass7a.as
 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass7a.as
new file mode 100644
index 0000000..db6ec8b
--- /dev/null
+++ 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass7a.as
@@ -0,0 +1,51 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flexUnitTests.network.support
+{
+   
+    import flexUnitTests.network.support.testnamespace;
+    
+    /**
+     * @royalesuppresspublicvarwarning
+     */
+    public class TestClass7a
+    {
+        //Note: do not change this test class unless you change the related 
tests to
+        //support any changes that might appear when testing reflection into it
+        
+        public function TestClass7a()
+        {
+        
+        }
+
+        public var test:String = 'test';
+        
+        protected var _something:String;
+        [Transient]
+        public function get something():String{
+            return _something;
+        }
+        public function set something(value:String):void{
+            _something = value;
+        }
+        
+    }
+    
+    
+}
diff --git 
a/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass7b.as
 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass7b.as
new file mode 100644
index 0000000..39b5f7d
--- /dev/null
+++ 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/TestClass7b.as
@@ -0,0 +1,49 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flexUnitTests.network.support
+{
+   
+    import flexUnitTests.network.support.testnamespace;
+    
+    /**
+     * @royalesuppresspublicvarwarning
+     */
+    public class TestClass7b extends TestClass7a
+    {
+        //Note: do not change this test class unless you change the related 
tests to
+        //support any changes that might appear when testing reflection into it
+        
+        public function TestClass7b()
+        {
+        
+        }
+        
+
+        [Bindable]
+        override public function get something():String{
+            return _something;
+        }
+        override public function set something(value:String):void{
+            _something = value;
+        }
+        
+    }
+    
+    
+}
diff --git 
a/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/testnamespace.as
 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/testnamespace.as
new file mode 100644
index 0000000..3a552b8
--- /dev/null
+++ 
b/frameworks/projects/Network/src/test/royale/flexUnitTests/network/support/testnamespace.as
@@ -0,0 +1,26 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flexUnitTests.network.support
+{
+    
+    
+
+    public namespace testnamespace = 'http://testnamespace.com/network';
+   
+}

Reply via email to