lib/xml/util/xmlcanonicalizer.rb in canonix-0.1.5 vs lib/xml/util/xmlcanonicalizer.rb in canonix-0.1.7
- old
+ new
@@ -8,45 +8,43 @@
require "rexml/document"
require "base64"
module XML
include REXML
-
+
module Util
-
class NamespaceNode
attr_reader :prefix, :uri
def initialize(prefix, uri)
@prefix = prefix
@uri = uri
end
end
-
+
class XmlCanonicalizer
attr_accessor :prefix_list, :logger, :inclusive_namespaces
-
+
BEFORE_DOC_ELEMENT = 0
INSIDE_DOC_ELEMENT = 1
AFTER_DOC_ELEMENT = 2
-
+
NODE_TYPE_ATTRIBUTE = 3
NODE_TYPE_WHITESPACE = 4
NODE_TYPE_COMMENT = 5
NODE_TYPE_PI = 6
NODE_TYPE_TEXT = 7
-
-
+
def initialize(with_comments, excl_c14n)
@with_comments = with_comments
@exclusive = excl_c14n
@state = BEFORE_DOC_ELEMENT
@xnl = Array.new()
@prevVisibleNamespacesStart = 0
@prevVisibleNamespacesEnd = 0
@visibleNamespaces = Array.new()
end
-
+
def add_inclusive_namespaces(prefix_list, element, visible_namespaces)
namespaces = element.attributes()
namespaces.each_attribute{|ns|
if (ns.prefix=="xmlns")
if (prefix_list.include?(ns.local_name()))
@@ -56,15 +54,15 @@
}
parent = element.parent()
add_inclusive_namespaces(prefix_list, parent, visible_namespaces) if (parent)
visible_namespaces
end
-
+
def canonicalize(document)
write_document_node(document)
end
-
+
def canonicalize_element(element, logging = true)
@preserve_document = element.document()
tmp_parent = element.parent()
body_string = remove_whitespace(element.to_s().gsub("\n","").gsub("\t","").gsub("\r",""))
document = Document.new(body_string)
@@ -74,11 +72,11 @@
document = Document.new(element.to_s())
ns = element.namespace(element.prefix())
document.root().add_namespace(element.prefix(), ns)
write_document_node(document)
end
-
+
def write_document_node(document)
@res = ""
@state = BEFORE_DOC_ELEMENT
if (document.class().to_s() == "REXML::Element")
write_node(document)
@@ -87,11 +85,11 @@
write_node(child)
}
end
@res
end
-
+
def write_node(node)
visible = is_node_visible(node)
if ((node.node_type() == :text) && white_text?(node.value()))
res = node.value()
res.gsub("\r\n","\n")
@@ -111,11 +109,11 @@
if (node.node_type() == :processing_instruction)
end
if (node.node_type() == :comment)
end
end
-
+
def write_element_node(node, visible)
savedPrevVisibleNamespacesStart = @prevVisibleNamespacesStart
savedPrevVisibleNamespacesEnd = @prevVisibleNamespacesEnd
savedVisibleNamespacesSize = @visibleNamespaces.size()
state = @state
@@ -131,11 +129,11 @@
@state = AFTER_DOC_ELEMENT if (visible && state == BEFORE_DOC_ELEMENT)
@prevVisibleNamespacesStart = savedPrevVisibleNamespacesStart
@prevVisibleNamespacesEnd = savedPrevVisibleNamespacesEnd
@visibleNamespaces.slice!(savedVisibleNamespacesSize, @visibleNamespaces.size() - savedVisibleNamespacesSize) if (@visibleNamespaces.size() > savedVisibleNamespacesSize)
end
-
+
def write_namespace_axis(node, visible)
doc = node.document()
has_empty_namespace = false
list = Array.new()
cur = node
@@ -155,18 +153,18 @@
has_empty_namespace = true if (prefix == nil)
}
if (visible && !has_empty_namespace && !is_namespace_rendered(nil, nil))
@res = @res + ' xmlns=""'
end
-
+
#: ns of inclusive_list
if self.inclusive_namespaces && !self.inclusive_namespaces.empty?
self.inclusive_namespaces.each{|prefix|
list.push(prefix) if (!list.include?(prefix) && (node.attributes.prefixes.include?(prefix)))
}
end
-
+
if list.delete('xmlns')
list = ["xmlns"] + list.sort
else
list.sort!
end
@@ -180,11 +178,11 @@
if (visible)
@prevVisibleNamespacesStart = @prevVisibleNamespacesEnd
@prevVisibleNamespacesEnd = @visibleNamespaces.size()
end
end
-
+
def node_namespaces(node)
ns = Array.new()
ns.push(node.prefix())
node.attributes().each_attribute{|a|
if (a.prefix() != nil)
@@ -194,11 +192,11 @@
ns.push("xmlns")
end
}
ns
end
-
+
def write_attribute_axis(node)
list = Array.new()
node.attributes.keys.sort.each{|key|
attr = node.attributes.get_attribute(key)
list.push(attr) if (!is_namespace_node(attr.value()) && !is_namespace_decl(attr))
@@ -231,15 +229,15 @@
# @res = @res + " " + normalize_string(attribute.name()+'="'+attribute.to_s()+'"', NODE_TYPE_ATTRIBUTE).gsub("'",'"')
end
end
}
end
-
+
def is_namespace_node(namespace_uri)
return (namespace_uri == "http://www.w3.org/2000/xmlns/")
end
-
+
def is_namespace_rendered(prefix, uri)
is_empty_ns = prefix == nil && uri == nil
if (is_empty_ns)
start = 0
else
@@ -257,19 +255,19 @@
# # p = ns.prefix() if (ns.prefix().index("xmlns") == 0)
# # return ns.uri() == uri if (p == prefix)
# }
# return is_empty_ns
end
-
+
def is_node_visible(node)
return true if (@xnl.size() == 0)
@xnl.each{|element|
return true if (element == node)
}
return false
end
-
+
def normalize_string(input, type)
sb = ""
return input
# input.each_byte{|b|
# if (b == 60 && (type == NODE_TYPE_ATTRIBUTE || is_text_node(type)))
@@ -292,33 +290,33 @@
# sb = sb.concat(b)
# end
# }
# sb
end
-
+
def write_text_node(node, visible)
if (visible)
- @res = @res + normalize_string(node.value(), node.node_type())
+ @res = @res + normalize_string(node.to_s, node.node_type())
end
end
-
+
def white_text?(text)
return true if ((text.strip() == "") || (text.strip() == nil))
return false
end
-
+
def is_namespace_decl(attribute)
# return true if (attribute.name() == "xmlns")
return true if (attribute.prefix().index("xmlns") == 0)
return false
end
-
+
def is_text_node(type)
return true if (type == NODE_TYPE_TEXT || type == NODE_TYPE_CDATA || type == NODE_TYPE_WHITESPACE)
return false
end
-
+
def remove_whitespace(string)
new_string = ""
in_white = false
string.each_byte{|b|
# if (in_white && b == 32)
@@ -337,16 +335,15 @@
end
end
end #Util
end #XML
-
if __FILE__ == $0
document = Document.new(File.new(ARGV[0]))
body = nil
c = WSS4R::Security::Util::XmlCanonicalizer.new(false, true)
-
+
if (ARGV.size() == 3)
body = ARGV[2]
if (body == "true")
element = XPath.match(document, "/soap:Envelope/soap:Body")[0]
element = XPath.first(document, "/soap:Envelope/soap:Header/wsse:Security/Signature/SignedInfo")
@@ -359,10 +356,10 @@
puts(CryptHash.new().digest_b64(result))
end
else
result = c.canonicalize(document)
end
-
+
file = File.new(ARGV[1], "wb")
file.write(result)
file.close()
end