1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 /*
21 * XSEC
22 *
23 * XSECNameSpaceExander := Class for expanding out a document's name space axis
24 * and then shrinking again
25 *
26 * $Id: XSECNameSpaceExpander.cpp 1833341 2018-06-11 16:25:41Z scantor $
27 *
28 */
29
30 // XSEC Includes
31 #include <xsec/utils/XSECNameSpaceExpander.hpp>
32 #include <xsec/dsig/DSIGConstants.hpp>
33 #include <xsec/framework/XSECError.hpp>
34
35 #include "XSECDOMUtils.hpp"
36
37 XERCES_CPP_NAMESPACE_USE
38
XSECNameSpaceExpander(DOMDocument * d)39 XSECNameSpaceExpander::XSECNameSpaceExpander(DOMDocument *d) {
40
41 mp_doc = d;
42 mp_fragment = d->getDocumentElement();
43 XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes,
44 XMLFormatter::UnRep_CharRef));
45
46 m_expanded = false;
47
48 }
49
XSECNameSpaceExpander(DOMElement * f)50 XSECNameSpaceExpander::XSECNameSpaceExpander(DOMElement *f) {
51
52 mp_doc = NULL;
53 mp_fragment = f;
54 XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes,
55 XMLFormatter::UnRep_CharRef));
56
57 m_expanded = false;
58
59 }
60
~XSECNameSpaceExpander()61 XSECNameSpaceExpander::~XSECNameSpaceExpander() {
62
63 if (mp_formatter != NULL)
64 delete mp_formatter;
65
66 }
67
recurse(DOMElement * n)68 void XSECNameSpaceExpander::recurse(DOMElement *n) {
69
70 // Recursively go down the tree adding namespaces
71
72 DOMNode *p = n->getParentNode();
73 if (p->getNodeType() != DOMNode::ELEMENT_NODE)
74 return;
75
76 DOMNamedNodeMap *pmap = p->getAttributes();
77 XMLSize_t psize = pmap->getLength();
78
79 DOMNamedNodeMap *nmap = n->getAttributes();
80
81 safeBuffer pname, pURI, nURI;
82 DOMNode *finder;
83
84 XSECNameSpaceEntry * tmpEnt;
85
86 for (XMLSize_t i = 0; i < psize; i++) {
87
88 // Run through each parent node to find namespaces
89 pname << (*mp_formatter << pmap->item(i)->getNodeName());
90
91 // See if this is an xmlns node
92
93 if (pname.sbStrncmp("xmlns", 5) == 0) {
94
95 // It is - see if it already exists
96 finder = nmap->getNamedItem(pname.sbStrToXMLCh());
97 if (finder == 0) {
98
99 // Need to add
100 n->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS,
101 pmap->item(i)->getNodeName(),
102 pmap->item(i)->getNodeValue());
103
104 // Add it to the list so it can be removed later
105 XSECnew(tmpEnt, XSECNameSpaceEntry);
106 tmpEnt->m_name.sbStrcpyIn(pname);
107 tmpEnt->mp_node = n;
108 tmpEnt->mp_att = nmap->getNamedItem(pname.sbStrToXMLCh());
109 m_lst.push_back(tmpEnt);
110
111 }
112
113 }
114
115 }
116
117 // Do the children
118
119 DOMNode *c;
120
121 c = n->getFirstChild();
122
123 while (c != NULL) {
124 if (c->getNodeType() == DOMNode::ELEMENT_NODE)
125 recurse((DOMElement *) c);
126 c = c->getNextSibling();
127 }
128
129 }
130
attNodeCount(DOMElement * d)131 int attNodeCount(DOMElement * d) {
132
133 XMLSize_t ret;
134
135 ret = d->getAttributes()->getLength();
136
137 DOMNode *c;
138
139 c = d->getFirstChild();
140
141 while (c != NULL) {
142
143 if (c->getNodeType() == DOMNode::ELEMENT_NODE)
144 ret += attNodeCount((DOMElement *) c);
145
146 c = c->getNextSibling();
147
148 }
149
150 return (int) ret;
151
152 }
153
expandNameSpaces()154 void XSECNameSpaceExpander::expandNameSpaces() {
155
156 if (m_expanded)
157 return; // Don't do this twice!
158
159 DOMElement *docElt; // The document element - do not expand it's namespaces
160
161 docElt = mp_fragment; //mp_doc->getDocumentElement();
162
163 DOMNode *c;
164
165 c = docElt->getFirstChild();
166
167 while (c != NULL) {
168 if (c->getNodeType() == DOMNode::ELEMENT_NODE)
169 recurse((DOMElement *) c);
170 c = c->getNextSibling();
171 }
172
173 m_expanded = true;
174
175 }
176
177
deleteAddedNamespaces()178 void XSECNameSpaceExpander::deleteAddedNamespaces() {
179
180 NameSpaceEntryListVectorType::size_type size = m_lst.size();
181 XSECNameSpaceEntry *e;
182
183 NameSpaceEntryListVectorType::size_type i;
184
185 for (i = 0; i < size; ++i) {
186
187 // Delete the element attribute, and then this node
188 e = m_lst[i];
189 if (e->m_name[5] == ':')
190 e->mp_node->removeAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS,
191 MAKE_UNICODE_STRING((char *) &((e->m_name.rawBuffer())[6])));
192 else
193 e->mp_node->removeAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS,
194 MAKE_UNICODE_STRING((char *) e->m_name.rawBuffer()));
195
196 // Delete the entry
197 delete e;
198
199 }
200
201 // Now done - empty everything
202 m_lst.clear();
203 m_expanded = false;
204
205 }
206
nodeWasAdded(DOMNode * n) const207 bool XSECNameSpaceExpander::nodeWasAdded(DOMNode *n) const {
208
209 NameSpaceEntryListVectorType::size_type size = m_lst.size();
210 XSECNameSpaceEntry *e;
211
212 NameSpaceEntryListVectorType::size_type i;
213 for (i = 0; i < size; ++i) {
214
215 // Delete the element attribute, and then this node
216 e = m_lst[i];
217
218 if (e->mp_att == n)
219 return true;
220
221 }
222
223 return false;
224
225 }
226