completely different fix for the recursion detection based on entity

* parser.c include/libxml/parser.h: completely different fix for
  the recursion detection based on entity density, big cleanups
  in the entity parsing code too
* result/*.sax*: the parser should not ask for used defined versions
  of the predefined entities
* testrecurse.c: automatic test for entity recursion checks
* Makefile.am: added testrecurse
* test/recurse/lol* test/recurse/good*: a first set of tests for
  the recursion
Daniel

svn path=/trunk/; revision=3783
This commit is contained in:
Daniel Veillard 2008-08-28 15:36:32 +00:00
parent 49d4405a6d
commit 0161e638c6
43 changed files with 2806 additions and 898 deletions

View File

@ -1,3 +1,15 @@
Thu Aug 28 17:31:46 CEST 2008 Daniel Veillard <daniel@veillard.com>
* parser.c include/libxml/parser.h: completely different fix for
the recursion detection based on entity density, big cleanups
in the entity parsing code too
* result/*.sax*: the parser should not ask for used defined versions
of the predefined entities
* testrecurse.c: automatic test for entity recursion checks
* Makefile.am: added testrecurse
* test/recurse/lol* test/recurse/good*: a first set of tests for
the recursion
Wed Aug 27 21:55:34 CEST 2008 Daniel Veillard <daniel@veillard.com>
* include/libxml/xmlerror.h parser.c: a bit of cleanup and

View File

@ -9,7 +9,7 @@ INCLUDES = -I$(top_builddir)/include -I@srcdir@/include @THREAD_CFLAGS@ @Z_CFLAG
noinst_PROGRAMS=testSchemas testRelax testSAX testHTML testXPath testURI \
testThreads testC14N testAutomata testRegexp \
testReader testapi testModule runtest runsuite testchar \
testdict runxmlconf
testdict runxmlconf testrecurse
bin_PROGRAMS = xmllint xmlcatalog
@ -56,6 +56,11 @@ runtest_LDFLAGS =
runtest_DEPENDENCIES = $(DEPS)
runtest_LDADD= @BASE_THREAD_LIBS@ @RDL_LIBS@ $(LDADDS)
testrecurse_SOURCES=testrecurse.c
testrecurse_LDFLAGS =
testrecurse_DEPENDENCIES = $(DEPS)
testrecurse_LDADD= @BASE_THREAD_LIBS@ @RDL_LIBS@ $(LDADDS)
testchar_SOURCES=testchar.c
testchar_LDFLAGS =
testchar_DEPENDENCIES = $(DEPS)

View File

@ -298,6 +298,7 @@ struct _xmlParserCtxt {
xmlError lastError;
xmlParserMode parseMode; /* the parser mode */
unsigned long nbentities; /* number of entities references */
unsigned long sizeentities; /* size of parsed entities */
};
/**

1738
parser.c

File diff suppressed because it is too large Load Diff

View File

@ -29,52 +29,42 @@ SAX.startElement(norm, attr='foobar ')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(norm, attr=' &#38; ')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(norm, attr=' foo&#38;bar ')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(norm, attr=' foobar&#38;')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(norm, attr='&#38;foo bar ')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(norm, attr='foobar &#38;')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(norm, attr=' < ')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(norm, attr=' foo<bar ')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(norm, attr=' foobar<')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(norm, attr='<foo bar ')
SAX.endElement(norm)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(norm, attr='foobar <')
SAX.endElement(norm)
SAX.characters(
@ -107,52 +97,42 @@ SAX.startElement(normId, attr='foobar ')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(normId, attr=' &#38; ')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(normId, attr=' foo&#38;bar ')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(normId, attr=' foobar&#38;')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(normId, attr='&#38;foo bar ')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(normId, attr='foobar &#38;')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(normId, attr=' < ')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(normId, attr=' foo<bar ')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(normId, attr=' foobar<')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(normId, attr='<foo bar ')
SAX.endElement(normId)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElement(normId, attr='foobar <')
SAX.endElement(normId)
SAX.characters(

View File

@ -29,52 +29,42 @@ SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr='foob...', 8)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr=' &#3...', 7)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr=' f...', 17)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr=' fo...', 13)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr='&#38...', 13)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr='foob...', 13)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr=' < ...', 3)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr=' f...', 13)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr=' fo...', 9)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr='<foo...', 9)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(norm, NULL, NULL, 0, 1, 0, attr='foob...', 9)
SAX.endElementNs(norm, NULL, NULL)
SAX.characters(
@ -108,52 +98,42 @@ SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='foob...', 6)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='&#38...', 5)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='foo&...', 11)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='foob...', 11)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='&#38...', 12)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='foob...', 12)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='<...', 1)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='foo<...', 7)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='foob...', 7)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='<foo...', 8)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(
, 3)
SAX.getEntity(lt)
SAX.startElementNs(normId, NULL, NULL, 0, 1, 0, attr='foob...', 8)
SAX.endElementNs(normId, NULL, NULL)
SAX.characters(

View File

@ -6,10 +6,8 @@ SAX.characters(
SAX.startElement(cat:ReferencedOrder)
SAX.characters(
, 7)
SAX.getEntity(gt)
SAX.startElement(cat:SellersOrderID, schemeID='pvalue->ReferencedOrder.SellersOrderID.schemeID', schemeAgencyID='pvalue->ReferencedOrder.SellersOrderID.schemeAgencyID', schemeVersionID='pvalue->ReferencedOrder.SellersOrderID.schemeVersionID', schemeAgencySchemeID='pvalue->ReferencedOrder.SellersOrderID.schemeAgencySchemeID', schemeAgencySchemeAgencyID='pvalue->ReferencedOrder.SellersOrderID.schemeAgencySchemeAgencyID', schemeDataURI='pvalue->ReferencedOrder.SellersOrderID.schemeDataURI', schemeURI='pvalue->ReferencedOrder.SellersOrderID.schemeURI', UID='pvalue->ReferencedOrder.SellersOrderID.UID', UIDRef='pvalue->ReferencedOrder.SellersOrderID.UIDRef', UIDRefs='pvalue->ReferencedOrder.SellersOrderID.UIDRefs0', language='pvalue->ReferencedOrder.SellersOrderID.language')
SAX.characters(pvalue-, 7)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.characters(ReferencedOrder.SellersOrderID, 30)
SAX.endElement(cat:SellersOrderID)

View File

@ -6,10 +6,8 @@ SAX.characters(
SAX.startElementNs(ReferencedOrder, cat, 'urn:oasis:names:tc:ubl:CommonAggregateTypes:1.0:0.70', 0, 0, 0)
SAX.characters(
, 7)
SAX.getEntity(gt)
SAX.startElementNs(SellersOrderID, cat, 'urn:oasis:names:tc:ubl:CommonAggregateTypes:1.0:0.70', 0, 11, 0, schemeID='pval...', 47, schemeAgencyID='pval...', 53, schemeVersionID='pval...', 54, schemeAgencySchemeID='pval...', 59, schemeAgencySchemeAgencyID='pval...', 65, schemeDataURI='pval...', 52, schemeURI='pval...', 48, UID='pval...', 42, UIDRef='pval...', 45, UIDRefs='pval...', 47, language='pval...', 47)
SAX.characters(pvalue-, 7)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.characters(ReferencedOrder.SellersOrderID, 30)
SAX.endElementNs(SellersOrderID, cat, 'urn:oasis:names:tc:ubl:CommonAggregateTypes:1.0:0.70')

View File

@ -3,10 +3,8 @@ SAX.startDocument()
SAX.startElement(ino:response, xmlns:ino='http://namespaces.softwareag.com/tamino/response2', xmlns:xql='http://metalab.unc.edu/xql/', ino:sessionid='556', ino:sessionkey='1590469677')
SAX.startElement(xql:query)
SAX.characters(/bsk:DocPart[@docId=, 20)
SAX.getEntity(apos)
SAX.characters(', 1)
SAX.characters(20040308152601345236, 20)
SAX.getEntity(apos)
SAX.characters(', 1)
SAX.characters( and @docPartNo=1], 18)
SAX.endElement(xql:query)

View File

@ -3,10 +3,8 @@ SAX.startDocument()
SAX.startElementNs(response, ino, 'http://namespaces.softwareag.com/tamino/response2', 2, xmlns:ino='http://namespaces.softwareag.com/tamino/response2', xmlns:xql='http://metalab.unc.edu/xql/', 2, 0, ino:sessionid='556"...', 3, ino:sessionkey='1590...', 10)
SAX.startElementNs(query, xql, 'http://metalab.unc.edu/xql/', 0, 0, 0)
SAX.characters(/bsk:DocPart[@docId=, 20)
SAX.getEntity(apos)
SAX.characters(', 1)
SAX.characters(20040308152601345236, 20)
SAX.getEntity(apos)
SAX.characters(', 1)
SAX.characters( and @docPartNo=1], 18)
SAX.endElementNs(query, xql, 'http://metalab.unc.edu/xql/')

View File

@ -1,6 +1,5 @@
SAX.setDocumentLocator()
SAX.startDocument()
SAX.getEntity(apos)
SAX.startElement(item, title='Icrontic.com - Warning: Breakdancing midget with tourette's syndrome on-board                                                ', url='http://www.icrontic.com/', first_time='985034339', last_time='985034339', visits='1')
SAX.endElement(item)
SAX.endDocument()

View File

@ -1,6 +1,5 @@
SAX.setDocumentLocator()
SAX.startDocument()
SAX.getEntity(apos)
SAX.startElementNs(item, NULL, NULL, 0, 5, 0, title='Icro...', 173, url='http...', 24, first_time='9850...', 9, last_time='9850...', 9, visits='1"/>...', 1)
SAX.endElementNs(item, NULL, NULL)
SAX.endDocument()

View File

@ -7,7 +7,6 @@ SAX.startElement(test)
SAX.pcdata(
<![CDATA[abc], 18)
SAX.characters(], 1)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.pcdata(
, 3)

View File

@ -7,7 +7,6 @@ SAX.startElementNs(test, NULL, NULL, 0, 0, 0)
SAX.pcdata(
<![CDATA[abc], 18)
SAX.characters(], 1)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.pcdata(
, 3)

View File

@ -4,7 +4,6 @@ SAX.internalSubset(EXAMPLE, , example.dtd)
SAX.entityDecl(xml, 1, (null), (null), Extensible Markup Language)
SAX.getEntity(xml)
SAX.externalSubset(EXAMPLE, , example.dtd)
SAX.getEntity(amp)
SAX.getEntity(xml)
SAX.startElement(EXAMPLE, prop1='a&#38;b', prop2='&xml;')
SAX.characters(

View File

@ -4,7 +4,6 @@ SAX.internalSubset(EXAMPLE, , example.dtd)
SAX.entityDecl(xml, 1, (null), (null), Extensible Markup Language)
SAX.getEntity(xml)
SAX.externalSubset(EXAMPLE, , example.dtd)
SAX.getEntity(amp)
SAX.getEntity(xml)
SAX.startElementNs(EXAMPLE, NULL, NULL, 0, 2, 0, prop1='a&#3...', 7, prop2='&xml...', 5)
SAX.characters(

View File

@ -7,10 +7,8 @@ SAX.externalSubset(EXAMPLE, , example.dtd)
SAX.startElement(EXAMPLE)
SAX.characters(
Test of , 11)
SAX.getEntity(amp)
SAX.characters(&, 1)
SAX.characters(amp; behaviour a, 16)
SAX.getEntity(amp)
SAX.characters(&, 1)
SAX.characters(b .
, 4)

View File

@ -7,10 +7,8 @@ SAX.externalSubset(EXAMPLE, , example.dtd)
SAX.startElementNs(EXAMPLE, NULL, NULL, 0, 0, 0)
SAX.characters(
Test of , 11)
SAX.getEntity(amp)
SAX.characters(&, 1)
SAX.characters(amp; behaviour a, 16)
SAX.getEntity(amp)
SAX.characters(&, 1)
SAX.characters(b .
, 4)

View File

@ -18,9 +18,7 @@ SAX.endElement(Content)
SAX.characters(
, 4)
SAX.startElement(Content)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.endElement(Content)
SAX.characters(

View File

@ -18,9 +18,7 @@ SAX.endElementNs(Content, NULL, NULL)
SAX.characters(
, 4)
SAX.startElementNs(Content, NULL, NULL, 0, 0, 0)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.endElementNs(Content, NULL, NULL)
SAX.characters(

View File

@ -20,7 +20,6 @@ SAX.characters(©, 2)
SAX.characters( 1947 , 6)
SAX.characters(É, 2)
SAX.characters(ditions Gallimard. , 19)
SAX.getEntity(amp)
SAX.characters(&, 1)
SAX.characters(rights;, 7)
SAX.endElement(eg)

View File

@ -20,7 +20,6 @@ SAX.characters(©, 2)
SAX.characters( 1947 , 6)
SAX.characters(É, 2)
SAX.characters(ditions Gallimard. , 19)
SAX.getEntity(amp)
SAX.characters(&, 1)
SAX.characters(rights;, 7)
SAX.endElementNs(eg, NULL, NULL)

View File

@ -41,7 +41,6 @@ SAX.characters(
SAX.startElement(USES)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElement(STATEMENT, action='read&#38;write', purp='0', recpnt='0', id='1')
SAX.characters(
, 5)

View File

@ -42,7 +42,6 @@ SAX.characters(
SAX.startElementNs(USES, NULL, NULL, 0, 0, 0)
SAX.characters(
, 3)
SAX.getEntity(amp)
SAX.startElementNs(STATEMENT, NULL, NULL, 0, 4, 0, action='read...', 14, purp='0" r...', 1, recpnt='0" i...', 1, id='1">
...', 1)
SAX.characters(

View File

@ -43,10 +43,8 @@ SAX.characters(
, 5)
SAX.startElement(RPM:Packager)
SAX.characters(Red Hat Software , 17)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters(bugs@redhat.com, 15)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.endElement(RPM:Packager)
SAX.characters(
@ -73,10 +71,8 @@ SAX.characters(
, 5)
SAX.startElement(RPM:Changelog)
SAX.characters(* Sun May 10 1998 Prospector S, 36)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters(bugs@redhat.com, 15)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.characters(
- translations modified for, 42)

View File

@ -43,10 +43,8 @@ SAX.characters(
, 5)
SAX.startElementNs(Packager, RPM, 'http://www.rpm.org/', 0, 0, 0)
SAX.characters(Red Hat Software , 17)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters(bugs@redhat.com, 15)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.endElementNs(Packager, RPM, 'http://www.rpm.org/')
SAX.characters(
@ -73,10 +71,8 @@ SAX.characters(
, 5)
SAX.startElementNs(Changelog, RPM, 'http://www.rpm.org/', 0, 0, 0)
SAX.characters(* Sun May 10 1998 Prospector S, 36)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters(bugs@redhat.com, 15)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.characters(
- translations modified for, 42)

View File

@ -43,16 +43,12 @@ SAX.characters(
, 5)
SAX.startElement(RPM:Packager)
SAX.characters(Till Bubeck , 12)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters(bubeck@delix.de, 15)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.characters(, Ngo Than , 11)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters(than@delix.de, 13)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.endElement(RPM:Packager)
SAX.characters(
@ -75,10 +71,8 @@ Routinen zur Ansteuerung, 57)
SAX.characters(ü, 2)
SAX.characters(gung, die
speziell optimiert s, 57)
SAX.getEntity(apos)
SAX.characters(', 1)
SAX.characters(new curses, 10)
SAX.getEntity(apos)
SAX.characters(', 1)
SAX.characters( (ncurses) Variante und ist de, 51)
SAX.characters(ü, 2)

View File

@ -43,16 +43,12 @@ SAX.characters(
, 5)
SAX.startElementNs(Packager, RPM, 'http://www.rpm.org/', 0, 0, 0)
SAX.characters(Till Bubeck , 12)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters(bubeck@delix.de, 15)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.characters(, Ngo Than , 11)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters(than@delix.de, 13)
SAX.getEntity(gt)
SAX.characters(>, 1)
SAX.endElementNs(Packager, RPM, 'http://www.rpm.org/')
SAX.characters(
@ -75,10 +71,8 @@ Routinen zur Ansteuerung, 57)
SAX.characters(ü, 2)
SAX.characters(gung, die
speziell optimiert s, 57)
SAX.getEntity(apos)
SAX.characters(', 1)
SAX.characters(new curses, 10)
SAX.getEntity(apos)
SAX.characters(', 1)
SAX.characters( (ncurses) Variante und ist de, 51)
SAX.characters(ü, 2)

View File

@ -23,7 +23,6 @@ SAX.characters(
SAX.startElement(script, type='text/javascript')
SAX.characters(
... unescaped script , 24)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters( content ...
, 15)

View File

@ -23,7 +23,6 @@ SAX.characters(
SAX.startElementNs(script, NULL, NULL, 0, 1, 0, type='text...', 15)
SAX.characters(
... unescaped script , 24)
SAX.getEntity(lt)
SAX.characters(<, 1)
SAX.characters( content ...
, 15)

View File

@ -15,7 +15,6 @@ SAX.characters() may be escaped
numerically , 31)
SAX.characters(&, 1)
SAX.characters(#38;) or with a general entity, 34)
SAX.getEntity(amp)
SAX.characters(&, 1)
SAX.characters(amp;)., 6)
SAX.endElement(p)

View File

@ -15,7 +15,6 @@ SAX.characters() may be escaped
numerically , 31)
SAX.characters(&, 1)
SAX.characters(#38;) or with a general entity, 34)
SAX.getEntity(amp)
SAX.characters(&, 1)
SAX.characters(amp;)., 6)
SAX.endElementNs(p, NULL, NULL)

343
test/recurse/good.xml Normal file
View File

@ -0,0 +1,343 @@
<!DOCTYPE foo [
<!ENTITY f "some internal data">
<!ENTITY e "&f;&f;">
<!ENTITY d "&e;&e;">
]>
<foo>&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;</foo>

343
test/recurse/goodattr.xml Normal file
View File

@ -0,0 +1,343 @@
<!DOCTYPE foo [
<!ENTITY f "some internal data rather large taking quite some room">
<!ENTITY e "&f;&f;">
<!ENTITY d "&e;&e;">
]>
<foo bar="&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;
&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;"/>

23
test/recurse/lol1.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<!DOCTYPE billion [
<!ELEMENT billion (#PCDATA)>
<!ENTITY laugh0 "ha">
<!ENTITY laugh1 "&laugh0;&laugh0;">
<!ENTITY laugh2 "&laugh1;&laugh1;">
<!ENTITY laugh3 "&laugh2;&laugh2;">
<!ENTITY laugh4 "&laugh3;&laugh3;">
<!ENTITY laugh5 "&laugh4;&laugh4;">
<!ENTITY laugh6 "&laugh5;&laugh5;">
<!ENTITY laugh7 "&laugh6;&laugh6;">
<!ENTITY laugh8 "&laugh7;&laugh7;">
<!ENTITY laugh9 "&laugh8;&laugh8;">
<!ENTITY laugh10 "&laugh9;&laugh9;">
<!ENTITY laugh11
"&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;">
<!ENTITY laugh12
"&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;">
<!ENTITY laugh13
"&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;">
]>
<billion>&laugh13;</billion>

23
test/recurse/lol2.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<!DOCTYPE billion [
<!ELEMENT billion (#PCDATA)>
<!ENTITY laugh0 "ha">
<!ENTITY laugh1 "&laugh0;&laugh0;">
<!ENTITY laugh2 "&laugh1;&laugh1;">
<!ENTITY laugh3 "&laugh2;&laugh2;">
<!ENTITY laugh4 "&laugh3;&laugh3;">
<!ENTITY laugh5 "&laugh4;&laugh4;">
<!ENTITY laugh6 "&laugh5;&laugh5;">
<!ENTITY laugh7 "&laugh6;&laugh6;">
<!ENTITY laugh8 "&laugh7;&laugh7;">
<!ENTITY laugh9 "&laugh8;&laugh8;">
<!ENTITY laugh10 "&laugh9;&laugh9;">
<!ENTITY laugh11
"&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;&laugh10;">
<!ENTITY laugh12
"&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;&laugh11;">
<!ENTITY laugh13
"&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;&laugh12;">
]>
<billion location="&laugh13;">text</billion>

20
test/recurse/lol3.dtd Normal file
View File

@ -0,0 +1,20 @@
<!ELEMENT billion (#PCDATA)>
<!ENTITY % laugh0 "<!-- Ha ! -->">
<!ENTITY % laugh1 "%laugh0;%laugh0;">
<!ENTITY % laugh2 "%laugh1;%laugh1;">
<!ENTITY % laugh3 "%laugh2;%laugh2;">
<!ENTITY % laugh4 "%laugh3;%laugh3;">
<!ENTITY % laugh5 "%laugh4;%laugh4;">
<!ENTITY % laugh6 "%laugh5;%laugh5;">
<!ENTITY % laugh7 "%laugh6;%laugh6;">
<!ENTITY % laugh8 "%laugh7;%laugh7;">
<!ENTITY % laugh9 "%laugh8;%laugh8;">
<!ENTITY % laugh10 "%laugh9;%laugh9;">
<!ENTITY % laugh11
"%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;%laugh10;">
<!ENTITY % laugh12
"%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;%laugh11;">
<!ENTITY % laugh13
"%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;%laugh12;">
%laugh13;

5
test/recurse/lol3.xml Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<!DOCTYPE billion SYSTEM "lol3.dtd">
<billion></billion>

16
test/recurse/lol4.patch Normal file
View File

@ -0,0 +1,16 @@
Index: parser.c
===================================================================
--- parser.c (revision 3773)
+++ parser.c (working copy)
@@ -2505,6 +2505,11 @@ xmlStringLenDecodeEntities(xmlParserCtxt
c = CUR_SCHAR(str, l);
else
c = 0;
+ if ((nbchars > 500000) &&
+ (ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE)) {
+ xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+ goto int_error;
+ }
}
buffer[nbchars++] = 0;
return(buffer);

36
test/recurse/lol4.xml Normal file

File diff suppressed because one or more lines are too long

51
test/recurse/lol5.xml Normal file
View File

@ -0,0 +1,51 @@
<!DOCTYPE root [
<!ENTITY ha "Ha !">
<!ENTITY ha2 "&ha; &ha;">
<!ENTITY ha3 "&ha2; &ha2;">
<!ENTITY ha4 "&ha3; &ha3;">
<!ENTITY ha5 "&ha4; &ha4;">
<!ENTITY ha6 "&ha5; &ha5;">
<!ENTITY ha7 "&ha6; &ha6;">
<!ENTITY ha8 "&ha7; &ha7;">
<!ENTITY ha9 "&ha8; &ha8;">
<!ENTITY ha10 "&ha9; &ha9;">
<!ENTITY ha11 "&ha10; &ha10;">
<!ENTITY ha12 "&ha11; &ha11;">
<!ENTITY ha13 "&ha12; &ha12;">
<!ENTITY ha14 "&ha13; &ha13;">
<!ENTITY ha15 "&ha14; &ha14;">
<!ENTITY ha16 "&ha15; &ha15;">
<!ENTITY ha17 "&ha16; &ha16;">
<!ENTITY ha18 "&ha17; &ha17;">
<!ENTITY ha19 "&ha18; &ha18;">
<!ENTITY ha20 "&ha19; &ha19;">
<!ENTITY ha21 "&ha20; &ha20;">
<!ENTITY ha22 "&ha21; &ha21;">
<!ENTITY ha23 "&ha22; &ha22;">
<!ENTITY ha24 "&ha23; &ha23;">
<!ENTITY ha25 "&ha24; &ha24;">
<!ENTITY ha26 "&ha25; &ha25;">
<!ENTITY ha27 "&ha26; &ha26;">
<!ENTITY ha28 "&ha27; &ha27;">
<!ENTITY ha29 "&ha28; &ha28;">
<!ENTITY ha30 "&ha29; &ha29;">
<!ENTITY ha31 "&ha30; &ha30;">
<!ENTITY ha32 "&ha31; &ha31;">
<!ENTITY ha33 "&ha32; &ha32;">
<!ENTITY ha34 "&ha33; &ha33;">
<!ENTITY ha35 "&ha34; &ha34;">
<!ENTITY ha36 "&ha35; &ha35;">
<!ENTITY ha37 "&ha36; &ha36;">
<!ENTITY ha38 "&ha37; &ha37;">
<!ENTITY ha39 "&ha38; &ha38;">
<!ENTITY ha40 "&ha39; &ha39;">
<!ENTITY ha41 "&ha40; &ha40;">
<!ENTITY ha42 "&ha41; &ha41;">
<!ENTITY ha43 "&ha42; &ha42;">
<!ENTITY ha44 "&ha43; &ha43;">
<!ENTITY ha45 "&ha44; &ha44;">
<!ENTITY ha46 "&ha45; &ha45;">
<!ENTITY ha47 "&ha46; &ha46;">
<!ENTITY ha48 "&ha47; &ha47;">
]>
<root>&ha48;</root>

23
test/recurse/lol6.xml Normal file

File diff suppressed because one or more lines are too long

973
testrecurse.c Normal file
View File

@ -0,0 +1,973 @@
/*
* testrecurse.c: C program to run libxml2 regression tests checking entities
* recursions
*
* To compile on Unixes:
* cc -o testrecurse `xml2-config --cflags` testrecurse.c `xml2-config --libs` -lpthread
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#ifdef HAVE_CONFIG_H
#include "libxml.h"
#else
#include <stdio.h>
#endif
#if !defined(_WIN32) || defined(__CYGWIN__)
#include <unistd.h>
#endif
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/uri.h>
#ifdef LIBXML_READER_ENABLED
#include <libxml/xmlreader.h>
#endif
/*
* O_BINARY is just for Windows compatibility - if it isn't defined
* on this system, avoid any compilation error
*/
#ifdef O_BINARY
#define RD_FLAGS O_RDONLY | O_BINARY
#else
#define RD_FLAGS O_RDONLY
#endif
typedef int (*functest) (const char *filename, const char *result,
const char *error, int options);
typedef struct testDesc testDesc;
typedef testDesc *testDescPtr;
struct testDesc {
const char *desc; /* descripton of the test */
functest func; /* function implementing the test */
const char *in; /* glob to path for input files */
const char *out; /* output directory */
const char *suffix;/* suffix for output files */
const char *err; /* suffix for error output files */
int options; /* parser options for the test */
};
static int checkTestFile(const char *filename);
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#include <io.h>
typedef struct
{
size_t gl_pathc; /* Count of paths matched so far */
char **gl_pathv; /* List of matched pathnames. */
size_t gl_offs; /* Slots to reserve in 'gl_pathv'. */
} glob_t;
#define GLOB_DOOFFS 0
static int glob(const char *pattern, int flags,
int errfunc(const char *epath, int eerrno),
glob_t *pglob) {
glob_t *ret;
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
unsigned int nb_paths = 0;
char directory[500];
int len;
if ((pattern == NULL) || (pglob == NULL)) return(-1);
strncpy(directory, pattern, 499);
for (len = strlen(directory);len >= 0;len--) {
if (directory[len] == '/') {
len++;
directory[len] = 0;
break;
}
}
if (len <= 0)
len = 0;
ret = pglob;
memset(ret, 0, sizeof(glob_t));
hFind = FindFirstFileA(pattern, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
return(0);
nb_paths = 20;
ret->gl_pathv = (char **) malloc(nb_paths * sizeof(char *));
if (ret->gl_pathv == NULL) {
FindClose(hFind);
return(-1);
}
strncpy(directory + len, FindFileData.cFileName, 499 - len);
ret->gl_pathv[ret->gl_pathc] = strdup(directory);
if (ret->gl_pathv[ret->gl_pathc] == NULL)
goto done;
ret->gl_pathc++;
while(FindNextFileA(hFind, &FindFileData)) {
if (FindFileData.cFileName[0] == '.')
continue;
if (ret->gl_pathc + 2 > nb_paths) {
char **tmp = realloc(ret->gl_pathv, nb_paths * 2 * sizeof(char *));
if (tmp == NULL)
break;
ret->gl_pathv = tmp;
nb_paths *= 2;
}
strncpy(directory + len, FindFileData.cFileName, 499 - len);
ret->gl_pathv[ret->gl_pathc] = strdup(directory);
if (ret->gl_pathv[ret->gl_pathc] == NULL)
break;
ret->gl_pathc++;
}
ret->gl_pathv[ret->gl_pathc] = NULL;
done:
FindClose(hFind);
return(0);
}
static void globfree(glob_t *pglob) {
unsigned int i;
if (pglob == NULL)
return;
for (i = 0;i < pglob->gl_pathc;i++) {
if (pglob->gl_pathv[i] != NULL)
free(pglob->gl_pathv[i]);
}
}
#define vsnprintf _vsnprintf
#define snprintf _snprintf
#else
#include <glob.h>
#endif
/************************************************************************
* *
* Huge document generator *
* *
************************************************************************/
#include <libxml/xmlIO.h>
static const char *start = "<!DOCTYPE foo [\
<!ENTITY f 'some internal data'> \
<!ENTITY e '&f;&f;'> \
<!ENTITY d '&e;&e;'> \
]> \
<foo>";
static const char *segment = " <bar>&e; &f; &d;</bar>\n";
static const char *finish = "</foo>";
static int curseg = 0;
static const char *current;
static int rlen;
/**
* hugeMatch:
* @URI: an URI to test
*
* Check for an huge: query
*
* Returns 1 if yes and 0 if another Input module should be used
*/
static int
hugeMatch(const char * URI) {
if ((URI != NULL) && (!strncmp(URI, "huge:", 4)))
return(1);
return(0);
}
/**
* hugeOpen:
* @URI: an URI to test
*
* Return a pointer to the huge: query handler, in this example simply
* the current pointer...
*
* Returns an Input context or NULL in case or error
*/
static void *
hugeOpen(const char * URI) {
if ((URI == NULL) || (strncmp(URI, "huge:", 4)))
return(NULL);
rlen = strlen(start);
current = start;
return((void *) current);
}
/**
* hugeClose:
* @context: the read context
*
* Close the huge: query handler
*
* Returns 0 or -1 in case of error
*/
static int
hugeClose(void * context) {
if (context == NULL) return(-1);
return(0);
}
#define MAX_NODES 1000000
/**
* hugeRead:
* @context: the read context
* @buffer: where to store data
* @len: number of bytes to read
*
* Implement an huge: query read.
*
* Returns the number of bytes read or -1 in case of error
*/
static int
hugeRead(void *context, char *buffer, int len)
{
if ((context == NULL) || (buffer == NULL) || (len < 0))
return (-1);
if (len >= rlen) {
if (curseg >= MAX_NODES + 1) {
rlen = 0;
return(0);
}
len = rlen;
rlen = 0;
memcpy(buffer, current, len);
curseg ++;
if (curseg == MAX_NODES) {
fprintf(stderr, "\n");
rlen = strlen(finish);
current = finish;
} else {
if (curseg % (MAX_NODES / 10) == 0)
fprintf(stderr, ".");
rlen = strlen(segment);
current = segment;
}
} else {
memcpy(buffer, current, len);
rlen -= len;
current += len;
}
return (len);
}
/************************************************************************
* *
* Libxml2 specific routines *
* *
************************************************************************/
static int nb_tests = 0;
static int nb_errors = 0;
static int nb_leaks = 0;
static int extraMemoryFromResolver = 0;
static int
fatalError(void) {
fprintf(stderr, "Exitting tests on fatal error\n");
exit(1);
}
/*
* We need to trap calls to the resolver to not account memory for the catalog
* which is shared to the current running test. We also don't want to have
* network downloads modifying tests.
*/
static xmlParserInputPtr
testExternalEntityLoader(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlParserInputPtr ret;
if (checkTestFile(URL)) {
ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
} else {
int memused = xmlMemUsed();
ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
extraMemoryFromResolver += xmlMemUsed() - memused;
}
return(ret);
}
/*
* Trapping the error messages at the generic level to grab the equivalent of
* stderr messages on CLI tools.
*/
static char testErrors[32769];
static int testErrorsSize = 0;
static void XMLCDECL
channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
va_list args;
int res;
if (testErrorsSize >= 32768)
return;
va_start(args, msg);
res = vsnprintf(&testErrors[testErrorsSize],
32768 - testErrorsSize,
msg, args);
va_end(args);
if (testErrorsSize + res >= 32768) {
/* buffer is full */
testErrorsSize = 32768;
testErrors[testErrorsSize] = 0;
} else {
testErrorsSize += res;
}
testErrors[testErrorsSize] = 0;
}
/**
* xmlParserPrintFileContext:
* @input: an xmlParserInputPtr input
*
* Displays current context within the input content for error tracking
*/
static void
xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
xmlGenericErrorFunc chanl, void *data ) {
const xmlChar *cur, *base;
unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
xmlChar content[81]; /* space for 80 chars + line terminator */
xmlChar *ctnt;
if (input == NULL) return;
cur = input->cur;
base = input->base;
/* skip backwards over any end-of-lines */
while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
cur--;
}
n = 0;
/* search backwards for beginning-of-line (to max buff size) */
while ((n++ < (sizeof(content)-1)) && (cur > base) &&
(*(cur) != '\n') && (*(cur) != '\r'))
cur--;
if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
/* calculate the error position in terms of the current position */
col = input->cur - cur;
/* search forward for end-of-line (to max buff size) */
n = 0;
ctnt = content;
/* copy selected text to our buffer */
while ((*cur != 0) && (*(cur) != '\n') &&
(*(cur) != '\r') && (n < sizeof(content)-1)) {
*ctnt++ = *cur++;
n++;
}
*ctnt = 0;
/* print out the selected text */
chanl(data ,"%s\n", content);
/* create blank line with problem pointer */
n = 0;
ctnt = content;
/* (leave buffer space for pointer + line terminator) */
while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) {
if (*(ctnt) != '\t')
*(ctnt) = ' ';
ctnt++;
}
*ctnt++ = '^';
*ctnt = 0;
chanl(data ,"%s\n", content);
}
static void
testStructuredErrorHandler(void *ctx ATTRIBUTE_UNUSED, xmlErrorPtr err) {
char *file = NULL;
int line = 0;
int code = -1;
int domain;
void *data = NULL;
const char *str;
const xmlChar *name = NULL;
xmlNodePtr node;
xmlErrorLevel level;
xmlParserInputPtr input = NULL;
xmlParserInputPtr cur = NULL;
xmlParserCtxtPtr ctxt = NULL;
if (err == NULL)
return;
file = err->file;
line = err->line;
code = err->code;
domain = err->domain;
level = err->level;
node = err->node;
if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
(domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
ctxt = err->ctxt;
}
str = err->message;
if (code == XML_ERR_OK)
return;
if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
name = node->name;
/*
* Maintain the compatibility with the legacy error handling
*/
if (ctxt != NULL) {
input = ctxt->input;
if ((input != NULL) && (input->filename == NULL) &&
(ctxt->inputNr > 1)) {
cur = input;
input = ctxt->inputTab[ctxt->inputNr - 2];
}
if (input != NULL) {
if (input->filename)
channel(data, "%s:%d: ", input->filename, input->line);
else if ((line != 0) && (domain == XML_FROM_PARSER))
channel(data, "Entity: line %d: ", input->line);
}
} else {
if (file != NULL)
channel(data, "%s:%d: ", file, line);
else if ((line != 0) && (domain == XML_FROM_PARSER))
channel(data, "Entity: line %d: ", line);
}
if (name != NULL) {
channel(data, "element %s: ", name);
}
if (code == XML_ERR_OK)
return;
switch (domain) {
case XML_FROM_PARSER:
channel(data, "parser ");
break;
case XML_FROM_NAMESPACE:
channel(data, "namespace ");
break;
case XML_FROM_DTD:
case XML_FROM_VALID:
channel(data, "validity ");
break;
case XML_FROM_HTML:
channel(data, "HTML parser ");
break;
case XML_FROM_MEMORY:
channel(data, "memory ");
break;
case XML_FROM_OUTPUT:
channel(data, "output ");
break;
case XML_FROM_IO:
channel(data, "I/O ");
break;
case XML_FROM_XINCLUDE:
channel(data, "XInclude ");
break;
case XML_FROM_XPATH:
channel(data, "XPath ");
break;
case XML_FROM_XPOINTER:
channel(data, "parser ");
break;
case XML_FROM_REGEXP:
channel(data, "regexp ");
break;
case XML_FROM_MODULE:
channel(data, "module ");
break;
case XML_FROM_SCHEMASV:
channel(data, "Schemas validity ");
break;
case XML_FROM_SCHEMASP:
channel(data, "Schemas parser ");
break;
case XML_FROM_RELAXNGP:
channel(data, "Relax-NG parser ");
break;
case XML_FROM_RELAXNGV:
channel(data, "Relax-NG validity ");
break;
case XML_FROM_CATALOG:
channel(data, "Catalog ");
break;
case XML_FROM_C14N:
channel(data, "C14N ");
break;
case XML_FROM_XSLT:
channel(data, "XSLT ");
break;
default:
break;
}
if (code == XML_ERR_OK)
return;
switch (level) {
case XML_ERR_NONE:
channel(data, ": ");
break;
case XML_ERR_WARNING:
channel(data, "warning : ");
break;
case XML_ERR_ERROR:
channel(data, "error : ");
break;
case XML_ERR_FATAL:
channel(data, "error : ");
break;
}
if (code == XML_ERR_OK)
return;
if (str != NULL) {
int len;
len = xmlStrlen((const xmlChar *)str);
if ((len > 0) && (str[len - 1] != '\n'))
channel(data, "%s\n", str);
else
channel(data, "%s", str);
} else {
channel(data, "%s\n", "out of memory error");
}
if (code == XML_ERR_OK)
return;
if (ctxt != NULL) {
xmlParserPrintFileContextInternal(input, channel, data);
if (cur != NULL) {
if (cur->filename)
channel(data, "%s:%d: \n", cur->filename, cur->line);
else if ((line != 0) && (domain == XML_FROM_PARSER))
channel(data, "Entity: line %d: \n", cur->line);
xmlParserPrintFileContextInternal(cur, channel, data);
}
}
if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
(err->int1 < 100) &&
(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
xmlChar buf[150];
int i;
channel(data, "%s\n", err->str1);
for (i=0;i < err->int1;i++)
buf[i] = ' ';
buf[i++] = '^';
buf[i] = 0;
channel(data, "%s\n", buf);
}
}
static void
initializeLibxml2(void) {
xmlGetWarningsDefaultValue = 0;
xmlPedanticParserDefault(0);
xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
xmlInitParser();
xmlSetExternalEntityLoader(testExternalEntityLoader);
xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
/*
* register the new I/O handlers
*/
if (xmlRegisterInputCallbacks(hugeMatch, hugeOpen,
hugeRead, hugeClose) < 0) {
fprintf(stderr, "failed to register Huge handler\n");
exit(1);
}
}
/************************************************************************
* *
* File name and path utilities *
* *
************************************************************************/
static const char *baseFilename(const char *filename) {
const char *cur;
if (filename == NULL)
return(NULL);
cur = &filename[strlen(filename)];
while ((cur > filename) && (*cur != '/'))
cur--;
if (*cur == '/')
return(cur + 1);
return(cur);
}
static char *resultFilename(const char *filename, const char *out,
const char *suffix) {
const char *base;
char res[500];
char suffixbuff[500];
/*************
if ((filename[0] == 't') && (filename[1] == 'e') &&
(filename[2] == 's') && (filename[3] == 't') &&
(filename[4] == '/'))
filename = &filename[5];
*************/
base = baseFilename(filename);
if (suffix == NULL)
suffix = ".tmp";
if (out == NULL)
out = "";
strncpy(suffixbuff,suffix,499);
#ifdef VMS
if(strstr(base,".") && suffixbuff[0]=='.')
suffixbuff[0]='_';
#endif
snprintf(res, 499, "%s%s%s", out, base, suffixbuff);
res[499] = 0;
return(strdup(res));
}
static int checkTestFile(const char *filename) {
struct stat buf;
if (stat(filename, &buf) == -1)
return(0);
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!(buf.st_mode & _S_IFREG))
return(0);
#else
if (!S_ISREG(buf.st_mode))
return(0);
#endif
return(1);
}
/************************************************************************
* *
* Test to detect or not recursive entities *
* *
************************************************************************/
/**
* recursiveDetectTest:
* @filename: the file to parse
* @result: the file with expected result
* @err: the file with error messages: unused
*
* Parse a file loading DTD and replacing entities check it fails for
* lol cases
*
* Returns 0 in case of success, an error code otherwise
*/
static int
recursiveDetectTest(const char *filename,
const char *result ATTRIBUTE_UNUSED,
const char *err ATTRIBUTE_UNUSED,
int options ATTRIBUTE_UNUSED) {
xmlDocPtr doc;
xmlParserCtxtPtr ctxt;
int res = 0;
int mem;
nb_tests++;
ctxt = xmlNewParserCtxt();
mem = xmlMemUsed();
/*
* base of the test, parse with the old API
*/
doc = xmlCtxtReadFile(ctxt, filename, NULL,
XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
if ((doc != NULL) || (ctxt->lastError.code != XML_ERR_ENTITY_LOOP)) {
fprintf(stderr, "Failed to detect recursion in %s\n", filename);
xmlFreeParserCtxt(ctxt);
xmlFreeDoc(doc);
return(1);
}
xmlFreeParserCtxt(ctxt);
return(res);
}
/**
* notRecursiveDetectTest:
* @filename: the file to parse
* @result: the file with expected result
* @err: the file with error messages: unused
*
* Parse a file loading DTD and replacing entities check it works for
* good cases
*
* Returns 0 in case of success, an error code otherwise
*/
static int
notRecursiveDetectTest(const char *filename,
const char *result ATTRIBUTE_UNUSED,
const char *err ATTRIBUTE_UNUSED,
int options ATTRIBUTE_UNUSED) {
xmlDocPtr doc;
xmlParserCtxtPtr ctxt;
int res = 0;
int mem;
nb_tests++;
ctxt = xmlNewParserCtxt();
mem = xmlMemUsed();
/*
* base of the test, parse with the old API
*/
doc = xmlCtxtReadFile(ctxt, filename, NULL,
XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
if (doc == NULL) {
fprintf(stderr, "Failed to parse correct file %s\n", filename);
xmlFreeParserCtxt(ctxt);
return(1);
}
xmlFreeDoc(doc);
xmlFreeParserCtxt(ctxt);
return(res);
}
#ifdef LIBXML_READER_ENABLED
/**
* notRecursiveHugeTest:
* @filename: the file to parse
* @result: the file with expected result
* @err: the file with error messages: unused
*
* Parse a memory generated file
* good cases
*
* Returns 0 in case of success, an error code otherwise
*/
static int
notRecursiveHugeTest(const char *filename ATTRIBUTE_UNUSED,
const char *result ATTRIBUTE_UNUSED,
const char *err ATTRIBUTE_UNUSED,
int options ATTRIBUTE_UNUSED) {
xmlTextReaderPtr reader;
int res = 0;
int ret;
nb_tests++;
reader = xmlReaderForFile("huge:test" , NULL,
XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
if (reader == NULL) {
fprintf(stderr, "Failed to open huge:test\n");
return(1);
}
ret = xmlTextReaderRead(reader);
while (ret == 1) {
ret = xmlTextReaderRead(reader);
}
if (ret != 0) {
fprintf(stderr, "Failed to parser huge:test with entities\n");
res = 1;
}
xmlFreeTextReader(reader);
return(res);
}
#endif
/************************************************************************
* *
* Tests Descriptions *
* *
************************************************************************/
static
testDesc testDescriptions[] = {
{ "Parsing recursive test cases" ,
recursiveDetectTest, "./test/recurse/lol*.xml", NULL, NULL, NULL,
0 },
{ "Parsing non-recursive test cases" ,
notRecursiveDetectTest, "./test/recurse/good*.xml", NULL, NULL, NULL,
0 },
#ifdef LIBXML_READER_ENABLED
{ "Parsing non-recursive huge case" ,
notRecursiveHugeTest, NULL, NULL, NULL, NULL,
0 },
#endif
{NULL, NULL, NULL, NULL, NULL, NULL, 0}
};
/************************************************************************
* *
* The main code driving the tests *
* *
************************************************************************/
static int
launchTests(testDescPtr tst) {
int res = 0, err = 0;
size_t i;
char *result;
char *error;
int mem;
if (tst == NULL) return(-1);
if (tst->in != NULL) {
glob_t globbuf;
globbuf.gl_offs = 0;
glob(tst->in, GLOB_DOOFFS, NULL, &globbuf);
for (i = 0;i < globbuf.gl_pathc;i++) {
if (!checkTestFile(globbuf.gl_pathv[i]))
continue;
if (tst->suffix != NULL) {
result = resultFilename(globbuf.gl_pathv[i], tst->out,
tst->suffix);
if (result == NULL) {
fprintf(stderr, "Out of memory !\n");
fatalError();
}
} else {
result = NULL;
}
if (tst->err != NULL) {
error = resultFilename(globbuf.gl_pathv[i], tst->out,
tst->err);
if (error == NULL) {
fprintf(stderr, "Out of memory !\n");
fatalError();
}
} else {
error = NULL;
}
if ((result) &&(!checkTestFile(result))) {
fprintf(stderr, "Missing result file %s\n", result);
} else if ((error) &&(!checkTestFile(error))) {
fprintf(stderr, "Missing error file %s\n", error);
} else {
mem = xmlMemUsed();
extraMemoryFromResolver = 0;
testErrorsSize = 0;
testErrors[0] = 0;
res = tst->func(globbuf.gl_pathv[i], result, error,
tst->options | XML_PARSE_COMPACT);
xmlResetLastError();
if (res != 0) {
fprintf(stderr, "File %s generated an error\n",
globbuf.gl_pathv[i]);
nb_errors++;
err++;
}
else if (xmlMemUsed() != mem) {
if ((xmlMemUsed() != mem) &&
(extraMemoryFromResolver == 0)) {
fprintf(stderr, "File %s leaked %d bytes\n",
globbuf.gl_pathv[i], xmlMemUsed() - mem);
nb_leaks++;
err++;
}
}
testErrorsSize = 0;
}
if (result)
free(result);
if (error)
free(error);
}
globfree(&globbuf);
} else {
testErrorsSize = 0;
testErrors[0] = 0;
extraMemoryFromResolver = 0;
res = tst->func(NULL, NULL, NULL, tst->options);
if (res != 0) {
nb_errors++;
err++;
}
}
return(err);
}
static int verbose = 0;
static int tests_quiet = 0;
static int
runtest(int i) {
int ret = 0, res;
int old_errors, old_tests, old_leaks;
old_errors = nb_errors;
old_tests = nb_tests;
old_leaks = nb_leaks;
if ((tests_quiet == 0) && (testDescriptions[i].desc != NULL))
printf("## %s\n", testDescriptions[i].desc);
res = launchTests(&testDescriptions[i]);
if (res != 0)
ret++;
if (verbose) {
if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
printf("Ran %d tests, no errors\n", nb_tests - old_tests);
else
printf("Ran %d tests, %d errors, %d leaks\n",
nb_tests - old_tests,
nb_errors - old_errors,
nb_leaks - old_leaks);
}
return(ret);
}
int
main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
int i, a, ret = 0;
int subset = 0;
initializeLibxml2();
for (a = 1; a < argc;a++) {
if (!strcmp(argv[a], "-v"))
verbose = 1;
else if (!strcmp(argv[a], "-quiet"))
tests_quiet = 1;
else {
for (i = 0; testDescriptions[i].func != NULL; i++) {
if (strstr(testDescriptions[i].desc, argv[a])) {
ret += runtest(i);
subset++;
}
}
}
}
if (subset == 0) {
for (i = 0; testDescriptions[i].func != NULL; i++) {
ret += runtest(i);
}
}
if ((nb_errors == 0) && (nb_leaks == 0)) {
ret = 0;
printf("Total %d tests, no errors\n",
nb_tests);
} else {
ret = 1;
printf("Total %d tests, %d errors, %d leaks\n",
nb_tests, nb_errors, nb_leaks);
}
xmlCleanupParser();
xmlMemoryDump();
return(ret);
}