summaryrefslogtreecommitdiff
path: root/subversion/libsvn_ra_serf/xml.c
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2018-05-08 03:44:38 +0000
committerPeter Wemm <peter@FreeBSD.org>2018-05-08 03:44:38 +0000
commit3faf8d6bffc5d0fb2525ba37bb504c53366caf9d (patch)
tree7e47911263e75034b767fe34b2f8d3d17e91f66d /subversion/libsvn_ra_serf/xml.c
parenta55fb3c0d5eca7d887798125d5b95942b1f01d4b (diff)
Notes
Diffstat (limited to 'subversion/libsvn_ra_serf/xml.c')
-rw-r--r--subversion/libsvn_ra_serf/xml.c173
1 files changed, 31 insertions, 142 deletions
diff --git a/subversion/libsvn_ra_serf/xml.c b/subversion/libsvn_ra_serf/xml.c
index 1a988572b841a..cc6948cd607a2 100644
--- a/subversion/libsvn_ra_serf/xml.c
+++ b/subversion/libsvn_ra_serf/xml.c
@@ -24,7 +24,6 @@
#include <apr_uri.h>
-#include <expat.h>
#include <serf.h>
#include "svn_hash.h"
@@ -43,22 +42,6 @@
#include "ra_serf.h"
-/* Fix for older expat 1.95.x's that do not define
- * XML_STATUS_OK/XML_STATUS_ERROR
- */
-#ifndef XML_STATUS_OK
-#define XML_STATUS_OK 1
-#define XML_STATUS_ERROR 0
-#endif
-
-#ifndef XML_VERSION_AT_LEAST
-#define XML_VERSION_AT_LEAST(major,minor,patch) \
-(((major) < XML_MAJOR_VERSION) \
- || ((major) == XML_MAJOR_VERSION && (minor) < XML_MINOR_VERSION) \
- || ((major) == XML_MAJOR_VERSION && (minor) == XML_MINOR_VERSION && \
- (patch) <= XML_MICRO_VERSION))
-#endif /* XML_VERSION_AT_LEAST */
-
/* Read/write chunks of this size into the spillbuf. */
#define PARSE_CHUNK_SIZE 8000
@@ -149,12 +132,10 @@ struct svn_ra_serf__xml_estate_t {
struct expat_ctx_t {
svn_ra_serf__xml_context_t *xmlctx;
- XML_Parser parser;
+ svn_xml_parser_t *parser;
svn_ra_serf__handler_t *handler;
const int *expected_status;
- svn_error_t *inner_error;
-
/* Do not use this pool for allocation. It is merely recorded for running
the cleanup handler. */
apr_pool_t *cleanup_pool;
@@ -886,132 +867,60 @@ xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx,
return SVN_NO_ERROR;
}
-/* svn_error_t * wrapper around XML_Parse */
+/* Wrapper around svn_xml_parse */
static APR_INLINE svn_error_t *
parse_xml(struct expat_ctx_t *ectx, const char *data, apr_size_t len, svn_boolean_t is_final)
{
- int xml_status = XML_Parse(ectx->parser, data, (int)len, is_final);
- const char *msg;
- int xml_code;
-
- if (xml_status == XML_STATUS_OK)
- return ectx->inner_error;
-
- xml_code = XML_GetErrorCode(ectx->parser);
-
-#if XML_VERSION_AT_LEAST(1, 95, 8)
- /* If we called XML_StopParser() expat will return an abort error. If we
- have a better error stored we should ignore it as it will not help
- the end-user to store it in the error chain. */
- if (xml_code == XML_ERROR_ABORTED && ectx->inner_error)
- return ectx->inner_error;
-#endif
-
- msg = XML_ErrorString(xml_code);
-
- return svn_error_compose_create(
- ectx->inner_error,
- svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA,
- svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
- _("Malformed XML: %s"),
- msg),
- _("The XML response contains invalid XML")));
-}
-
-/* Apr pool cleanup handler to release an XML_Parser in success and error
- conditions */
-static apr_status_t
-xml_parser_cleanup(void *baton)
-{
- XML_Parser *xmlp = baton;
+ svn_error_t *err = svn_xml_parse(ectx->parser, data, len, is_final);
- if (*xmlp)
- {
- (void) XML_ParserFree(*xmlp);
- *xmlp = NULL;
- }
+ if (err && err->apr_err == SVN_ERR_XML_MALFORMED)
+ err = svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, err,
+ _("The XML response contains invalid XML"));
- return APR_SUCCESS;
+ return err;
}
-/* Conforms to Expat's XML_StartElementHandler */
+/* Implements svn_xml_start_elem callback */
static void
-expat_start(void *userData, const char *raw_name, const char **attrs)
+expat_start(void *baton, const char *raw_name, const char **attrs)
{
- struct expat_ctx_t *ectx = userData;
-
- if (ectx->inner_error != NULL)
- return;
+ struct expat_ctx_t *ectx = baton;
+ svn_error_t *err;
- ectx->inner_error = svn_error_trace(xml_cb_start(ectx->xmlctx,
- raw_name, attrs));
+ err = svn_error_trace(xml_cb_start(ectx->xmlctx, raw_name, attrs));
-#if XML_VERSION_AT_LEAST(1, 95, 8)
- if (ectx->inner_error)
- (void) XML_StopParser(ectx->parser, 0 /* resumable */);
-#endif
+ if (err)
+ svn_xml_signal_bailout(err, ectx->parser);
}
-/* Conforms to Expat's XML_EndElementHandler */
+/* Implements svn_xml_end_elem callback */
static void
-expat_end(void *userData, const char *raw_name)
+expat_end(void *baton, const char *raw_name)
{
- struct expat_ctx_t *ectx = userData;
-
- if (ectx->inner_error != NULL)
- return;
+ struct expat_ctx_t *ectx = baton;
+ svn_error_t *err;
- ectx->inner_error = svn_error_trace(xml_cb_end(ectx->xmlctx, raw_name));
+ err = svn_error_trace(xml_cb_end(ectx->xmlctx, raw_name));
-#if XML_VERSION_AT_LEAST(1, 95, 8)
- if (ectx->inner_error)
- (void) XML_StopParser(ectx->parser, 0 /* resumable */);
-#endif
+ if (err)
+ svn_xml_signal_bailout(err, ectx->parser);
}
-/* Conforms to Expat's XML_CharacterDataHandler */
+/* Implements svn_xml_char_data callback */
static void
-expat_cdata(void *userData, const char *data, int len)
+expat_cdata(void *baton, const char *data, apr_size_t len)
{
- struct expat_ctx_t *ectx = userData;
-
- if (ectx->inner_error != NULL)
- return;
+ struct expat_ctx_t *ectx = baton;
+ svn_error_t *err;
- ectx->inner_error = svn_error_trace(xml_cb_cdata(ectx->xmlctx, data, len));
+ err = svn_error_trace(xml_cb_cdata(ectx->xmlctx, data, len));
-#if XML_VERSION_AT_LEAST(1, 95, 8)
- if (ectx->inner_error)
- (void) XML_StopParser(ectx->parser, 0 /* resumable */);
-#endif
+ if (err)
+ svn_xml_signal_bailout(err, ectx->parser);
}
-#if XML_VERSION_AT_LEAST(1, 95, 8)
-static void
-expat_entity_declaration(void *userData,
- const XML_Char *entityName,
- int is_parameter_entity,
- const XML_Char *value,
- int value_length,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName)
-{
- struct expat_ctx_t *ectx = userData;
-
- /* Stop the parser if an entity declaration is hit. */
- XML_StopParser(ectx->parser, 0 /* resumable */);
-}
-#else
-/* A noop default_handler. */
-static void
-expat_default_handler(void *userData, const XML_Char *s, int len)
-{
-}
-#endif
/* Implements svn_ra_serf__response_handler_t */
static svn_error_t *
@@ -1060,18 +969,8 @@ expat_response_handler(serf_request_t *request,
if (!ectx->parser)
{
- ectx->parser = XML_ParserCreate(NULL);
- apr_pool_cleanup_register(ectx->cleanup_pool, &ectx->parser,
- xml_parser_cleanup, apr_pool_cleanup_null);
- XML_SetUserData(ectx->parser, ectx);
- XML_SetElementHandler(ectx->parser, expat_start, expat_end);
- XML_SetCharacterDataHandler(ectx->parser, expat_cdata);
-
-#if XML_VERSION_AT_LEAST(1, 95, 8)
- XML_SetEntityDeclHandler(ectx->parser, expat_entity_declaration);
-#else
- XML_SetDefaultHandler(ectx->parser, expat_default_handler);
-#endif
+ ectx->parser = svn_xml_make_parser(ectx, expat_start, expat_end,
+ expat_cdata, ectx->cleanup_pool);
}
while (1)
@@ -1079,7 +978,6 @@ expat_response_handler(serf_request_t *request,
apr_status_t status;
const char *data;
apr_size_t len;
- svn_error_t *err;
svn_boolean_t at_eof = FALSE;
status = serf_bucket_read(response, PARSE_CHUNK_SIZE, &data, &len);
@@ -1088,16 +986,7 @@ expat_response_handler(serf_request_t *request,
else if (APR_STATUS_IS_EOF(status))
at_eof = TRUE;
- err = parse_xml(ectx, data, len, at_eof /* isFinal */);
-
- if (at_eof || err)
- {
- /* Release xml parser state/tables. */
- apr_pool_cleanup_run(ectx->cleanup_pool, &ectx->parser,
- xml_parser_cleanup);
- }
-
- SVN_ERR(err);
+ SVN_ERR(parse_xml(ectx, data, len, at_eof /* isFinal */));
/* The parsing went fine. What has the bucket told us? */
if (at_eof)