PostgreSQL Source Code: contrib/xml2/xslt_proc.c Source File (original) (raw)

1

2

3

4

5

6

7

9

13

14#ifdef USE_LIBXSLT

15

16

17

18#include <libxml/xpath.h>

19#include <libxml/tree.h>

20#include <libxml/xmlmemory.h>

21

22

23

24#include <libxslt/xslt.h>

25#include <libxslt/xsltInternals.h>

26#include <libxslt/security.h>

27#include <libxslt/transform.h>

28#include <libxslt/xsltutils.h>

29#endif

30

31

32#ifdef USE_LIBXSLT

33

34

36

37

38static const char **parse_params(text *paramstr);

39#endif

40

41

43

46{

47#ifdef USE_LIBXSLT

48

52 text *paramstr;

53 const char **params;

55 volatile xsltStylesheetPtr stylesheet = NULL;

56 volatile xmlDocPtr doctree = NULL;

57 volatile xmlDocPtr restree = NULL;

58 volatile xsltSecurityPrefsPtr xslt_sec_prefs = NULL;

59 volatile xsltTransformContextPtr xslt_ctxt = NULL;

60 volatile int resstat = -1;

61 xmlChar *resstr = NULL;

62 int reslen = 0;

63

64 if (fcinfo->nargs == 3)

65 {

67 params = parse_params(paramstr);

68 }

69 else

70 {

71

72 params = (const char **) palloc(sizeof(char *));

73 params[0] = NULL;

74 }

75

76

78

80 {

81 xmlDocPtr ssdoc;

82 bool xslt_sec_prefs_error;

83

84

85 doctree = xmlReadMemory((char *) VARDATA_ANY(doct),

87 XML_PARSE_NOENT);

88

89 if (doctree == NULL)

91 "error parsing XML document");

92

93

94 ssdoc = xmlReadMemory((char *) VARDATA_ANY(ssheet),

96 XML_PARSE_NOENT);

97

98 if (ssdoc == NULL)

100 "error parsing stylesheet as XML document");

101

102

103 stylesheet = xsltParseStylesheetDoc(ssdoc);

104

105 if (stylesheet == NULL)

106 xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,

107 "failed to parse stylesheet");

108

109 xslt_ctxt = xsltNewTransformContext(stylesheet, doctree);

110

111 xslt_sec_prefs_error = false;

112 if ((xslt_sec_prefs = xsltNewSecurityPrefs()) == NULL)

113 xslt_sec_prefs_error = true;

114

115 if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_READ_FILE,

116 xsltSecurityForbid) != 0)

117 xslt_sec_prefs_error = true;

118 if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_WRITE_FILE,

119 xsltSecurityForbid) != 0)

120 xslt_sec_prefs_error = true;

121 if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_CREATE_DIRECTORY,

122 xsltSecurityForbid) != 0)

123 xslt_sec_prefs_error = true;

124 if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_READ_NETWORK,

125 xsltSecurityForbid) != 0)

126 xslt_sec_prefs_error = true;

127 if (xsltSetSecurityPrefs(xslt_sec_prefs, XSLT_SECPREF_WRITE_NETWORK,

128 xsltSecurityForbid) != 0)

129 xslt_sec_prefs_error = true;

130 if (xsltSetCtxtSecurityPrefs(xslt_sec_prefs, xslt_ctxt) != 0)

131 xslt_sec_prefs_error = true;

132

133 if (xslt_sec_prefs_error)

135 (errmsg("could not set libxslt security preferences")));

136

137 restree = xsltApplyStylesheetUser(stylesheet, doctree, params,

138 NULL, NULL, xslt_ctxt);

139

140 if (restree == NULL)

141 xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,

142 "failed to apply stylesheet");

143

144 resstat = xsltSaveResultToString(&resstr, &reslen, restree, stylesheet);

145 }

147 {

148 if (restree != NULL)

149 xmlFreeDoc(restree);

150 if (xslt_ctxt != NULL)

151 xsltFreeTransformContext(xslt_ctxt);

152 if (xslt_sec_prefs != NULL)

153 xsltFreeSecurityPrefs(xslt_sec_prefs);

154 if (stylesheet != NULL)

155 xsltFreeStylesheet(stylesheet);

156 if (doctree != NULL)

157 xmlFreeDoc(doctree);

158 xsltCleanupGlobals();

159

161

163 }

165

166 xmlFreeDoc(restree);

167 xsltFreeTransformContext(xslt_ctxt);

168 xsltFreeSecurityPrefs(xslt_sec_prefs);

169 xsltFreeStylesheet(stylesheet);

170 xmlFreeDoc(doctree);

171 xsltCleanupGlobals();

172

174

175

176 if (resstat < 0)

178

180

181 if (resstr)

182 xmlFree(resstr);

183

185#else

186

188 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

189 errmsg("xslt_process() is not available without libxslt")));

191#endif

192}

193

194#ifdef USE_LIBXSLT

195

196static const char **

197parse_params(text *paramstr)

198{

199 char *pos;

200 char *pstr;

201 char *nvsep = "=";

202 char *itsep = ",";

203 const char **params;

204 int max_params;

205 int nparams;

206

208

209 max_params = 20;

210 params = (const char **) palloc((max_params + 1) * sizeof(char *));

211 nparams = 0;

212

213 pos = pstr;

214

215 while (*pos != '\0')

216 {

217 if (nparams >= max_params)

218 {

219 max_params *= 2;

220 params = (const char **) repalloc(params,

221 (max_params + 1) * sizeof(char *));

222 }

223 params[nparams++] = pos;

224 pos = strstr(pos, nvsep);

225 if (pos != NULL)

226 {

227 *pos = '\0';

228 pos++;

229 }

230 else

231 {

232

233 nparams--;

234 break;

235 }

236

237

238 params[nparams++] = pos;

239 pos = strstr(pos, itsep);

240 if (pos != NULL)

241 {

242 *pos = '\0';

243 pos++;

244 }

245 else

246 break;

247 }

248

249

250 params[nparams] = NULL;

251

252 return params;

253}

254

255#endif

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

#define PG_GETARG_TEXT_PP(n)

#define PG_RETURN_TEXT_P(x)

void * repalloc(void *pointer, Size size)

#define VARSIZE_ANY_EXHDR(PTR)

text * cstring_to_text_with_len(const char *s, int len)

char * text_to_cstring(const text *t)

struct PgXmlErrorContext PgXmlErrorContext

void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)

void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)

@ PG_XML_STRICTNESS_LEGACY

PgXmlErrorContext * pgxml_parser_init(PgXmlStrictness strictness)

PG_FUNCTION_INFO_V1(xslt_process)

Datum xslt_process(PG_FUNCTION_ARGS)