/*
 * xml.c :  standard XML parsing routines for ra_serf
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */



#include <apr_uri.h>
#include <expat.h>
#include <serf.h>

#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_ra.h"
#include "svn_dav.h"
#include "svn_xml.h"
#include "../libsvn_ra/ra_loader.h"
#include "svn_config.h"
#include "svn_delta.h"
#include "svn_path.h"

#include "svn_private_config.h"
#include "private/svn_string_private.h"

#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


struct svn_ra_serf__xml_context_t {
  /* Current state information.  */
  svn_ra_serf__xml_estate_t *current;

  /* If WAITING >= then we are waiting for an element to close before
     resuming events. The number stored here is the amount of nested
     elements open. The Xml parser will make sure the document is well
     formed. */
  int waiting;

  /* The transition table.  */
  const svn_ra_serf__xml_transition_t *ttable;

  /* The callback information.  */
  svn_ra_serf__xml_opened_t opened_cb;
  svn_ra_serf__xml_closed_t closed_cb;
  svn_ra_serf__xml_cdata_t cdata_cb;
  void *baton;

  /* Linked list of free states.  */
  svn_ra_serf__xml_estate_t *free_states;

#ifdef SVN_DEBUG
  /* Used to verify we are not re-entering a callback, specifically to
     ensure SCRATCH_POOL is not cleared while an outer callback is
     trying to use it.  */
  svn_boolean_t within_callback;
#define START_CALLBACK(xmlctx) \
  do {                                                    \
    svn_ra_serf__xml_context_t *xmlctx__tmp = (xmlctx);   \
    SVN_ERR_ASSERT(!xmlctx__tmp->within_callback);        \
    xmlctx__tmp->within_callback = TRUE;                  \
  } while (0)
#define END_CALLBACK(xmlctx) ((xmlctx)->within_callback = FALSE)
#else
#define START_CALLBACK(xmlctx)  /* empty */
#define END_CALLBACK(xmlctx)  /* empty */
#endif /* SVN_DEBUG  */

  apr_pool_t *scratch_pool;

};

/* Structure which represents an XML namespace. */
typedef struct svn_ra_serf__ns_t {
  /* The assigned name. */
  const char *xmlns;
  /* The full URL for this namespace. */
  const char *url;
  /* The next namespace in our list. */
  struct svn_ra_serf__ns_t *next;
} svn_ra_serf__ns_t;

struct svn_ra_serf__xml_estate_t {
  /* The current state value.  */
  int state;

  /* The xml tag that opened this state. Waiting for the tag to close.  */
  svn_ra_serf__dav_props_t tag;

  /* Should the CLOSED_CB function be called for custom processing when
     this tag is closed?  */
  svn_boolean_t custom_close;

  /* A pool may be constructed for this state.  */
  apr_pool_t *state_pool;

  /* The namespaces extent for this state/element. This will start with
     the parent's NS_LIST, and we will push new namespaces into our
     local list. The parent will be unaffected by our locally-scoped data. */
  svn_ra_serf__ns_t *ns_list;

  /* Any collected attribute values. char * -> svn_string_t *. May be NULL
     if no attributes have been collected.  */
  apr_hash_t *attrs;

  /* Any collected cdata. May be NULL if no cdata is being collected.  */
  svn_stringbuf_t *cdata;

  /* Previous/outer state.  */
  svn_ra_serf__xml_estate_t *prev;

};

struct expat_ctx_t {
  svn_ra_serf__xml_context_t *xmlctx;
  XML_Parser 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;
};


static void
define_namespaces(svn_ra_serf__ns_t **ns_list,
                  const char *const *attrs,
                  apr_pool_t *(*get_pool)(void *baton),
                  void *baton)
{
  const char *const *tmp_attrs = attrs;

  for (tmp_attrs = attrs; *tmp_attrs != NULL; tmp_attrs += 2)
    {
      if (strncmp(*tmp_attrs, "xmlns", 5) == 0)
        {
          const svn_ra_serf__ns_t *cur_ns;
          svn_boolean_t found = FALSE;
          const char *prefix;

          /* The empty prefix, or a named-prefix.  */
          if (tmp_attrs[0][5] == ':')
            prefix = &tmp_attrs[0][6];
          else
            prefix = "";

          /* Have we already defined this ns previously? */
          for (cur_ns = *ns_list; cur_ns; cur_ns = cur_ns->next)
            {
              if (strcmp(cur_ns->xmlns, prefix) == 0)
                {
                  found = TRUE;
                  break;
                }
            }

          if (!found)
            {
              apr_pool_t *pool;
              svn_ra_serf__ns_t *new_ns;

              if (get_pool)
                pool = get_pool(baton);
              else
                pool = baton;
              new_ns = apr_palloc(pool, sizeof(*new_ns));
              new_ns->xmlns = apr_pstrdup(pool, prefix);
              new_ns->url = apr_pstrdup(pool, tmp_attrs[1]);

              /* Push into the front of NS_LIST. Parent states will point
                 to later in the chain, so will be unaffected by
                 shadowing/other namespaces pushed onto NS_LIST.  */
              new_ns->next = *ns_list;
              *ns_list = new_ns;
            }
        }
    }
}

/*
 * Look up @a name in the @a ns_list list for previously declared namespace
 * definitions.
 *
 * Return (in @a *returned_prop_name) a #svn_ra_serf__dav_props_t tuple
 * representing the expanded name.
 */
static void
expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
                       const svn_ra_serf__ns_t *ns_list,
                       const char *name)
{
  const char *colon;

  colon = strchr(name, ':');
  if (colon)
    {
      const svn_ra_serf__ns_t *ns;

      for (ns = ns_list; ns; ns = ns->next)
        {
          if (strncmp(ns->xmlns, name, colon - name) == 0)
            {
              returned_prop_name->xmlns = ns->url;
              returned_prop_name->name = colon + 1;
              return;
            }
        }
    }
  else
    {
      const svn_ra_serf__ns_t *ns;

      for (ns = ns_list; ns; ns = ns->next)
        {
          if (! ns->xmlns[0])
            {
              returned_prop_name->xmlns = ns->url;
              returned_prop_name->name = name;
              return;
            }
        }
    }

  /* If the prefix is not found, then the name is NOT within a
     namespace.  */
  returned_prop_name->xmlns = "";
  returned_prop_name->name = name;
}


#define XML_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?>"

void
svn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket,
                                    serf_bucket_alloc_t *bkt_alloc)
{
  serf_bucket_t *tmp;

  tmp = SERF_BUCKET_SIMPLE_STRING_LEN(XML_HEADER, sizeof(XML_HEADER) - 1,
                                      bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);
}

void
svn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket,
                                  serf_bucket_alloc_t *bkt_alloc,
                                  const char *tag, ...)
{
  va_list ap;
  const char *key;
  serf_bucket_t *tmp;

  tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<", 1, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);

  tmp = SERF_BUCKET_SIMPLE_STRING(tag, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);

  va_start(ap, tag);
  while ((key = va_arg(ap, char *)) != NULL)
    {
      const char *val = va_arg(ap, const char *);
      if (val)
        {
          tmp = SERF_BUCKET_SIMPLE_STRING_LEN(" ", 1, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);

          tmp = SERF_BUCKET_SIMPLE_STRING(key, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);

          tmp = SERF_BUCKET_SIMPLE_STRING_LEN("=\"", 2, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);

          tmp = SERF_BUCKET_SIMPLE_STRING(val, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);

          tmp = SERF_BUCKET_SIMPLE_STRING_LEN("\"", 1, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);
        }
    }
  va_end(ap);

  tmp = SERF_BUCKET_SIMPLE_STRING_LEN(">", 1, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);
}

void
svn_ra_serf__add_empty_tag_buckets(serf_bucket_t *agg_bucket,
                                   serf_bucket_alloc_t *bkt_alloc,
                                   const char *tag, ...)
{
  va_list ap;
  const char *key;
  serf_bucket_t *tmp;

  tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<", 1, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);

  tmp = SERF_BUCKET_SIMPLE_STRING(tag, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);

  va_start(ap, tag);
  while ((key = va_arg(ap, char *)) != NULL)
    {
      const char *val = va_arg(ap, const char *);
      if (val)
        {
          tmp = SERF_BUCKET_SIMPLE_STRING_LEN(" ", 1, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);

          tmp = SERF_BUCKET_SIMPLE_STRING(key, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);

          tmp = SERF_BUCKET_SIMPLE_STRING_LEN("=\"", 2, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);

          tmp = SERF_BUCKET_SIMPLE_STRING(val, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);

          tmp = SERF_BUCKET_SIMPLE_STRING_LEN("\"", 1, bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp);
        }
    }
  va_end(ap);

  tmp = SERF_BUCKET_SIMPLE_STRING_LEN("/>", 2, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);
}

void
svn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket,
                                   serf_bucket_alloc_t *bkt_alloc,
                                   const char *tag)
{
  serf_bucket_t *tmp;

  tmp = SERF_BUCKET_SIMPLE_STRING_LEN("</", 2, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);

  tmp = SERF_BUCKET_SIMPLE_STRING(tag, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);

  tmp = SERF_BUCKET_SIMPLE_STRING_LEN(">", 1, bkt_alloc);
  serf_bucket_aggregate_append(agg_bucket, tmp);
}

void
svn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket,
                                   serf_bucket_alloc_t *bkt_alloc,
                                   const char *data, apr_size_t len)
{
  const char *end = data + len;
  const char *p = data, *q;
  serf_bucket_t *tmp_bkt;

  while (1)
    {
      /* Find a character which needs to be quoted and append bytes up
         to that point.  Strictly speaking, '>' only needs to be
         quoted if it follows "]]", but it's easier to quote it all
         the time.

         So, why are we escaping '\r' here?  Well, according to the
         XML spec, '\r\n' gets converted to '\n' during XML parsing.
         Also, any '\r' not followed by '\n' is converted to '\n'.  By
         golly, if we say we want to escape a '\r', we want to make
         sure it remains a '\r'!  */
      q = p;
      while (q < end && *q != '&' && *q != '<' && *q != '>' && *q != '\r')
        q++;


      tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(p, q - p, bkt_alloc);
      serf_bucket_aggregate_append(agg_bucket, tmp_bkt);

      /* We may already be a winner.  */
      if (q == end)
        break;

      /* Append the entity reference for the character.  */
      if (*q == '&')
        {
          tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("&amp;", sizeof("&amp;") - 1,
                                                  bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp_bkt);
        }
      else if (*q == '<')
        {
          tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("&lt;", sizeof("&lt;") - 1,
                                                  bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp_bkt);
        }
      else if (*q == '>')
        {
          tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("&gt;", sizeof("&gt;") - 1,
                                                  bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp_bkt);
        }
      else if (*q == '\r')
        {
          tmp_bkt = SERF_BUCKET_SIMPLE_STRING_LEN("&#13;", sizeof("&#13;") - 1,
                                                  bkt_alloc);
          serf_bucket_aggregate_append(agg_bucket, tmp_bkt);
        }

      p = q + 1;
    }
}

void svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket, const char *tag,
                                  const char *value,
                                  serf_bucket_alloc_t *bkt_alloc)
{
  svn_ra_serf__add_open_tag_buckets(agg_bucket, bkt_alloc, tag, SVN_VA_NULL);

  if (value)
    {
      svn_ra_serf__add_cdata_len_buckets(agg_bucket, bkt_alloc,
                                         value, strlen(value));
    }

  svn_ra_serf__add_close_tag_buckets(agg_bucket, bkt_alloc, tag);
}

/* Return a pool for XES to use for self-alloc (and other specifics).  */
static apr_pool_t *
xes_pool(const svn_ra_serf__xml_estate_t *xes)
{
  /* Move up through parent states looking for one with a pool. This
     will always terminate since the initial state has a pool.  */
  while (xes->state_pool == NULL)
    xes = xes->prev;
  return xes->state_pool;
}


static void
ensure_pool(svn_ra_serf__xml_estate_t *xes)
{
  if (xes->state_pool == NULL)
    xes->state_pool = svn_pool_create(xes_pool(xes));
}


/* This callback is used by define_namespaces() to wait until a pool is
   required before constructing it.  */
static apr_pool_t *
lazy_create_pool(void *baton)
{
  svn_ra_serf__xml_estate_t *xes = baton;

  ensure_pool(xes);
  return xes->state_pool;
}

svn_error_t *
svn_ra_serf__xml_context_done(svn_ra_serf__xml_context_t *xmlctx)
{
  if (xmlctx->current->prev)
    {
      /* Probably unreachable as this would be an xml parser error */
      return svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
                               _("XML stream truncated: closing '%s' missing"),
                               xmlctx->current->tag.name);
    }
  else if (! xmlctx->free_states)
    {
      /* If we have no items on the free_states list, we didn't push anything,
         which tells us that we found an empty xml body */
      const svn_ra_serf__xml_transition_t *scan;
      const svn_ra_serf__xml_transition_t *document = NULL;
      const char *msg;

      for (scan = xmlctx->ttable; scan->ns != NULL; ++scan)
        {
          if (scan->from_state == XML_STATE_INITIAL)
            {
              if (document != NULL)
                {
                  document = NULL; /* Multiple document elements defined */
                  break;
                }
              document = scan;
            }
        }

      if (document)
        msg = apr_psprintf(xmlctx->scratch_pool, "'%s' element not found",
                            document->name);
      else
        msg = _("document element not found");

      return svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
                               _("XML stream truncated: %s"),
                               msg);
    }

  svn_pool_destroy(xmlctx->scratch_pool);
  return SVN_NO_ERROR;
}

svn_ra_serf__xml_context_t *
svn_ra_serf__xml_context_create(
  const svn_ra_serf__xml_transition_t *ttable,
  svn_ra_serf__xml_opened_t opened_cb,
  svn_ra_serf__xml_closed_t closed_cb,
  svn_ra_serf__xml_cdata_t cdata_cb,
  void *baton,
  apr_pool_t *result_pool)
{
  svn_ra_serf__xml_context_t *xmlctx;
  svn_ra_serf__xml_estate_t *xes;

  xmlctx = apr_pcalloc(result_pool, sizeof(*xmlctx));
  xmlctx->ttable = ttable;
  xmlctx->opened_cb = opened_cb;
  xmlctx->closed_cb = closed_cb;
  xmlctx->cdata_cb = cdata_cb;
  xmlctx->baton = baton;
  xmlctx->scratch_pool = svn_pool_create(result_pool);

  xes = apr_pcalloc(result_pool, sizeof(*xes));
  /* XES->STATE == 0  */

  /* Child states may use this pool to allocate themselves. If a child
     needs to collect information, then it will construct a subpool and
     will use that to allocate itself and its collected data.  */
  xes->state_pool = result_pool;

  xmlctx->current = xes;

  return xmlctx;
}


apr_hash_t *
svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
                              int stop_state)
{
  apr_hash_t *data;
  apr_pool_t *pool;

  ensure_pool(xes);
  pool = xes->state_pool;

  data = apr_hash_make(pool);

  for (; xes != NULL; xes = xes->prev)
    {
      if (xes->attrs != NULL)
        {
          apr_hash_index_t *hi;

          for (hi = apr_hash_first(pool, xes->attrs); hi;
               hi = apr_hash_next(hi))
            {
              const void *key;
              apr_ssize_t klen;
              void *val;

              /* Parent name/value lifetimes are at least as long as POOL.  */
              apr_hash_this(hi, &key, &klen, &val);
              apr_hash_set(data, key, klen, val);
            }
        }

      if (xes->state == stop_state)
        break;
    }

  return data;
}


void
svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
                      int state,
                      const char *name,
                      const char *value)
{
  svn_ra_serf__xml_estate_t *scan;

  for (scan = xes; scan != NULL && scan->state != state; scan = scan->prev)
    /* pass */ ;

  SVN_ERR_ASSERT_NO_RETURN(scan != NULL);

  /* Make sure the target state has a pool.  */
  ensure_pool(scan);

  /* ... and attribute storage.  */
  if (scan->attrs == NULL)
    scan->attrs = apr_hash_make(scan->state_pool);

  /* In all likelihood, NAME is a string constant. But we can't really
     be sure. And it isn't like we're storing a billion of these into
     the state pool.  */
  svn_hash_sets(scan->attrs,
                apr_pstrdup(scan->state_pool, name),
                apr_pstrdup(scan->state_pool, value));
}


apr_pool_t *
svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes)
{
  /* If they asked for a pool, then ensure that we have one to provide.  */
  ensure_pool(xes);

  return xes->state_pool;
}


static svn_error_t *
xml_cb_start(svn_ra_serf__xml_context_t *xmlctx,
             const char *raw_name,
             const char *const *attrs)
{
  svn_ra_serf__xml_estate_t *current = xmlctx->current;
  svn_ra_serf__dav_props_t elemname;
  const svn_ra_serf__xml_transition_t *scan;
  apr_pool_t *new_pool;
  svn_ra_serf__xml_estate_t *new_xes;

  /* If we're waiting for an element to close, then just ignore all
     other element-opens.  */
  if (xmlctx->waiting > 0)
    {
      xmlctx->waiting++;
      return SVN_NO_ERROR;
    }

  /* Look for xmlns: attributes. Lazily create the state pool if any
     were found.  */
  define_namespaces(&current->ns_list, attrs, lazy_create_pool, current);

  expand_ns(&elemname, current->ns_list, raw_name);

  for (scan = xmlctx->ttable; scan->ns != NULL; ++scan)
    {
      if (scan->from_state != current->state)
        continue;

      /* Wildcard tag match.  */
      if (*scan->name == '*')
        break;

      /* Found a specific transition.  */
      if (strcmp(elemname.name, scan->name) == 0
          && strcmp(elemname.xmlns, scan->ns) == 0)
        break;
    }
  if (scan->ns == NULL)
    {
      if (current->state == XML_STATE_INITIAL)
        {
          return svn_error_createf(
                        SVN_ERR_XML_UNEXPECTED_ELEMENT, NULL,
                        _("XML Parsing failed: Unexpected root element '%s'"),
                        elemname.name);
        }

      xmlctx->waiting++; /* Start waiting for the close tag */
      return SVN_NO_ERROR;
    }

  /* We should not be told to collect cdata if the closed_cb will not
     be called.  */
  SVN_ERR_ASSERT(!scan->collect_cdata || scan->custom_close);

  /* Found a transition. Make it happen.  */

  /* ### todo. push state  */

  /* ### how to use free states?  */
  /* This state should be allocated in the extent pool. If we will be
     collecting information for this state, then construct a subpool.

     ### potentially optimize away the subpool if none of the
     ### attributes are present. subpools are cheap, tho...  */
  new_pool = xes_pool(current);
  if (scan->collect_cdata || scan->collect_attrs[0])
    {
      new_pool = svn_pool_create(new_pool);

      /* Prep the new state.  */
      new_xes = apr_pcalloc(new_pool, sizeof(*new_xes));
      new_xes->state_pool = new_pool;

      /* If we're supposed to collect cdata, then set up a buffer for
         this. The existence of this buffer will instruct our cdata
         callback to collect the cdata.  */
      if (scan->collect_cdata)
        new_xes->cdata = svn_stringbuf_create_empty(new_pool);

      if (scan->collect_attrs[0] != NULL)
        {
          const char *const *saveattr = &scan->collect_attrs[0];

          new_xes->attrs = apr_hash_make(new_pool);
          for (; *saveattr != NULL; ++saveattr)
            {
              const char *name;
              const char *value;

              if (**saveattr == '?')
                {
                  name = *saveattr + 1;
                  value = svn_xml_get_attr_value(name, attrs);
                }
              else
                {
                  name = *saveattr;
                  value = svn_xml_get_attr_value(name, attrs);
                  if (value == NULL)
                    return svn_error_createf(
                                SVN_ERR_XML_ATTRIB_NOT_FOUND,
                                NULL,
                                _("Missing XML attribute '%s' on '%s' element"),
                                name, scan->name);
                }

              if (value)
                svn_hash_sets(new_xes->attrs, name,
                              apr_pstrdup(new_pool, value));
            }
        }
    }
  else
    {
      /* Prep the new state.  */
      new_xes = apr_pcalloc(new_pool, sizeof(*new_xes));
      /* STATE_POOL remains NULL.  */
    }

  /* Some basic copies to set up the new estate.  */
  new_xes->state = scan->to_state;
  new_xes->tag.name = apr_pstrdup(new_pool, elemname.name);
  new_xes->tag.xmlns = apr_pstrdup(new_pool, elemname.xmlns);
  new_xes->custom_close = scan->custom_close;

  /* Start with the parent's namespace set.  */
  new_xes->ns_list = current->ns_list;

  /* The new state is prepared. Make it current.  */
  new_xes->prev = current;
  xmlctx->current = new_xes;

  if (xmlctx->opened_cb)
    {
      START_CALLBACK(xmlctx);
      SVN_ERR(xmlctx->opened_cb(new_xes, xmlctx->baton,
                                new_xes->state, &new_xes->tag,
                                xmlctx->scratch_pool));
      END_CALLBACK(xmlctx);
      svn_pool_clear(xmlctx->scratch_pool);
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
xml_cb_end(svn_ra_serf__xml_context_t *xmlctx,
           const char *raw_name)
{
  svn_ra_serf__xml_estate_t *xes = xmlctx->current;

  if (xmlctx->waiting > 0)
    {
      xmlctx->waiting--;
      return SVN_NO_ERROR;
    }

  if (xes->custom_close)
    {
      const svn_string_t *cdata;

      if (xes->cdata)
        {
          cdata = svn_stringbuf__morph_into_string(xes->cdata);
#ifdef SVN_DEBUG
          /* We might toss the pool holding this structure, but it could also
             be within a parent pool. In any case, for safety's sake, disable
             the stringbuf against future Badness.  */
          xes->cdata->pool = NULL;
#endif
        }
      else
        cdata = NULL;

      START_CALLBACK(xmlctx);
      SVN_ERR(xmlctx->closed_cb(xes, xmlctx->baton, xes->state,
                                cdata, xes->attrs,
                                xmlctx->scratch_pool));
      END_CALLBACK(xmlctx);
      svn_pool_clear(xmlctx->scratch_pool);
    }

  /* Pop the state.  */
  xmlctx->current = xes->prev;

  /* ### not everything should go on the free state list. XES may go
     ### away with the state pool.  */
  xes->prev = xmlctx->free_states;
  xmlctx->free_states = xes;

  /* If there is a STATE_POOL, then toss it. This will get rid of as much
     memory as possible. Potentially the XES (if we didn't create a pool
     right away, then XES may be in a parent pool).  */
  if (xes->state_pool)
    svn_pool_destroy(xes->state_pool);

  return SVN_NO_ERROR;
}


static svn_error_t *
xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx,
             const char *data,
             apr_size_t len)
{
  /* If we are waiting for a closing tag, then we are uninterested in
     the cdata. Just return.  */
  if (xmlctx->waiting > 0)
    return SVN_NO_ERROR;

  /* If the current state is collecting cdata, then copy the cdata.  */
  if (xmlctx->current->cdata != NULL)
    {
      svn_stringbuf_appendbytes(xmlctx->current->cdata, data, len);
    }
  /* ... else if a CDATA_CB has been supplied, then invoke it for
     all states.  */
  else if (xmlctx->cdata_cb != NULL)
    {
      START_CALLBACK(xmlctx);
      SVN_ERR(xmlctx->cdata_cb(xmlctx->current,
                               xmlctx->baton,
                               xmlctx->current->state,
                               data, len,
                               xmlctx->scratch_pool));
      END_CALLBACK(xmlctx);
      svn_pool_clear(xmlctx->scratch_pool);
    }

  return SVN_NO_ERROR;
}

/* svn_error_t * wrapper around 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;

  if (*xmlp)
    {
      (void) XML_ParserFree(*xmlp);
      *xmlp = NULL;
    }

  return APR_SUCCESS;
}

/* Conforms to Expat's XML_StartElementHandler  */
static void
expat_start(void *userData, const char *raw_name, const char **attrs)
{
  struct expat_ctx_t *ectx = userData;

  if (ectx->inner_error != NULL)
    return;

  ectx->inner_error = 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
}


/* Conforms to Expat's XML_EndElementHandler  */
static void
expat_end(void *userData, const char *raw_name)
{
  struct expat_ctx_t *ectx = userData;

  if (ectx->inner_error != NULL)
    return;

  ectx->inner_error = 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
}


/* Conforms to Expat's XML_CharacterDataHandler  */
static void
expat_cdata(void *userData, const char *data, int len)
{
  struct expat_ctx_t *ectx = userData;

  if (ectx->inner_error != NULL)
    return;

  ectx->inner_error = 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
}


/* Implements svn_ra_serf__response_handler_t */
static svn_error_t *
expat_response_handler(serf_request_t *request,
                       serf_bucket_t *response,
                       void *baton,
                       apr_pool_t *scratch_pool)
{
  struct expat_ctx_t *ectx = baton;
  svn_boolean_t got_expected_status;

  if (ectx->expected_status)
    {
      const int *status = ectx->expected_status;
      got_expected_status = FALSE;

      while (*status && ectx->handler->sline.code != *status)
        status++;

      got_expected_status = (*status) != 0;
    }
  else
    got_expected_status = (ectx->handler->sline.code == 200);

  if (!ectx->handler->server_error
      && ((ectx->handler->sline.code < 200) || (ectx->handler->sline.code >= 300)
          || ! got_expected_status))
    {
      /* By deferring to expect_empty_body(), it will make a choice on
         how to handle the body. Whatever the decision, the core handler
         will take over, and we will not be called again.  */

      /* ### This handles xml bodies as svn-errors (returned via serf context
         ### loop), but ignores non-xml errors.

         Current code depends on this behavior and checks itself while other
         continues, and then verifies if work has been performed.

         ### TODO: Make error checking consistent */

      /* ### If !GOT_EXPECTED_STATUS, this should always produce an error */
      return svn_error_trace(svn_ra_serf__expect_empty_body(
                               request, response, ectx->handler,
                               scratch_pool));
    }

  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);
    }

  while (1)
    {
      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);
      if (SERF_BUCKET_READ_ERROR(status))
        return svn_ra_serf__wrap_err(status, NULL);
      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);

      /* The parsing went fine. What has the bucket told us?  */
      if (at_eof)
        {
          /* Make sure we actually got xml and clean up after parsing */
          SVN_ERR(svn_ra_serf__xml_context_done(ectx->xmlctx));
        }

      if (status && !SERF_BUCKET_READ_ERROR(status))
        {
          return svn_ra_serf__wrap_err(status, NULL);
        }
    }

  /* NOTREACHED */
}


svn_ra_serf__handler_t *
svn_ra_serf__create_expat_handler(svn_ra_serf__session_t *session,
                                  svn_ra_serf__xml_context_t *xmlctx,
                                  const int *expected_status,
                                  apr_pool_t *result_pool)
{
  svn_ra_serf__handler_t *handler;
  struct expat_ctx_t *ectx;

  ectx = apr_pcalloc(result_pool, sizeof(*ectx));
  ectx->xmlctx = xmlctx;
  ectx->parser = NULL;
  ectx->expected_status = expected_status;
  ectx->cleanup_pool = result_pool;

  handler = svn_ra_serf__create_handler(session, result_pool);
  handler->response_handler = expat_response_handler;
  handler->response_baton = ectx;

  ectx->handler = handler;

  return handler;
}
