1 /* libxml2 - Library for parsing XML documents
2  * Copyright (C) 2006-2019 Free Software Foundation, Inc.
3  *
4  * This file is not part of the GNU gettext program, but is used with
5  * GNU gettext.
6  *
7  * The original copyright notice is as follows:
8  */
9 
10 /*
11  * Copyright (C) 1998-2012 Daniel Veillard.  All Rights Reserved.
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a copy
14  * of this software and associated documentation files (the "Software"), to deal
15  * in the Software without restriction, including without limitation the rights
16  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17  * copies of the Software, and to permit persons to whom the Software is fur-
18  * nished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included in
21  * all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
25  * NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
26  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29  * THE SOFTWARE.
30  *
31  * daniel@veillard.com
32  */
33 
34 /*
35  * xlink.c : implementation of the hyperlinks detection module
36  *           This version supports both XML XLinks and HTML simple links
37  */
38 
39 #define IN_LIBXML
40 #include "libxml.h"
41 
42 #ifdef LIBXML_XPTR_ENABLED
43 #include <string.h> /* for memset() only */
44 #ifdef HAVE_CTYPE_H
45 #include <ctype.h>
46 #endif
47 #ifdef HAVE_STDLIB_H
48 #include <stdlib.h>
49 #endif
50 #ifdef HAVE_SYS_STAT_H
51 #include <sys/stat.h>
52 #endif
53 #ifdef HAVE_FCNTL_H
54 #include <fcntl.h>
55 #endif
56 #ifdef HAVE_UNISTD_H
57 #include <unistd.h>
58 #endif
59 #ifdef LIBXML_ZLIB_ENABLED
60 #include <zlib.h>
61 #endif
62 
63 #include <libxml/xmlmemory.h>
64 #include <libxml/tree.h>
65 #include <libxml/parser.h>
66 #include <libxml/valid.h>
67 #include <libxml/xlink.h>
68 #include <libxml/globals.h>
69 
70 #define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
71 #define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")
72 
73 /****************************************************************
74  *								*
75  *           Default setting and related functions		*
76  *								*
77  ****************************************************************/
78 
79 static xlinkHandlerPtr xlinkDefaultHandler = NULL;
80 static xlinkNodeDetectFunc	xlinkDefaultDetect = NULL;
81 
82 /**
83  * xlinkGetDefaultHandler:
84  *
85  * Get the default xlink handler.
86  *
87  * Returns the current xlinkHandlerPtr value.
88  */
89 xlinkHandlerPtr
xlinkGetDefaultHandler(void)90 xlinkGetDefaultHandler(void) {
91     return(xlinkDefaultHandler);
92 }
93 
94 
95 /**
96  * xlinkSetDefaultHandler:
97  * @handler:  the new value for the xlink handler block
98  *
99  * Set the default xlink handlers
100  */
101 void
xlinkSetDefaultHandler(xlinkHandlerPtr handler)102 xlinkSetDefaultHandler(xlinkHandlerPtr handler) {
103     xlinkDefaultHandler = handler;
104 }
105 
106 /**
107  * xlinkGetDefaultDetect:
108  *
109  * Get the default xlink detection routine
110  *
111  * Returns the current function or NULL;
112  */
113 xlinkNodeDetectFunc
xlinkGetDefaultDetect(void)114 xlinkGetDefaultDetect	(void) {
115     return(xlinkDefaultDetect);
116 }
117 
118 /**
119  * xlinkSetDefaultDetect:
120  * @func: pointer to the new detection routine.
121  *
122  * Set the default xlink detection routine
123  */
124 void
xlinkSetDefaultDetect(xlinkNodeDetectFunc func)125 xlinkSetDefaultDetect	(xlinkNodeDetectFunc func) {
126     xlinkDefaultDetect = func;
127 }
128 
129 /****************************************************************
130  *								*
131  *                  The detection routines			*
132  *								*
133  ****************************************************************/
134 
135 
136 /**
137  * xlinkIsLink:
138  * @doc:  the document containing the node
139  * @node:  the node pointer itself
140  *
141  * Check whether the given node carries the attributes needed
142  * to be a link element (or is one of the linking elements issued
143  * from the (X)HTML DtDs).
144  * This routine don't try to do full checking of the link validity
145  * but tries to detect and return the appropriate link type.
146  *
147  * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no
148  *         link detected.
149  */
150 xlinkType
xlinkIsLink(xmlDocPtr doc,xmlNodePtr node)151 xlinkIsLink	(xmlDocPtr doc, xmlNodePtr node) {
152     xmlChar *type = NULL, *role = NULL;
153     xlinkType ret = XLINK_TYPE_NONE;
154 
155     if (node == NULL) return(XLINK_TYPE_NONE);
156     if (doc == NULL) doc = node->doc;
157     if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
158         /*
159 	 * This is an HTML document.
160 	 */
161     } else if ((node->ns != NULL) &&
162                (xmlStrEqual(node->ns->href, XHTML_NAMESPACE))) {
163 	/*
164 	 * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@
165 	 */
166         /*
167 	 * This is an XHTML element within an XML document
168 	 * Check whether it's one of the element able to carry links
169 	 * and in that case if it holds the attributes.
170 	 */
171     }
172 
173     /*
174      * We don't prevent a-priori having XML Linking constructs on
175      * XHTML elements
176      */
177     type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE);
178     if (type != NULL) {
179 	if (xmlStrEqual(type, BAD_CAST "simple")) {
180             ret = XLINK_TYPE_SIMPLE;
181 	} else if (xmlStrEqual(type, BAD_CAST "extended")) {
182 	    role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
183 	    if (role != NULL) {
184 		xmlNsPtr xlink;
185 		xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE);
186 		if (xlink == NULL) {
187 		    /* Humm, fallback method */
188 		    if (xmlStrEqual(role, BAD_CAST"xlink:external-linkset"))
189 			ret = XLINK_TYPE_EXTENDED_SET;
190 		} else {
191 		    xmlChar buf[200];
192 		    snprintf((char *) buf, sizeof(buf), "%s:external-linkset",
193 			     (char *) xlink->prefix);
194                     buf[sizeof(buf) - 1] = 0;
195 		    if (xmlStrEqual(role, buf))
196 			ret = XLINK_TYPE_EXTENDED_SET;
197 
198 		}
199 
200 	    }
201 	    ret = XLINK_TYPE_EXTENDED;
202 	}
203     }
204 
205     if (type != NULL) xmlFree(type);
206     if (role != NULL) xmlFree(role);
207     return(ret);
208 }
209 #endif /* LIBXML_XPTR_ENABLED */
210 #define bottom_xlink
211 #include "elfgcchack.h"
212