func (xmlNode *XmlNode) ResetChildren() { var p unsafe.Pointer for childPtr := xmlNode.Ptr.children; childPtr != nil; { nextPtr := childPtr.next p = unsafe.Pointer(childPtr) C.xmlUnlinkNode((*C.xmlNode)(p)) xmlNode.Document.AddUnlinkedNode(p) childPtr = nextPtr } }
func (n *Element) RemoveAttribute(name string) error { prop, err := n.getAttributeNode(name) if err != nil { return err } C.xmlUnlinkNode((*C.xmlNode)(unsafe.Pointer(prop))) C.xmlFreeProp(prop) return nil }
func (xmlNode *XmlNode) addNextSibling(node Node) (err error) { nodeType := node.NodeType() if nodeType == XML_DOCUMENT_NODE || nodeType == XML_HTML_DOCUMENT_NODE { err = ERR_CANNOT_MAKE_DUCMENT_AS_CHILD return } nodePtr := node.NodePtr() C.xmlUnlinkNode((*C.xmlNode)(nodePtr)) C.xmlAddNextSibling(xmlNode.Ptr, (*C.xmlNode)(nodePtr)) /* childPtr := C.xmlAddNextSibling(xmlNode.Ptr, (*C.xmlNode)(nodePtr)) if nodeType == XML_TEXT_NODE && childPtr != (*C.xmlNode)(nodePtr) { //check the retured pointer //if it is not the text node just added, it means that the text node is freed because it has merged into other nodes //then we should invalid this node, because we do not want to have a dangling pointer //node.Remove() } */ return }
func (xmlNode *XmlNode) addChild(node Node) (err error) { nodeType := node.NodeType() if nodeType == XML_DOCUMENT_NODE || nodeType == XML_HTML_DOCUMENT_NODE { err = ERR_CANNOT_MAKE_DUCMENT_AS_CHILD return } nodePtr := node.NodePtr() parentPtr := xmlNode.Ptr.parent if C.xmlNodePtrCheck(unsafe.Pointer(parentPtr)) == C.int(0) { return } isNodeAccestor := false for ; parentPtr != nil; parentPtr = parentPtr.parent { if C.xmlNodePtrCheck(unsafe.Pointer(parentPtr)) == C.int(0) { return } p := unsafe.Pointer(parentPtr) if p == nodePtr { isNodeAccestor = true } } if !isNodeAccestor { C.xmlUnlinkNode((*C.xmlNode)(nodePtr)) C.xmlAddChild(xmlNode.Ptr, (*C.xmlNode)(nodePtr)) } else { node.Remove() } /* childPtr := C.xmlAddChild(xmlNode.Ptr, (*C.xmlNode)(nodePtr)) if nodeType == XML_TEXT_NODE && childPtr != (*C.xmlNode)(nodePtr) { //check the retured pointer //if it is not the text node just added, it means that the text node is freed because it has merged into other nodes //then we should invalid this node, because we do not want to have a dangling pointer node.Remove() } */ return }
// VerifySignature Verify a signature for the given context and public key func (xp *Xp) VerifySignature(context *C.xmlNode, pub *rsa.PublicKey) error { signaturelist := xp.Query(context, "ds:Signature[1]") isvalid := len(signaturelist) > 0 if !isvalid { return fmt.Errorf("no signature found") } signature := signaturelist[0] signatureValue := xp.Query1(signature, "ds:SignatureValue") signedInfo := xp.Query(signature, "ds:SignedInfo")[0] signedInfoC14n := xp.C14n(signedInfo) digestValue := xp.Query1(signedInfo, "ds:Reference/ds:DigestValue") ID := xp.Query1(context, "@ID") URI := xp.Query1(signedInfo, "ds:Reference/@URI") isvalid = "#"+ID == URI if !isvalid { return fmt.Errorf("ID mismatch") } digestMethod := xp.Query1(signedInfo, "ds:Reference/ds:DigestMethod/@Algorithm") C.xmlUnlinkNode(signature) contextDigest := Hash(algos[digestMethod].algo, xp.C14n(context)) contextDigestValueComputed := base64.StdEncoding.EncodeToString(contextDigest) isvalid = isvalid && contextDigestValueComputed == digestValue if !isvalid { return fmt.Errorf("digest mismatch") } signatureMethod := xp.Query1(signedInfo, "ds:SignatureMethod/@Algorithm") signedInfoDigest := Hash(algos[signatureMethod].algo, signedInfoC14n) ds, _ := base64.StdEncoding.DecodeString(signatureValue) err := rsa.VerifyPKCS1v15(pub, algos[signatureMethod].algo, signedInfoDigest[:], ds) if err != nil { return err } return nil }
// xmlUnlinkNode func (node *Node) Unlink() { C.xmlUnlinkNode(node.Ptr) }
// UnlinkNode shim around the libxml2 function with the same name func (xp *Xp) UnlinkNode(node *C.xmlNode) { C.xmlUnlinkNode(node) }