1ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/*
2ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xlink.c : implementation of the hyperlinks detection module
3ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *           This version supports both XML XLinks and HTML simple links
4ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
5ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * See Copyright for the status of this software.
6ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
7ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * daniel@veillard.com
8ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
9ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
10ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
11ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define IN_LIBXML
12ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "libxml.h"
13ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
14ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef LIBXML_XPTR_ENABLED
15ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <string.h> /* for memset() only */
16ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_CTYPE_H
17ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <ctype.h>
18ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
19ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_STDLIB_H
20ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <stdlib.h>
21ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
22ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_SYS_STAT_H
23ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <sys/stat.h>
24ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
25ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_FCNTL_H
26ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <fcntl.h>
27ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
28ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_UNISTD_H
29ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <unistd.h>
30ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
31ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_ZLIB_H
32ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <zlib.h>
33ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
34ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
35ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/xmlmemory.h>
36ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/tree.h>
37ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/parser.h>
38ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/valid.h>
39ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/xlink.h>
40ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/globals.h>
41ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
42ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
43ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")
44ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
45ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/****************************************************************
46ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *								*
47ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *           Default setting and related functions		*
48ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *								*
49ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project ****************************************************************/
50ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
51ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic xlinkHandlerPtr xlinkDefaultHandler = NULL;
52ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic xlinkNodeDetectFunc	xlinkDefaultDetect = NULL;
53ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
54ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
55ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xlinkGetDefaultHandler:
56ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
57ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Get the default xlink handler.
58ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
59ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the current xlinkHandlerPtr value.
60ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
61ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxlinkHandlerPtr
62ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxlinkGetDefaultHandler(void) {
63ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(xlinkDefaultHandler);
64ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
65ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
66ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
67ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
68ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xlinkSetDefaultHandler:
69ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @handler:  the new value for the xlink handler block
70ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
71ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Set the default xlink handlers
72ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
73ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid
74ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxlinkSetDefaultHandler(xlinkHandlerPtr handler) {
75ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xlinkDefaultHandler = handler;
76ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
77ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
78ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
79ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xlinkGetDefaultDetect:
80ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
81ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Get the default xlink detection routine
82ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
83ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the current function or NULL;
84ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
85ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxlinkNodeDetectFunc
86ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxlinkGetDefaultDetect	(void) {
87ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(xlinkDefaultDetect);
88ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
89ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
90ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
91ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xlinkSetDefaultDetect:
92ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @func: pointer to the new detection routine.
93ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
94ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Set the default xlink detection routine
95ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
96ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid
97ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxlinkSetDefaultDetect	(xlinkNodeDetectFunc func) {
98ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xlinkDefaultDetect = func;
99ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
100ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
101ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/****************************************************************
102ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *								*
103ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *                  The detection routines			*
104ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *								*
105ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project ****************************************************************/
106ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
107ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
108ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
109ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xlinkIsLink:
110ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @doc:  the document containing the node
111ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @node:  the node pointer itself
112ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
113ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Check whether the given node carries the attributes needed
114ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * to be a link element (or is one of the linking elements issued
115ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * from the (X)HTML DtDs).
116ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * This routine don't try to do full checking of the link validity
117ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * but tries to detect and return the appropriate link type.
118ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
119ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no
120ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *         link detected.
121ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
122ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxlinkType
123ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxlinkIsLink	(xmlDocPtr doc, xmlNodePtr node) {
124ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlChar *type = NULL, *role = NULL;
125ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xlinkType ret = XLINK_TYPE_NONE;
126ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
127ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (node == NULL) return(XLINK_TYPE_NONE);
128ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (doc == NULL) doc = node->doc;
129ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
130ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        /*
131ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 * This is an HTML document.
132ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 */
133ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else if ((node->ns != NULL) &&
134ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project               (xmlStrEqual(node->ns->href, XHTML_NAMESPACE))) {
135ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	/*
136ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@
137ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 */
138ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        /*
139ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 * This is an XHTML element within an XML document
140ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 * Check whether it's one of the element able to carry links
141ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 * and in that case if it holds the attributes.
142ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 */
143ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
144ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
145ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
146ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * We don't prevent a-priori having XML Linking constructs on
147ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * XHTML elements
148ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
149ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE);
150ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (type != NULL) {
151ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (xmlStrEqual(type, BAD_CAST "simple")) {
152ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project            ret = XLINK_TYPE_SIMPLE;
153ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	} if (xmlStrEqual(type, BAD_CAST "extended")) {
154ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
155ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (role != NULL) {
156ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		xmlNsPtr xlink;
157ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE);
158ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (xlink == NULL) {
159ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    /* Humm, fallback method */
160ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    if (xmlStrEqual(role, BAD_CAST"xlink:external-linkset"))
161ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			ret = XLINK_TYPE_EXTENDED_SET;
162ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		} else {
163ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    xmlChar buf[200];
164ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    snprintf((char *) buf, sizeof(buf), "%s:external-linkset",
165ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			     (char *) xlink->prefix);
166ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                    buf[sizeof(buf) - 1] = 0;
167ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    if (xmlStrEqual(role, buf))
168ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			ret = XLINK_TYPE_EXTENDED_SET;
169ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
170ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
171ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
172ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
173ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ret = XLINK_TYPE_EXTENDED;
174ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
175ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
176ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
177ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (type != NULL) xmlFree(type);
178ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (role != NULL) xmlFree(role);
179ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(ret);
180ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
181ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif /* LIBXML_XPTR_ENABLED */
182ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define bottom_xlink
183ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "elfgcchack.h"
184