|
| 1 | +package examples |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "testing" |
| 6 | + |
| 7 | + "github.com/moov-io/signedxml" |
| 8 | + |
| 9 | + . "github.com/smartystreets/goconvey/convey" |
| 10 | +) |
| 11 | + |
| 12 | +var example31Input = `<?xml version="1.0"?> |
| 13 | +
|
| 14 | +<?xml-stylesheet href="doc.xsl" type="text/xsl" ?> |
| 15 | +
|
| 16 | +<!DOCTYPE doc SYSTEM "doc.dtd"> |
| 17 | +
|
| 18 | +<doc>Hello, world!<!-- Comment 1 --></doc> |
| 19 | +
|
| 20 | +<?pi-without-data ?> |
| 21 | +
|
| 22 | +<!-- Comment 2 --> |
| 23 | +
|
| 24 | +<!-- Comment 3 -->` |
| 25 | + |
| 26 | +var example31Output = `<?xml-stylesheet href="doc.xsl" type="text/xsl" ?> |
| 27 | +<doc>Hello, world!</doc> |
| 28 | +<?pi-without-data?>` |
| 29 | + |
| 30 | +var example31OutputWithComments = `<?xml-stylesheet href="doc.xsl" type="text/xsl" ?> |
| 31 | +<doc>Hello, world!<!-- Comment 1 --></doc> |
| 32 | +<?pi-without-data?> |
| 33 | +<!-- Comment 2 --> |
| 34 | +<!-- Comment 3 -->` |
| 35 | + |
| 36 | +var example32Input = `<doc> |
| 37 | + <clean> </clean> |
| 38 | + <dirty> A B </dirty> |
| 39 | + <mixed> |
| 40 | + A |
| 41 | + <clean> </clean> |
| 42 | + B |
| 43 | + <dirty> A B </dirty> |
| 44 | + C |
| 45 | + </mixed> |
| 46 | +</doc>` |
| 47 | + |
| 48 | +var example32Output = `<doc> |
| 49 | + <clean> </clean> |
| 50 | + <dirty> A B </dirty> |
| 51 | + <mixed> |
| 52 | + A |
| 53 | + <clean> </clean> |
| 54 | + B |
| 55 | + <dirty> A B </dirty> |
| 56 | + C |
| 57 | + </mixed> |
| 58 | +</doc>` |
| 59 | + |
| 60 | +var example33Input = `<!DOCTYPE doc [<!ATTLIST e9 attr CDATA "default">]> |
| 61 | +<doc> |
| 62 | + <e1 /> |
| 63 | + <e2 ></e2> |
| 64 | + <e3 name = "elem3" id="elem3" /> |
| 65 | + <e4 name="elem4" id="elem4" ></e4> |
| 66 | + <e5 a:attr="out" b:attr="sorted" attr2="all" attr="I'm" xmlns:b="http://www.ietf.org" xmlns:a="http://www.w3.org" xmlns="http://example.org"/> |
| 67 | + <e6 xmlns="" xmlns:a="http://www.w3.org"> |
| 68 | + <e7 xmlns="http://www.ietf.org"> |
| 69 | + <e8 xmlns="" xmlns:a="http://www.w3.org"> |
| 70 | + <e9 xmlns="" xmlns:a="http://www.ietf.org"/> |
| 71 | + </e8> |
| 72 | + </e7> |
| 73 | + </e6> |
| 74 | +</doc>` |
| 75 | + |
| 76 | +var example33Output = `<doc> |
| 77 | + <e1></e1> |
| 78 | + <e2></e2> |
| 79 | + <e3 id="elem3" name="elem3"></e3> |
| 80 | + <e4 id="elem4" name="elem4"></e4> |
| 81 | + <e5 xmlns="http://example.org" xmlns:a="http://www.w3.org" xmlns:b="http://www.ietf.org" attr="I'm" attr2="all" b:attr="sorted" a:attr="out"></e5> |
| 82 | + <e6 xmlns:a="http://www.w3.org"> |
| 83 | + <e7 xmlns="http://www.ietf.org"> |
| 84 | + <e8 xmlns=""> |
| 85 | + <e9 xmlns:a="http://www.ietf.org" attr="default"></e9> |
| 86 | + </e8> |
| 87 | + </e7> |
| 88 | + </e6> |
| 89 | +</doc>` |
| 90 | + |
| 91 | +var example34Input = `<!DOCTYPE doc [ |
| 92 | +<!ATTLIST normId id ID #IMPLIED> |
| 93 | +<!ATTLIST normNames attr NMTOKENS #IMPLIED> |
| 94 | +]> |
| 95 | +<doc> |
| 96 | + <text>First line
 Second line</text> |
| 97 | + <value>2</value> |
| 98 | + <compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute> |
| 99 | + <compute expr='value>"0" && value<"10" ?"valid":"error"'>valid</compute> |
| 100 | + <norm attr=' '   
	 ' '/> |
| 101 | + <normNames attr=' A   
	 B '/> |
| 102 | +</doc>` |
| 103 | + |
| 104 | +var example34Output = `<doc> |
| 105 | + <text>First line
 |
| 106 | +Second line</text> |
| 107 | + <value>2</value> |
| 108 | + <compute>value>"0" && value<"10" ?"valid":"error"</compute> |
| 109 | + <compute expr="value>"0" && value<"10" ?"valid":"error"">valid</compute> |
| 110 | + <norm attr=" ' 
	 ' "></norm> |
| 111 | + <normNames attr="A 
	 B"></normNames> |
| 112 | +</doc>` |
| 113 | + |
| 114 | +// modified to not include DTD processing. still tests for whitespace treated as |
| 115 | +// CDATA |
| 116 | +var example34ModifiedOutput = `<doc> |
| 117 | + <text>First line
 |
| 118 | +Second line</text> |
| 119 | + <value>2</value> |
| 120 | + <compute>value>"0" && value<"10" ?"valid":"error"</compute> |
| 121 | + <compute expr="value>"0" && value<"10" ?"valid":"error"">valid</compute> |
| 122 | + <norm attr=" ' 
	 ' "></norm> |
| 123 | + <normNames attr=" A 
	 B "></normNames> |
| 124 | +</doc>` |
| 125 | + |
| 126 | +var example35Input = `<!DOCTYPE doc [ |
| 127 | +<!ATTLIST doc attrExtEnt ENTITY #IMPLIED> |
| 128 | +<!ENTITY ent1 "Hello"> |
| 129 | +<!ENTITY ent2 SYSTEM "world.txt"> |
| 130 | +<!ENTITY entExt SYSTEM "earth.gif" NDATA gif> |
| 131 | +<!NOTATION gif SYSTEM "viewgif.exe"> |
| 132 | +]> |
| 133 | +<doc attrExtEnt="entExt"> |
| 134 | + &ent1;, &ent2;! |
| 135 | +</doc> |
| 136 | +
|
| 137 | +<!-- Let world.txt contain "world" (excluding the quotes) -->` |
| 138 | + |
| 139 | +var example35Output = `<doc attrExtEnt="entExt"> |
| 140 | + Hello, world! |
| 141 | +</doc>` |
| 142 | + |
| 143 | +var example36Input = `<?xml version="1.0" encoding="ISO-8859-1"?> |
| 144 | +<doc>©</doc>` |
| 145 | + |
| 146 | +var example36Output = "<doc>\u00A9</doc>" |
| 147 | + |
| 148 | +var example37Input = `<!DOCTYPE doc [ |
| 149 | +<!ATTLIST e2 xml:space (default|preserve) 'preserve'> |
| 150 | +<!ATTLIST e3 id ID #IMPLIED> |
| 151 | +]> |
| 152 | +<doc xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org"> |
| 153 | + <e1> |
| 154 | + <e2 xmlns=""> |
| 155 | + <e3 id="E3"/> |
| 156 | + </e2> |
| 157 | + </e1> |
| 158 | +</doc>` |
| 159 | + |
| 160 | +var example37SubsetExpression = `<!-- Evaluate with declaration xmlns:ietf="http://www.ietf.org" --> |
| 161 | +
|
| 162 | +(//. | //@* | //namespace::*) |
| 163 | +[ |
| 164 | + self::ietf:e1 or (parent::ietf:e1 and not(self::text() or self::e2)) |
| 165 | + or |
| 166 | + count(id("E3")|ancestor-or-self::node()) = count(ancestor-or-self::node()) |
| 167 | +]` |
| 168 | + |
| 169 | +var example37Output = `<e1 xmlns="http://www.ietf.org" xmlns:w3c="http://www.w3.org"><e3 xmlns="" id="E3" xml:space="preserve"></e3></e1>` |
| 170 | + |
| 171 | +type exampleXML struct { |
| 172 | + input string |
| 173 | + output string |
| 174 | + withComments bool |
| 175 | + expression string |
| 176 | +} |
| 177 | + |
| 178 | +// test examples from the spec (www.w3.org/TR/2001/REC-xml-c14n-20010315#Examples) |
| 179 | +func TestCanonicalizationExamples(t *testing.T) { |
| 180 | + Convey("Given XML Input", t, func() { |
| 181 | + cases := map[string]exampleXML{ |
| 182 | + "(Example 3.1 w/o Comments)": {input: example31Input, output: example31Output}, |
| 183 | + "(Example 3.1 w/Comments)": {input: example31Input, output: example31OutputWithComments, withComments: true}, |
| 184 | + "(Example 3.2)": {input: example32Input, output: example32Output}, |
| 185 | + // 3.3 is for Canonical NOT ExclusiveCanonical (one of the exceptions here: http://www.w3.org/TR/xml-exc-c14n/#sec-Specification) |
| 186 | + // "(Example 3.3)": {input: example33Input, output: example33Output}, |
| 187 | + "(Example 3.4)": {input: example34Input, output: example34ModifiedOutput}, |
| 188 | + // "(Example 3.5)": {input: example35Input, output: example35Output}, |
| 189 | + // 3.6 will work, but requires a change to the etree package first: |
| 190 | + // http://stackoverflow.com/questions/6002619/unmarshal-an-iso-8859-1-xml-input-in-go |
| 191 | + // "(Example 3.6)": {input: example36Input, output: example36Output}, |
| 192 | + // "(Example 3.7)": {input: example37Input, output: example37Output, expression: example37SubsetExpression}, |
| 193 | + } |
| 194 | + for description, test := range cases { |
| 195 | + Convey(fmt.Sprintf("When transformed %s", description), func() { |
| 196 | + transform := signedxml.ExclusiveCanonicalization{ |
| 197 | + WithComments: test.withComments, |
| 198 | + } |
| 199 | + resultXML, err := transform.Process(test.input, "") |
| 200 | + Convey("Then the resulting XML match the example output", func() { |
| 201 | + So(err, ShouldBeNil) |
| 202 | + So(resultXML, ShouldEqual, test.output) |
| 203 | + }) |
| 204 | + }) |
| 205 | + } |
| 206 | + }) |
| 207 | +} |
| 208 | + |
| 209 | +func TestTODO(t *testing.T) { |
| 210 | + // The XML specifications cover the following examples, but our library does not successfully transform. |
| 211 | + t.Logf("Input:\n%s\nOutput:\n%s\n", example33Input, example33Output) // Example 3.3 |
| 212 | + t.Logf("Input:\n%s\nOutput:\n%s\n", example35Input, example35Output) // Example 3.5 |
| 213 | + t.Logf("Input:\n%s\nOutput:\n%s\n", example36Input, example36Output) // Example 3.6 |
| 214 | + t.Logf("Input:\n%s\nOutput:\n%s\n", example37Input, example37Output) // Example 3.7 |
| 215 | +} |
0 commit comments