13473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 23473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xlink.c : implementation of the hyperlinks detection module 33473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This version supports both XML XLinks and HTML simple links 43473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 53473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * See Copyright for the status of this software. 63473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7c5d64345cf19bfd72418eb0a837869b0462e9130Daniel Veillard * daniel@veillard.com 83473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 93473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1134ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#define IN_LIBXML 1270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "libxml.h" 133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 144432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#ifdef LIBXML_XPTR_ENABLED 153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <string.h> /* for memset() only */ 163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_CTYPE_H 173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <ctype.h> 183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_STDLIB_H 203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <stdlib.h> 213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_STAT_H 233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/stat.h> 243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_FCNTL_H 263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <fcntl.h> 273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_UNISTD_H 293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <unistd.h> 303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 31cb5541c9f34fc29b0d7b8d89a3122c3fa46a6068Nick Wellnhofer#ifdef LIBXML_ZLIB_ENABLED 323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <zlib.h> 333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif 343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h> 363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/tree.h> 373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/parser.h> 383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/valid.h> 393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xlink.h> 403c01b1d81b696fe8624b6d7e26ec0ebffcc7c06bDaniel Veillard#include <libxml/globals.h> 413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/") 433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/") 443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**************************************************************** 463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Default setting and related functions * 483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ****************************************************************/ 50f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 51d0463560300f1d8b3e41d70c3728ed84fdc8dd30Daniel Veillardstatic xlinkHandlerPtr xlinkDefaultHandler = NULL; 52d0463560300f1d8b3e41d70c3728ed84fdc8dd30Daniel Veillardstatic xlinkNodeDetectFunc xlinkDefaultDetect = NULL; 533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xlinkGetDefaultHandler: 563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Get the default xlink handler. 583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the current xlinkHandlerPtr value. 603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxlinkHandlerPtr 623473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxlinkGetDefaultHandler(void) { 633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xlinkDefaultHandler); 643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xlinkSetDefaultHandler: 693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @handler: the new value for the xlink handler block 703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Set the default xlink handlers 723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid 743473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxlinkSetDefaultHandler(xlinkHandlerPtr handler) { 753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xlinkDefaultHandler = handler; 763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xlinkGetDefaultDetect: 803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Get the default xlink detection routine 823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the current function or NULL; 843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxlinkNodeDetectFunc 863473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxlinkGetDefaultDetect (void) { 873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(xlinkDefaultDetect); 883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xlinkSetDefaultDetect: 92cbaf399537a1fb69ef97b079e4cb553869aaa4d9Daniel Veillard * @func: pointer to the new detection routine. 933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Set the default xlink detection routine 953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 96f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillardvoid 973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxlinkSetDefaultDetect (xlinkNodeDetectFunc func) { 983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xlinkDefaultDetect = func; 993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**************************************************************** 1023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 1033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The detection routines * 1043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 1053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ****************************************************************/ 1063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 107f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 1083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xlinkIsLink: 1103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @doc: the document containing the node 1113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node: the node pointer itself 1123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check whether the given node carries the attributes needed 1143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be a link element (or is one of the linking elements issued 1153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * from the (X)HTML DtDs). 1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This routine don't try to do full checking of the link validity 1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * but tries to detect and return the appropriate link type. 1183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no 1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * link detected. 1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 122f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel VeillardxlinkType 1233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxlinkIsLink (xmlDocPtr doc, xmlNodePtr node) { 1243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *type = NULL, *role = NULL; 1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xlinkType ret = XLINK_TYPE_NONE; 1263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (node == NULL) return(XLINK_TYPE_NONE); 1283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (doc == NULL) doc = node->doc; 1293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) { 1303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This is an HTML document. 1323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else if ((node->ns != NULL) && 1343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (xmlStrEqual(node->ns->href, XHTML_NAMESPACE))) { 1353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@ 1373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * This is an XHTML element within an XML document 1403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check whether it's one of the element able to carry links 1413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and in that case if it holds the attributes. 1423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * We don't prevent a-priori having XML Linking constructs on 1473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * XHTML elements 1483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE); 1503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (type != NULL) { 151ef4d3bc36c22f6a9742e672d0bdd8342caf80c2eDaniel Veillard if (xmlStrEqual(type, BAD_CAST "simple")) { 1523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = XLINK_TYPE_SIMPLE; 15333a25af71f78c370850a057f430d874710169a6fAmi Fischman } else if (xmlStrEqual(type, BAD_CAST "extended")) { 1543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE); 1553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (role != NULL) { 1563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNsPtr xlink; 1573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE); 1583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xlink == NULL) { 1593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* Humm, fallback method */ 160f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (xmlStrEqual(role, BAD_CAST"xlink:external-linkset")) 1613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = XLINK_TYPE_EXTENDED_SET; 1623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } else { 1633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar buf[200]; 1643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor snprintf((char *) buf, sizeof(buf), "%s:external-linkset", 1653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor (char *) xlink->prefix); 1663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor buf[sizeof(buf) - 1] = 0; 1673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (xmlStrEqual(role, buf)) 1683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = XLINK_TYPE_EXTENDED_SET; 1693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = XLINK_TYPE_EXTENDED; 1743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (type != NULL) xmlFree(type); 1783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (role != NULL) xmlFree(role); 1793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 1803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 1814432df239b7aba6bff86c838e0be11d08f283b76Daniel Veillard#endif /* LIBXML_XPTR_ENABLED */ 1825d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_xlink 1835d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 184