You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2019/06/21 04:41:59 UTC

[royale-asjs] branch develop updated: Fix for XML issue reported by Harbs/Yishay after recent changes. Added test and verified against Chrome/Firefox/IE11/Edge/Opera on windows (and swf)

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


The following commit(s) were added to refs/heads/develop by this push:
     new e172a8b  Fix for XML issue reported by Harbs/Yishay after recent changes. Added test and verified against Chrome/Firefox/IE11/Edge/Opera on windows (and swf)
     new b71e933  Merge branch 'develop' of https://github.com/apache/royale-asjs into develop
e172a8b is described below

commit e172a8b49ee10b8fc73fe830e0ef30669241d038
Author: greg-dove <gr...@gmail.com>
AuthorDate: Fri Jun 21 14:44:02 2019 +1200

    Fix for XML issue reported by Harbs/Yishay after recent changes. Added test and verified against Chrome/Firefox/IE11/Edge/Opera on windows (and swf)
---
 frameworks/projects/XML/src/main/royale/XML.as     |  53 +++++--
 .../language/LanguageTesterIntUint.as              |  23 +++
 .../reflection/ReflectionTesterNativeTypes.as      |   4 +-
 .../flexUnitTests/xml/XMLTesterGeneralTest.as      |  28 ++++
 .../flexUnitTests/xml/XMLTesterStringifyTest.as    | 155 +++++++++++++++++++++
 5 files changed, 248 insertions(+), 15 deletions(-)

diff --git a/frameworks/projects/XML/src/main/royale/XML.as b/frameworks/projects/XML/src/main/royale/XML.as
index f0ae94f..f210031 100644
--- a/frameworks/projects/XML/src/main/royale/XML.as
+++ b/frameworks/projects/XML/src/main/royale/XML.as
@@ -32,6 +32,8 @@ package
 		 * Additionally, it has a namespaceURI. Otherwise the namespaceURI is null.
 		 * the prefix together with the namespaceURI form a QName
 		*/
+		
+
 
 		/**
 		 * Memory optimization.
@@ -59,6 +61,11 @@ package
 			}
 			return qname;
 		}
+		
+		/**
+		 * regex to match the xml declaration
+		 */
+		private static const xmlDecl:RegExp = /^\s*<\?xml[^?]*\?>/im;
 
 		/**
 		 * Method to free up references to shared QName objects.
@@ -456,10 +463,13 @@ package
 					errorNS = "na";
 				}
 			}
+			
+			var decl:String = xmlDecl.exec(xml);
+			if (decl) xml = xml.replace(decl,'');
+			if (ignoreWhitespace) xml = trimXMLWhitespace( xml) ;
 			//various node types not supported directly
-			//maybe it should always wrap (e4x seems to say yes on p34, 'Semantics' of e4x-Ecma-357.pdf)
-			var wrap:Boolean = (xml.indexOf('<?') == 0 && xml.indexOf('<?xml ') != 0) || (xml.indexOf('<![CDATA[') == 0) || (xml.indexOf('<!--') == 0);
-			if (wrap) xml = '<parseRoot>'+xml+'</parseRoot>';
+			//when parsing, always wrap (e4x ref p34, 'Semantics' of e4x-Ecma-357.pdf)
+			xml = '<parseRoot>'+xml+'</parseRoot>';
 			try
 			{
 				var doc:Document = parser.parseFromString(xml, "application/xml");
@@ -473,12 +483,19 @@ package
 			var errorNodes:NodeList = doc.getElementsByTagNameNS(errorNS, 'parsererror');
 			if(errorNodes.length > 0)
 				throw new Error(errorNodes[0].innerHTML);
-			if (wrap) doc = doc.childNodes[0];
-			for(var i:int=0;i<doc.childNodes.length;i++)
+
+			//parseRoot wrapper
+			doc = doc.childNodes[0];
+
+			var childCount:uint = doc.childNodes.length;
+			var errIfNoRoot:String;
+			for(var i:int=0;i<childCount;i++)
 			{
 				var node:Node = doc.childNodes[i];
 				if(node.nodeType == 1)
 				{
+					if (errIfNoRoot) errIfNoRoot = null;
+					if (childCount > 1) this.setNodeKind('element');
 					_version = doc.xmlVersion;
 					_encoding = doc.xmlEncoding;
 					_name = getQName(node.localName,node.prefix,node.namespaceURI,false);
@@ -490,6 +507,7 @@ package
 				}
 				else
 				{
+					
 					if (node.nodeType == 7) {
 						if (XML.ignoreProcessingInstructions) {
 							this.setNodeKind('text');
@@ -497,12 +515,20 @@ package
 							_name = null;
 							this.setValue('');
 						} else {
+							if (childCount > 1) {
+								//as3 XML ignores processing instructions outside the doc root tag
+								errIfNoRoot = 'Error #1088: The markup in the document following the root element must be well-formed.';
+								continue;
+							}
 							this.setNodeKind('processing-instruction');
 							this.setName(node.nodeName);
 							this.setValue(node.nodeValue);
 						}
 						
 					} else if (node.nodeType == 4) {
+						if (childCount > 1) {
+							throw new TypeError('Error #1088: The markup in the document following the root element must be well-formed.');
+						}
 						this.setNodeKind('text');
 						//e4x: The value of the [[Name]] property is null if and only if the XML object represents an XML comment or text node
 						_name = null;
@@ -521,15 +547,17 @@ package
 							this.setNodeKind('comment');
 							this.setValue(node.nodeValue);
 						}
-						
-						
 					}
-
-					// Do we record the nodes which are probably processing instructions?
-//						var child:XML = XML.fromNode(node);
-//						addChild(child);
+					else if (node.nodeType == 3) {
+						if (childCount > 1 && !(XML.ignoreWhitespace && /^\s*$/.test(node.nodeValue))) {
+							throw new TypeError('Error #1088: The markup in the document following the root element must be well-formed.');
+						}
+					}
+					
 				}
 			}
+			
+			if (errIfNoRoot) throw new TypeError(errIfNoRoot);
 			//normalize seems wrong here:
 			//normalize();
 		//need to deal with errors https://bugzilla.mozilla.org/show_bug.cgi?id=45566
@@ -539,12 +567,11 @@ package
 		
 		private var _children:Array;
 		private var _attributes:Array;
-		private var _processingInstructions:Array;
 		private var _parent:XML;
 		private var _value:String;
 		private var _version:String;
 		private var _encoding:String;
-		private var _appliedNamespace:Namespace;
+
 		/**
 		 * Memory optimization: Don't create the array unless needed.
 		 */
diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/language/LanguageTesterIntUint.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/language/LanguageTesterIntUint.as
index 90f99ca..660d3ae 100644
--- a/manualtests/UnitTests/src/main/royale/flexUnitTests/language/LanguageTesterIntUint.as
+++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/language/LanguageTesterIntUint.as
@@ -163,6 +163,29 @@ package flexUnitTests.language
             Assert.assertTrue('Unexpected Number check', untyped === 31.5);
             
         }
+    
+    
+        [Test]
+        [TestVariance(variance="JS", description="Variance in js implementation with @royalesuppressresolveuncertain off, strict equality can fail")]
+        /**
+         * @royalesuppressresolveuncertain c
+         */
+        public function testNoResolveUncertain():void
+        {
+
+            var c:Class = int;
+            var untyped:* = new c(30);
+            var expected:Boolean = isJS ? false : true;
+            Assert.assertEquals('Unexpected int check', untyped === 30, expected);
+            // b does not have suppression, only c does above (via @royalesuppressresolveuncertain c)
+            expected = true;
+            var b:Class = String;
+           // c = String;
+            untyped = new b(30);
+            Assert.assertEquals('Unexpected String check', untyped === '30', expected);
+        
+        }
+        
         
     }
 }
diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/reflection/ReflectionTesterNativeTypes.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/reflection/ReflectionTesterNativeTypes.as
index feae9eb..d37f38f 100644
--- a/manualtests/UnitTests/src/main/royale/flexUnitTests/reflection/ReflectionTesterNativeTypes.as
+++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/reflection/ReflectionTesterNativeTypes.as
@@ -172,7 +172,7 @@ package flexUnitTests.reflection
             
             var def:TypeDefinition = describeType(inst);
 
-                RoyaleUnitTestRunner.consoleOut('def name is '+def.name);
+            //    RoyaleUnitTestRunner.consoleOut('def name is '+def.name);
 
             //This is treated as Number
             Assert.assertEquals("Unexpected type name", def.name, "int");
@@ -211,7 +211,7 @@ package flexUnitTests.reflection
             Assert.assertEquals("Unexpected type name", getQualifiedClassName(Vector.<uint>), "Vector.<uint>");
             Assert.assertEquals("Unexpected type", getDefinitionByName("Vector.<uint>"), Vector.<uint>);
             var def:TypeDefinition = describeType(Vector.<uint>);
-            RoyaleUnitTestRunner.consoleOut(def.toString(true));
+         //   RoyaleUnitTestRunner.consoleOut(def.toString(true));
             Assert.assertEquals("Unexpected type name", def.name, "Vector.<uint>");
             
         }
diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
index 6b2cf8b..3765074 100644
--- a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
+++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as
@@ -811,5 +811,33 @@ package flexUnitTests.xml
             //account for variation in output order of attributes and namespace declarations (from native DOMParser)
             Assert.assertTrue('unexpected complex stringify results',  xmlString == expected || xmlString == alternate);
         }
+        
+        
+        [Test]
+        public function testTopLevelProcessingInstructions():void{
+            var xmlSource:String = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
+                    '<?aid style="50" type="snippet" readerVersion="6.0" featureSet="257" product="14.0(209)" ?>\n' +
+                    '<?aid SnippetType="PageItem"?>';
+    
+            XML.ignoreProcessingInstructions = true;
+            var xml:XML = new XML(xmlSource);
+            
+            
+            Assert.assertTrue('unexpected toSting result', xml.toString() == '');
+            Assert.assertTrue('unexpected toSting result', xml.nodeKind() == 'text');
+           
+    
+            XML.ignoreProcessingInstructions = false;
+            var parseError:Boolean;
+            try {
+                xml = new XML(xmlSource);
+            } catch (e:Error)
+            {
+                //RoyaleUnitTestRunner.consoleOut(e.message);
+                parseError = true;
+            }
+            //RoyaleUnitTestRunner.consoleOut('testTopLevelProcessingInstructions '+xml.nodeKind());
+            Assert.assertTrue('error was expected', parseError)
+        }
     }
 }
diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterStringifyTest.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterStringifyTest.as
index f7a1b1e..269d683 100644
--- a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterStringifyTest.as
+++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterStringifyTest.as
@@ -152,6 +152,161 @@ package flexUnitTests.xml
     
 
         }
+    
+        [Test]
+        public function stringifyAdvanced2():void{
+            XML.ignoreProcessingInstructions = true;
+            var xmlSource:String = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
+                    '<?aid style="50" type="snippet" readerVersion="6.0" featureSet="257" product="14.0(209)" ?>\n' +
+                    '<?aid SnippetType="PageItem"?>\n' +
+                    '<Document LinkedSpreads="undefined" DOMVersion="14.0" Self="d">\n' +
+                    '\t<Color Self="Color/Black" Model="Process" Space="CMYK" ColorValue="0 0 0 100" ColorOverride="Specialblack" AlternateSpace="NoAlternateColor" AlternateColorValue="" Name="Black" ColorEditable="false" ColorRemovable="false" Visible="true" SwatchCreatorID="7937" SwatchColorGroupReference="u223ColorGroupSwatch3" />\n' +
+                    '\t<Swatch Self="Swatch/None" Name="None" ColorEditable="false" ColorRemovable="false" Visible="true" SwatchCreatorID="7937" SwatchColorGroupReference="u223ColorGroupSwatch0" />\n' +
+                    '\t<Str Self="Str/$ID/Solid" Name="$ID/Solid" />\n' +
+                    '\t<RCS Self="u77">\n' +
+                    '\t\t<CharacterStyle Self="CharacterStyle/$ID/[No character style]" Imported="false" Spl="false" EmitCss="true" StyleUniqueId="$ID/" IncludeClass="true" Name="$ID/[No character style]" />\n' +
+                    '\t</RCS>\n' +
+                    '\t<Nu Self="Nu/$ID/[Default]" Name="$ID/[Default]" ContinueNumbersAcrossStories="false" ContinueNumbersAcrossDocuments="false" />\n' +
+                    '\t<RootParagraphStyleGroup Self="u76">\n' +
+                    '\t\t\n' +
+                    '\t\t\n' +
+                    '\t</RootParagraphStyleGroup>\n' +
+                    '\t\n' +
+                    '\t\n' +
+                    '\t\n' +
+                    '\t\n' +
+                    '\t\n' +
+                    '\t<Story Self="u180" UserText="true" IsEndnoteStory="false" AppliedTOCStyle="n" TrackChanges="false" StoryTitle="$ID/" AppliedNamedGrid="n">\n' +
+                    '\t\t<StoryPreference OpticalMarginAlignment="false" OpticalMarginSize="12" FrameType="TextFrameType" StoryOrientation="Horizontal" StoryDirection="LeftToRightDirection" />\n' +
+                    '\t\t<InCopyExportOption IncludeGraphicProxies="true" IncludeAllResources="false" />\n' +
+                    '\t\t<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/NormalParagraphStyle">\n' +
+                    '\t\t\t<CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]" PointSize="20">\n' +
+                    '\t\t\t\t<Content>a</Content>\n' +
+                    '\t\t\t\t<Br />\n' +
+                    '\t\t\t\t<Content>s who work on the tickes.</Content>\n' +
+                    '\t\t\t</CharacterStyleRange>\n' +
+                    '\t\t</ParagraphStyleRange>\n' +
+                    '\t</Story>\n' +
+                    '\t<ColorGroup Self="ColorGroup/[Root Color Group]" Name="[Root Color Group]" IsRootColorGroup="true">\n' +
+                    '\t\t<ColorGroupSwatch Self="u223ColorGroupSwatch0" SwatchItemRef="Swatch/None" />\n' +
+                    '\t\t<ColorGroupSwatch Self="u223ColorGroupSwatch3" SwatchItemRef="Color/Black" />\n' +
+                    '\t</ColorGroup>\n' +
+                    '</Document>';
+            
+            var xml:XML = new XML(xmlSource);
+        
+            
+            var expected:String = '<Document LinkedSpreads="undefined" DOMVersion="14.0" Self="d">\n' +
+                    '  <Color Self="Color/Black" Model="Process" Space="CMYK" ColorValue="0 0 0 100" ColorOverride="Specialblack" AlternateSpace="NoAlternateColor" AlternateColorValue="" Name="Black" ColorEditable="false" ColorRemovable="false" Visible="true" SwatchCreatorID="7937" SwatchColorGroupReference="u223ColorGroupSwatch3"/>\n' +
+                    '  <Swatch Self="Swatch/None" Name="None" ColorEditable="false" ColorRemovable="false" Visible="true" SwatchCreatorID="7937" SwatchColorGroupReference="u223ColorGroupSwatch0"/>\n' +
+                    '  <Str Self="Str/$ID/Solid" Name="$ID/Solid"/>\n' +
+                    '  <RCS Self="u77">\n' +
+                    '    <CharacterStyle Self="CharacterStyle/$ID/[No character style]" Imported="false" Spl="false" EmitCss="true" StyleUniqueId="$ID/" IncludeClass="true" Name="$ID/[No character style]"/>\n' +
+                    '  </RCS>\n' +
+                    '  <Nu Self="Nu/$ID/[Default]" Name="$ID/[Default]" ContinueNumbersAcrossStories="false" ContinueNumbersAcrossDocuments="false"/>\n' +
+                    '  <RootParagraphStyleGroup Self="u76"/>\n' +
+                    '  <Story Self="u180" UserText="true" IsEndnoteStory="false" AppliedTOCStyle="n" TrackChanges="false" StoryTitle="$ID/" AppliedNamedGrid="n">\n' +
+                    '    <StoryPreference OpticalMarginAlignment="false" OpticalMarginSize="12" FrameType="TextFrameType" StoryOrientation="Horizontal" StoryDirection="LeftToRightDirection"/>\n' +
+                    '    <InCopyExportOption IncludeGraphicProxies="true" IncludeAllResources="false"/>\n' +
+                    '    <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/NormalParagraphStyle">\n' +
+                    '      <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]" PointSize="20">\n' +
+                    '        <Content>a</Content>\n' +
+                    '        <Br/>\n' +
+                    '        <Content>s who work on the tickes.</Content>\n' +
+                    '      </CharacterStyleRange>\n' +
+                    '    </ParagraphStyleRange>\n' +
+                    '  </Story>\n' +
+                    '  <ColorGroup Self="ColorGroup/[Root Color Group]" Name="[Root Color Group]" IsRootColorGroup="true">\n' +
+                    '    <ColorGroupSwatch Self="u223ColorGroupSwatch0" SwatchItemRef="Swatch/None"/>\n' +
+                    '    <ColorGroupSwatch Self="u223ColorGroupSwatch3" SwatchItemRef="Color/Black"/>\n' +
+                    '  </ColorGroup>\n' +
+                    '</Document>';
+            
+            var outString:String = xml.toString();
+
+            //RoyaleUnitTestRunner.consoleOut('stringifyAdvanced2:\n' + outString );
+            
+            //the order of toString output can be quite different for some browsers, but the length should be identical
+            Assert.assertTrue('unexpected toString result', outString.length == expected.length);
+        }
+    
+        [Test]
+        public function stringifyAdvanced3():void{
+            //AS3 XML ignores processing instructions outside the root tag, even when it is told not to
+            //This is (I think) because there is no concept of a 'Document' level XML that is different to a regular XML node
+            XML.ignoreProcessingInstructions = false;
+            var xmlSource:String = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
+                    '<?aid style="50" type="snippet" readerVersion="6.0" featureSet="257" product="14.0(209)" ?>\n' +
+                    '<?aid SnippetType="PageItem"?>\n' +
+                    '<Document LinkedSpreads="undefined" DOMVersion="14.0" Self="d">\n' +
+                    '\t<Color Self="Color/Black" Model="Process" Space="CMYK" ColorValue="0 0 0 100" ColorOverride="Specialblack" AlternateSpace="NoAlternateColor" AlternateColorValue="" Name="Black" ColorEditable="false" ColorRemovable="false" Visible="true" SwatchCreatorID="7937" SwatchColorGroupReference="u223ColorGroupSwatch3" />\n' +
+                    '\t<Swatch Self="Swatch/None" Name="None" ColorEditable="false" ColorRemovable="false" Visible="true" SwatchCreatorID="7937" SwatchColorGroupReference="u223ColorGroupSwatch0" />\n' +
+                    '\t<Str Self="Str/$ID/Solid" Name="$ID/Solid" />\n' +
+                    '\t<RCS Self="u77">\n' +
+                    '\t\t<CharacterStyle Self="CharacterStyle/$ID/[No character style]" Imported="false" Spl="false" EmitCss="true" StyleUniqueId="$ID/" IncludeClass="true" Name="$ID/[No character style]" />\n' +
+                    '\t</RCS>\n' +
+                    '\t<Nu Self="Nu/$ID/[Default]" Name="$ID/[Default]" ContinueNumbersAcrossStories="false" ContinueNumbersAcrossDocuments="false" />\n' +
+                    '\t<RootParagraphStyleGroup Self="u76">\n' +
+                    '\t\t\n' +
+                    '\t\t\n' +
+                    '\t</RootParagraphStyleGroup>\n' +
+                    '\t\n' +
+                    '\t\n' +
+                    '\t\n' +
+                    '\t\n' +
+                    '\t\n' +
+                    '\t<Story Self="u180" UserText="true" IsEndnoteStory="false" AppliedTOCStyle="n" TrackChanges="false" StoryTitle="$ID/" AppliedNamedGrid="n">\n' +
+                    '\t\t<StoryPreference OpticalMarginAlignment="false" OpticalMarginSize="12" FrameType="TextFrameType" StoryOrientation="Horizontal" StoryDirection="LeftToRightDirection" />\n' +
+                    '\t\t<InCopyExportOption IncludeGraphicProxies="true" IncludeAllResources="false" />\n' +
+                    '\t\t<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/NormalParagraphStyle">\n' +
+                    '\t\t\t<CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]" PointSize="20">\n' +
+                    '\t\t\t\t<Content>a</Content>\n' +
+                    '\t\t\t\t<Br />\n' +
+                    '\t\t\t\t<Content>s who work on the tickes.</Content>\n' +
+                    '\t\t\t</CharacterStyleRange>\n' +
+                    '\t\t</ParagraphStyleRange>\n' +
+                    '\t</Story>\n' +
+                    '\t<ColorGroup Self="ColorGroup/[Root Color Group]" Name="[Root Color Group]" IsRootColorGroup="true">\n' +
+                    '\t\t<ColorGroupSwatch Self="u223ColorGroupSwatch0" SwatchItemRef="Swatch/None" />\n' +
+                    '\t\t<ColorGroupSwatch Self="u223ColorGroupSwatch3" SwatchItemRef="Color/Black" />\n' +
+                    '\t</ColorGroup>\n' +
+                    '</Document>';
+        
+            var xml:XML = new XML(xmlSource);
+            XML.ignoreProcessingInstructions = true;
+
+            var outString:String = xml.toString();
+            var expected:String = '<Document LinkedSpreads="undefined" DOMVersion="14.0" Self="d">\n' +
+                    '  <Color Self="Color/Black" Model="Process" Space="CMYK" ColorValue="0 0 0 100" ColorOverride="Specialblack" AlternateSpace="NoAlternateColor" AlternateColorValue="" Name="Black" ColorEditable="false" ColorRemovable="false" Visible="true" SwatchCreatorID="7937" SwatchColorGroupReference="u223ColorGroupSwatch3"/>\n' +
+                    '  <Swatch Self="Swatch/None" Name="None" ColorEditable="false" ColorRemovable="false" Visible="true" SwatchCreatorID="7937" SwatchColorGroupReference="u223ColorGroupSwatch0"/>\n' +
+                    '  <Str Self="Str/$ID/Solid" Name="$ID/Solid"/>\n' +
+                    '  <RCS Self="u77">\n' +
+                    '    <CharacterStyle Self="CharacterStyle/$ID/[No character style]" Imported="false" Spl="false" EmitCss="true" StyleUniqueId="$ID/" IncludeClass="true" Name="$ID/[No character style]"/>\n' +
+                    '  </RCS>\n' +
+                    '  <Nu Self="Nu/$ID/[Default]" Name="$ID/[Default]" ContinueNumbersAcrossStories="false" ContinueNumbersAcrossDocuments="false"/>\n' +
+                    '  <RootParagraphStyleGroup Self="u76"/>\n' +
+                    '  <Story Self="u180" UserText="true" IsEndnoteStory="false" AppliedTOCStyle="n" TrackChanges="false" StoryTitle="$ID/" AppliedNamedGrid="n">\n' +
+                    '    <StoryPreference OpticalMarginAlignment="false" OpticalMarginSize="12" FrameType="TextFrameType" StoryOrientation="Horizontal" StoryDirection="LeftToRightDirection"/>\n' +
+                    '    <InCopyExportOption IncludeGraphicProxies="true" IncludeAllResources="false"/>\n' +
+                    '    <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/$ID/NormalParagraphStyle">\n' +
+                    '      <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]" PointSize="20">\n' +
+                    '        <Content>a</Content>\n' +
+                    '        <Br/>\n' +
+                    '        <Content>s who work on the tickes.</Content>\n' +
+                    '      </CharacterStyleRange>\n' +
+                    '    </ParagraphStyleRange>\n' +
+                    '  </Story>\n' +
+                    '  <ColorGroup Self="ColorGroup/[Root Color Group]" Name="[Root Color Group]" IsRootColorGroup="true">\n' +
+                    '    <ColorGroupSwatch Self="u223ColorGroupSwatch0" SwatchItemRef="Swatch/None"/>\n' +
+                    '    <ColorGroupSwatch Self="u223ColorGroupSwatch3" SwatchItemRef="Color/Black"/>\n' +
+                    '  </ColorGroup>\n' +
+                    '</Document>';
+            //RoyaleUnitTestRunner.consoleOut('stringifyAdvanced3:\n' + outString);
+    
+            //the order of toString output can be quite different for some browsers, but the length should be identical
+            Assert.assertTrue('unexpected toString result', outString.length == expected.length);
+        }
+        
         
         [Test]
         public function testCDATA():void{