Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/CHANGES  view on Meta::CPAN

 * miscellaneous small code cleanups
 * bug fixes: more valgrind memory bugs, apr xlate i18n mess (#872),
   non-existent URL checkout (#946), props on to-be-deleted files (#1066),
   ra_svn move/copy (#1084), eol translation (#1085), ra_svn
   checksumming (#1099), cat command corrupt output (#1104), cvs2svn
   memory consumption (#1107), merge of property add (#1109),
   '..' relative path (#1111), commit/cleanup/diff3 (#1119),
   .svn/entries checksum (#1120), svn commit in / (#1122),
   status on uncontrolled directory (#1124), commit message eol
   characters (#1126), cat -r PREV (#1134), ra_dav wcprops (#1136)
   split XML cdata/attribute encoding (#1118)


Version 0.17.1 (released 22 Jan 2003, revision 4503, branches/0.17.1)

 User-visible changes:
 * changed non-baseline build version number display.
 * compatibility change: make sure old clients can talk to newest servers.
 * some changes to the Book

 Developer-visible changes:

src/subversion/subversion/include/svn_xml.h  view on Meta::CPAN


/** The namespace all Subversion XML uses. */
#define SVN_XML_NAMESPACE "svn:"

/** Used as style argument to svn_xml_make_open_tag() and friends. */
enum svn_xml_open_tag_style {
  /** <tag ...> */
  svn_xml_normal = 1,

  /** <tag ...>, no cosmetic newline */
  svn_xml_protect_pcdata,

  /** <tag .../>  */
  svn_xml_self_closing
};



/** Determine if a string of character @a data of length @a len is a
 * safe bet for use with the svn_xml_escape_* functions found in this
 * header.

src/subversion/subversion/include/svn_xml.h  view on Meta::CPAN

svn_xml_is_xml_safe(const char *data,
                    apr_size_t len);

/** Create or append in @a *outstr an xml-escaped version of @a string,
 * suitable for output as character data.
 *
 * If @a *outstr is @c NULL, set @a *outstr to a new stringbuf allocated
 * in @a pool, else append to the existing stringbuf there.
 */
void
svn_xml_escape_cdata_stringbuf(svn_stringbuf_t **outstr,
                               const svn_stringbuf_t *string,
                               apr_pool_t *pool);

/** Same as svn_xml_escape_cdata_stringbuf(), but @a string is an
 * @c svn_string_t.
 */
void
svn_xml_escape_cdata_string(svn_stringbuf_t **outstr,
                            const svn_string_t *string,
                            apr_pool_t *pool);

/** Same as svn_xml_escape_cdata_stringbuf(), but @a string is a
 * NULL-terminated C string.
 */
void
svn_xml_escape_cdata_cstring(svn_stringbuf_t **outstr,
                             const char *string,
                             apr_pool_t *pool);


/** Create or append in @a *outstr an xml-escaped version of @a string,
 * suitable for output as an attribute value.
 *
 * If @a *outstr is @c NULL, set @a *outstr to a new stringbuf allocated
 * in @a pool, else append to the existing stringbuf there.
 */

src/subversion/subversion/libsvn_ra_serf/blame.c  view on Meta::CPAN

  svn_revnum_t start;
  svn_revnum_t end;
  svn_boolean_t include_merged_revisions;

  /* blame handler and baton */
  svn_file_rev_handler_t file_rev;
  void *file_rev_baton;

  /* As we parse each FILE_REV, we collect data in these variables:
     property changes and new content.  STREAM is valid when we're
     in the TXDELTA state, processing the incoming cdata.  */
  apr_hash_t *rev_props;
  apr_array_header_t *prop_diffs;
  apr_pool_t *state_pool;  /* put property stuff in here  */

  svn_stream_t *stream;

} blame_context_t;


#define D_ "DAV:"

src/subversion/subversion/libsvn_ra_serf/blame.c  view on Meta::CPAN


  return SVN_NO_ERROR;
}


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
blame_closed(svn_ra_serf__xml_estate_t *xes,
             void *baton,
             int leaving_state,
             const svn_string_t *cdata,
             apr_hash_t *attrs,
             apr_pool_t *scratch_pool)
{
  blame_context_t *blame_ctx = baton;

  if (leaving_state == FILE_REV)
    {
      /* Note that we test STREAM, but any pointer is currently invalid.
         It was closed when left the TXDELTA state.  */
      if (blame_ctx->stream == NULL)

src/subversion/subversion/libsvn_ra_serf/blame.c  view on Meta::CPAN


      if (leaving_state == REMOVE_PROP)
        {
          value = NULL;
        }
      else
        {
          const char *encoding = svn_hash_gets(attrs, "encoding");

          if (encoding && strcmp(encoding, "base64") == 0)
            value = svn_base64_decode_string(cdata, blame_ctx->state_pool);
          else
            value = svn_string_dup(cdata, blame_ctx->state_pool);
        }

      if (leaving_state == REV_PROP)
        {
          svn_hash_sets(blame_ctx->rev_props, name, value);
        }
      else
        {
          svn_prop_t *prop = apr_array_push(blame_ctx->prop_diffs);

          prop->name = name;
          prop->value = value;
        }
    }

  return SVN_NO_ERROR;
}


/* Conforms to svn_ra_serf__xml_cdata_t  */
static svn_error_t *
blame_cdata(svn_ra_serf__xml_estate_t *xes,
            void *baton,
            int current_state,
            const char *data,
            apr_size_t len,
            apr_pool_t *scratch_pool)
{
  blame_context_t *blame_ctx = baton;

  if (current_state == TXDELTA)
    {

src/subversion/subversion/libsvn_ra_serf/blame.c  view on Meta::CPAN

  blame_ctx->include_merged_revisions = include_merged_revisions;

  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                      session, NULL /* conn */,
                                      NULL /* url */, end,
                                      pool, pool));

  xmlctx = svn_ra_serf__xml_context_create(blame_ttable,
                                           blame_opened,
                                           blame_closed,
                                           blame_cdata,
                                           blame_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);

  handler->method = "REPORT";
  handler->path = req_url;
  handler->body_type = "text/xml";
  handler->body_delegate = create_file_revs_body;
  handler->body_delegate_baton = blame_ctx;
  handler->conn = session->conns[0];

src/subversion/subversion/libsvn_ra_serf/commit.c  view on Meta::CPAN

  body_bkt = serf_bucket_aggregate_create(alloc);

  svn_ra_serf__add_xml_header_buckets(body_bkt, alloc);
  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:checkout",
                                    "xmlns:D", "DAV:",
                                    NULL);
  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:activity-set", NULL);
  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:href", NULL);

  SVN_ERR_ASSERT(activity_url != NULL);
  svn_ra_serf__add_cdata_len_buckets(body_bkt, alloc,
                                     activity_url,
                                     strlen(activity_url));

  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href");
  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:activity-set");
  svn_ra_serf__add_tag_buckets(body_bkt, "D:apply-to-version", NULL, alloc);
  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:checkout");

  *bkt = body_bkt;
  return SVN_NO_ERROR;

src/subversion/subversion/libsvn_ra_serf/commit.c  view on Meta::CPAN

                  _("File '%s' is out of date; try updating"),
                  svn_dirent_local_style(file->relpath, scratch_pool)));
      return err;
    }

  return SVN_NO_ERROR;
}

/* Helper function for proppatch_walker() below. */
static svn_error_t *
get_encoding_and_cdata(const char **encoding_p,
                       const svn_string_t **encoded_value_p,
                       serf_bucket_alloc_t *alloc,
                       const svn_string_t *value,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  if (value == NULL)
    {
      *encoding_p = NULL;
      *encoded_value_p = NULL;
      return SVN_NO_ERROR;
    }

  /* If a property is XML-safe, XML-encode it.  Else, base64-encode
     it. */
  if (svn_xml_is_xml_safe(value->data, value->len))
    {
      svn_stringbuf_t *xml_esc = NULL;
      svn_xml_escape_cdata_string(&xml_esc, value, scratch_pool);
      *encoding_p = NULL;
      *encoded_value_p = svn_string_create_from_buf(xml_esc, result_pool);
    }
  else
    {
      *encoding_p = "base64";
      *encoded_value_p = svn_base64_encode_string2(value, TRUE, result_pool);
    }

  return SVN_NO_ERROR;

src/subversion/subversion/libsvn_ra_serf/commit.c  view on Meta::CPAN


static svn_error_t *
proppatch_walker(void *baton,
                 const char *ns,
                 const char *name,
                 const svn_string_t *val,
                 apr_pool_t *scratch_pool)
{
  walker_baton_t *wb = baton;
  serf_bucket_t *body_bkt = wb->body_bkt;
  serf_bucket_t *cdata_bkt;
  serf_bucket_alloc_t *alloc;
  const char *encoding;
  svn_boolean_t have_old_val;
  const svn_string_t *old_val;
  const svn_string_t *encoded_value;
  const char *prop_name;

  SVN_ERR(derive_old_val(&have_old_val, &old_val, wb, ns, name));

  /* Jump through hoops to work with D:remove and its val = (""-for-NULL)

src/subversion/subversion/libsvn_ra_serf/commit.c  view on Meta::CPAN

      if (wb->filter == filter_props_with_old_value && ! have_old_val)
      	return SVN_NO_ERROR;
      if (wb->filter == filter_props_without_old_value && have_old_val)
      	return SVN_NO_ERROR;
    }
  if (wb->deleting)
    val = NULL;

  alloc = body_bkt->allocator;

  SVN_ERR(get_encoding_and_cdata(&encoding, &encoded_value, alloc, val,
                                 wb->body_pool, scratch_pool));
  if (encoded_value)
    {
      cdata_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(encoded_value->data,
                                                encoded_value->len,
                                                alloc);
    }
  else
    {
      cdata_bkt = NULL;
    }

  /* Use the namespace prefix instead of adding the xmlns attribute to support
     property names containing ':' */
  if (strcmp(ns, SVN_DAV_PROP_NS_SVN) == 0)
    prop_name = apr_pstrcat(wb->body_pool, "S:", name, (char *)NULL);
  else if (strcmp(ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
    prop_name = apr_pstrcat(wb->body_pool, "C:", name, (char *)NULL);

  if (cdata_bkt)
    svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, prop_name,
                                      "V:encoding", encoding,
                                      NULL);
  else
    svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, prop_name,
                                      "V:" SVN_DAV__OLD_VALUE__ABSENT, "1",
                                      NULL);

  if (have_old_val)
    {
      const char *encoding2;
      const svn_string_t *encoded_value2;
      serf_bucket_t *cdata_bkt2;

      SVN_ERR(get_encoding_and_cdata(&encoding2, &encoded_value2,
                                     alloc, old_val,
                                     wb->body_pool, scratch_pool));

      if (encoded_value2)
        {
          cdata_bkt2 = SERF_BUCKET_SIMPLE_STRING_LEN(encoded_value2->data,
                                                     encoded_value2->len,
                                                     alloc);
        }
      else
        {
          cdata_bkt2 = NULL;
        }

      if (cdata_bkt2)
        svn_ra_serf__add_open_tag_buckets(body_bkt, alloc,
                                          "V:" SVN_DAV__OLD_VALUE,
                                          "V:encoding", encoding2,
                                          NULL);
      else
        svn_ra_serf__add_open_tag_buckets(body_bkt, alloc,
                                          "V:" SVN_DAV__OLD_VALUE,
                                          "V:" SVN_DAV__OLD_VALUE__ABSENT, "1",
                                          NULL);

      if (cdata_bkt2)
        serf_bucket_aggregate_append(body_bkt, cdata_bkt2);

      svn_ra_serf__add_close_tag_buckets(body_bkt, alloc,
                                         "V:" SVN_DAV__OLD_VALUE);
    }
  if (cdata_bkt)
    serf_bucket_aggregate_append(body_bkt, cdata_bkt);
  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, prop_name);

  return SVN_NO_ERROR;
}

/* Possible add the lock-token "If:" precondition header to HEADERS if
   an examination of COMMIT_CTX and RELPATH indicates that this is the
   right thing to do.

   Generally speaking, if the client provided a lock token for

src/subversion/subversion/libsvn_ra_serf/get_deleted_rev.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
getdrev_closed(svn_ra_serf__xml_estate_t *xes,
               void *baton,
               int leaving_state,
               const svn_string_t *cdata,
               apr_hash_t *attrs,
               apr_pool_t *scratch_pool)
{
  drev_context_t *drev_ctx = baton;

  SVN_ERR_ASSERT(leaving_state == VERSION_NAME);
  SVN_ERR_ASSERT(cdata != NULL);

  *drev_ctx->revision_deleted = SVN_STR_TO_REV(cdata->data);

  return SVN_NO_ERROR;
}


/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_getdrev_body(serf_bucket_t **body_bkt,
                    void *baton,
                    serf_bucket_alloc_t *alloc,

src/subversion/subversion/libsvn_ra_serf/getdate.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
date_closed(svn_ra_serf__xml_estate_t *xes,
            void *baton,
            int leaving_state,
            const svn_string_t *cdata,
            apr_hash_t *attrs,
            apr_pool_t *scratch_pool)
{
  date_context_t *date_ctx = baton;

  SVN_ERR_ASSERT(leaving_state == VERSION_NAME);
  SVN_ERR_ASSERT(cdata != NULL);

  *date_ctx->revision = SVN_STR_TO_REV(cdata->data);

  return SVN_NO_ERROR;
}


/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_getdate_body(serf_bucket_t **body_bkt,
                    void *baton,
                    serf_bucket_alloc_t *alloc,

src/subversion/subversion/libsvn_ra_serf/getlocations.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
getloc_closed(svn_ra_serf__xml_estate_t *xes,
              void *baton,
              int leaving_state,
              const svn_string_t *cdata,
              apr_hash_t *attrs,
              apr_pool_t *scratch_pool)
{
  loc_context_t *loc_ctx = baton;
  const char *revstr;
  const char *path;

  SVN_ERR_ASSERT(leaving_state == LOCATION);

  revstr = svn_hash_gets(attrs, "rev");

src/subversion/subversion/libsvn_ra_serf/getlocationsegments.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
gls_closed(svn_ra_serf__xml_estate_t *xes,
           void *baton,
           int leaving_state,
           const svn_string_t *cdata,
           apr_hash_t *attrs,
           apr_pool_t *scratch_pool)
{
  gls_context_t *gls_ctx = baton;
  const char *path;
  const char *start_str;
  const char *end_str;
  svn_location_segment_t segment;

  SVN_ERR_ASSERT(leaving_state == SEGMENT);

src/subversion/subversion/libsvn_ra_serf/getlocks.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
getlocks_closed(svn_ra_serf__xml_estate_t *xes,
                void *baton,
                int leaving_state,
                const svn_string_t *cdata,
                apr_hash_t *attrs,
                apr_pool_t *scratch_pool)
{
  lock_context_t *lock_ctx = baton;

  if (leaving_state == LOCK)
    {
      const char *path = svn_hash_gets(attrs, "path");
      const char *token = svn_hash_gets(attrs, "token");
      svn_boolean_t save_lock = FALSE;

src/subversion/subversion/libsvn_ra_serf/getlocks.c  view on Meta::CPAN

                                          scratch_pool));

          result_lock = svn_lock_dup(&lock, lock_ctx->pool);
          svn_hash_sets(lock_ctx->hash, result_lock->path, result_lock);
        }
    }
  else
    {
      const char *name;

      SVN_ERR_ASSERT(cdata != NULL);

      if (leaving_state == PATH)
        name = "path";
      else if (leaving_state == TOKEN)
        name = "token";
      else if (leaving_state == OWNER)
        name = "owner";
      else if (leaving_state == COMMENT)
        name = "comment";
      else if (leaving_state == CREATION_DATE)
        name = SVN_DAV__CREATIONDATE;
      else if (leaving_state == EXPIRATION_DATE)
        name = "expirationdate";
      else
        SVN_ERR_MALFUNCTION();

      /* Store the lock information onto the LOCK elemstate.  */
      svn_ra_serf__xml_note(xes, LOCK, name, cdata->data);
    }

  return SVN_NO_ERROR;
}


/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_getlocks_body(serf_bucket_t **body_bkt,
                     void *baton,

src/subversion/subversion/libsvn_ra_serf/inherited_props.c  view on Meta::CPAN

      iprops_ctx->curr_iprop->prop_hash = apr_hash_make(iprops_ctx->pool);
    }
  return SVN_NO_ERROR;
}

/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
iprops_closed(svn_ra_serf__xml_estate_t *xes,
              void *baton,
              int leaving_state,
              const svn_string_t *cdata,
              apr_hash_t *attrs,
              apr_pool_t *scratch_pool)
{
  iprops_context_t *iprops_ctx = baton;

  if (leaving_state == IPROPS_ITEM)
    {
      APR_ARRAY_PUSH(iprops_ctx->iprops, svn_prop_inherited_item_t *) =
        iprops_ctx->curr_iprop;

      iprops_ctx->curr_iprop = NULL;
    }
  else if (leaving_state == IPROPS_PATH)
    {
      /* Every <iprop-item> has a single <iprop-path> */
      if (iprops_ctx->curr_iprop->path_or_url)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      iprops_ctx->curr_iprop->path_or_url =
        svn_path_url_add_component2(iprops_ctx->repos_root_url,
                                    cdata->data,
                                    iprops_ctx->pool);
    }
  else if (leaving_state == IPROPS_PROPNAME)
    {
      if (iprops_ctx->curr_propname->len)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      /* Store propname for value */
      svn_stringbuf_set(iprops_ctx->curr_propname, cdata->data);
    }
  else if (leaving_state == IPROPS_PROPVAL)
    {
      const char *encoding;
      const svn_string_t *val_str;

      if (! iprops_ctx->curr_propname->len)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      encoding = svn_hash_gets(attrs, "V:encoding");

      if (encoding)
        {
          if (strcmp(encoding, "base64") != 0)
            return svn_error_createf(SVN_ERR_XML_MALFORMED,
                                     NULL,
                                     _("Got unrecognized encoding '%s'"),
                                     encoding);

          /* Decode into the right pool.  */
          val_str = svn_base64_decode_string(cdata, iprops_ctx->pool);
        }
      else
        {
          /* Copy into the right pool.  */
          val_str = svn_string_dup(cdata, iprops_ctx->pool);
        }

      svn_hash_sets(iprops_ctx->curr_iprop->prop_hash,
                    apr_pstrdup(iprops_ctx->pool,
                                iprops_ctx->curr_propname->data),
                    val_str);
      /* Clear current propname. */
      svn_stringbuf_setempty(iprops_ctx->curr_propname);
    }
  else

src/subversion/subversion/libsvn_ra_serf/locks.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
locks_closed(svn_ra_serf__xml_estate_t *xes,
             void *baton,
             int leaving_state,
             const svn_string_t *cdata,
             apr_hash_t *attrs,
             apr_pool_t *scratch_pool)
{
  lock_info_t *lock_ctx = baton;

  if (leaving_state == TIMEOUT)
    {
      if (strcasecmp(cdata->data, "Infinite") == 0)
        lock_ctx->lock->expiration_date = 0;
      else if (strncasecmp(cdata->data, "Second-", 7) == 0)
        {
          unsigned n;
          SVN_ERR(svn_cstring_atoui(&n, cdata->data+7));

          lock_ctx->lock->expiration_date = apr_time_now() +
                                            apr_time_from_sec(n);
        }
      else
        return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                 _("Invalid LOCK timeout value '%s'"),
                                 cdata->data);
    }
  else if (leaving_state == HREF)
    {
      if (cdata->len)
        {
          char *buf = apr_pstrmemdup(lock_ctx->pool, cdata->data, cdata->len);

          apr_collapse_spaces(buf, buf);
          lock_ctx->lock->token = buf;
        }
    }
  else if (leaving_state == OWNER)
    {
      if (cdata->len)
        {
          lock_ctx->lock->comment = apr_pstrmemdup(lock_ctx->pool,
                                                   cdata->data, cdata->len);
        }
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
set_lock_headers(serf_bucket_t *headers,
                 void *baton,

src/subversion/subversion/libsvn_ra_serf/log.c  view on Meta::CPAN

};


/* Store CDATA into REVPROPS, associated with PROPNAME. If ENCODING is not
   NULL, then it must base "base64" and CDATA will be decoded first.

   NOTE: PROPNAME must live longer than REVPROPS.  */
static svn_error_t *
collect_revprop(apr_hash_t *revprops,
                const char *propname,
                const svn_string_t *cdata,
                const char *encoding)
{
  apr_pool_t *result_pool = apr_hash_pool_get(revprops);
  const svn_string_t *decoded;

  if (encoding)
    {
      /* Check for a known encoding type.  This is easy -- there's
         only one.  */
      if (strcmp(encoding, "base64") != 0)
        {
          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                   _("Unsupported encoding '%s'"),
                                   encoding);
        }

      decoded = svn_base64_decode_string(cdata, result_pool);
    }
  else
    {
      decoded = svn_string_dup(cdata, result_pool);
    }

  /* Caller has ensured PROPNAME has sufficient lifetime.  */
  svn_hash_sets(revprops, propname, decoded);

  return SVN_NO_ERROR;
}


/* Record ACTION on the path in CDATA into PATHS. Other properties about
   the action are pulled from ATTRS.  */
static svn_error_t *
collect_path(apr_hash_t *paths,
             char action,
             const svn_string_t *cdata,
             apr_hash_t *attrs)
{
  apr_pool_t *result_pool = apr_hash_pool_get(paths);
  svn_log_changed_path2_t *lcp;
  const char *copyfrom_path;
  const char *copyfrom_rev;
  const char *path;

  lcp = svn_log_changed_path2_create(result_pool);
  lcp->action = action;

src/subversion/subversion/libsvn_ra_serf/log.c  view on Meta::CPAN

          lcp->copyfrom_rev = rev;
        }
    }

  lcp->node_kind = svn_node_kind_from_word(svn_hash_gets(attrs, "node-kind"));
  lcp->text_modified = svn_tristate__from_word(svn_hash_gets(attrs,
                                                             "text-mods"));
  lcp->props_modified = svn_tristate__from_word(svn_hash_gets(attrs,
                                                              "prop-mods"));

  path = apr_pstrmemdup(result_pool, cdata->data, cdata->len);
  svn_hash_sets(paths, path, lcp);

  return SVN_NO_ERROR;
}


/* Conforms to svn_ra_serf__xml_opened_t  */
static svn_error_t *
log_opened(svn_ra_serf__xml_estate_t *xes,
           void *baton,

src/subversion/subversion/libsvn_ra_serf/log.c  view on Meta::CPAN


  return SVN_NO_ERROR;
}


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
log_closed(svn_ra_serf__xml_estate_t *xes,
           void *baton,
           int leaving_state,
           const svn_string_t *cdata,
           apr_hash_t *attrs,
           apr_pool_t *scratch_pool)
{
  log_context_t *log_ctx = baton;

  if (leaving_state == ITEM)
    {
      svn_log_entry_t *log_entry;
      const char *rev_str;

src/subversion/subversion/libsvn_ra_serf/log.c  view on Meta::CPAN

        }

      /* These hash tables are going to be unusable once this state's
         pool is destroyed. But let's not leave stale pointers in
         structures that have a longer life.  */
      log_ctx->collect_revprops = NULL;
      log_ctx->collect_paths = NULL;
    }
  else if (leaving_state == VERSION)
    {
      svn_ra_serf__xml_note(xes, ITEM, "revision", cdata->data);
    }
  else if (leaving_state == CREATOR)
    {
      if (log_ctx->want_author)
        {
          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
                                  SVN_PROP_REVISION_AUTHOR,
                                  cdata,
                                  svn_hash_gets(attrs, "encoding")));
        }
    }
  else if (leaving_state == DATE)
    {
      if (log_ctx->want_date)
        {
          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
                                  SVN_PROP_REVISION_DATE,
                                  cdata,
                                  svn_hash_gets(attrs, "encoding")));
        }
    }
  else if (leaving_state == COMMENT)
    {
      if (log_ctx->want_message)
        {
          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
                                  SVN_PROP_REVISION_LOG,
                                  cdata,
                                  svn_hash_gets(attrs, "encoding")));
        }
    }
  else if (leaving_state == REVPROP)
    {
      apr_pool_t *result_pool = apr_hash_pool_get(log_ctx->collect_revprops);

      SVN_ERR(collect_revprop(
                log_ctx->collect_revprops,
                apr_pstrdup(result_pool,
                            svn_hash_gets(attrs, "name")),
                cdata,
                svn_hash_gets(attrs, "encoding")
                ));
    }
  else if (leaving_state == HAS_CHILDREN)
    {
      svn_ra_serf__xml_note(xes, ITEM, "has-children", "yes");
    }
  else if (leaving_state == SUBTRACTIVE_MERGE)
    {
      svn_ra_serf__xml_note(xes, ITEM, "subtractive-merge", "yes");

src/subversion/subversion/libsvn_ra_serf/log.c  view on Meta::CPAN

      else if (leaving_state == REPLACED_PATH)
        action = 'R';
      else if (leaving_state == DELETED_PATH)
        action = 'D';
      else
        {
          SVN_ERR_ASSERT(leaving_state == MODIFIED_PATH);
          action = 'M';
        }

      SVN_ERR(collect_path(log_ctx->collect_paths, action, cdata, attrs));
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
create_log_body(serf_bucket_t **body_bkt,
                void *baton,
                serf_bucket_alloc_t *alloc,

src/subversion/subversion/libsvn_ra_serf/merge.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
merge_closed(svn_ra_serf__xml_estate_t *xes,
             void *baton,
             int leaving_state,
             const svn_string_t *cdata,
             apr_hash_t *attrs,
             apr_pool_t *scratch_pool)
{
  merge_context_t *merge_ctx = baton;

  if (leaving_state == RESPONSE)
    {
      const char *rtype;

      rtype = svn_hash_gets(attrs, "resourcetype");

src/subversion/subversion/libsvn_ra_serf/merge.c  view on Meta::CPAN

    {
      svn_ra_serf__xml_note(xes, RESPONSE, "resourcetype", "baseline");
    }
  else if (leaving_state == COLLECTION)
    {
      svn_ra_serf__xml_note(xes, RESPONSE, "resourcetype", "collection");
    }
  else
    {
      const char *name;
      const char *value = cdata->data;

      if (leaving_state == HREF)
        {
          name = "href";
          value = svn_urlpath__canonicalize(value, scratch_pool);
        }
      else if (leaving_state == CHECKED_IN)
        {
          name = "checked-in";
          value = svn_urlpath__canonicalize(value, scratch_pool);

src/subversion/subversion/libsvn_ra_serf/merge.c  view on Meta::CPAN


      path.data = key;
      path.len = klen;

      if (parent && !svn_relpath_skip_ancestor(parent, key))
        continue;

      svn_ra_serf__add_open_tag_buckets(body, alloc, "S:lock", NULL);

      svn_ra_serf__add_open_tag_buckets(body, alloc, "lock-path", NULL);
      svn_ra_serf__add_cdata_len_buckets(body, alloc, path.data, path.len);
      svn_ra_serf__add_close_tag_buckets(body, alloc, "lock-path");

      svn_ra_serf__add_tag_buckets(body, "lock-token", val, alloc);

      svn_ra_serf__add_close_tag_buckets(body, alloc, "S:lock");
    }

  svn_ra_serf__add_close_tag_buckets(body, alloc, "S:lock-token-list");
}

src/subversion/subversion/libsvn_ra_serf/merge.c  view on Meta::CPAN


  body_bkt = serf_bucket_aggregate_create(alloc);

  svn_ra_serf__add_xml_header_buckets(body_bkt, alloc);
  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:merge",
                                    "xmlns:D", "DAV:",
                                    NULL);
  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:source", NULL);
  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:href", NULL);

  svn_ra_serf__add_cdata_len_buckets(body_bkt, alloc,
                                     ctx->merge_resource_url,
                                     strlen(ctx->merge_resource_url));

  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href");
  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:source");

  svn_ra_serf__add_tag_buckets(body_bkt, "D:no-auto-merge", NULL, alloc);
  svn_ra_serf__add_tag_buckets(body_bkt, "D:no-checkout", NULL, alloc);

  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop", NULL);

src/subversion/subversion/libsvn_ra_serf/mergeinfo.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
mergeinfo_closed(svn_ra_serf__xml_estate_t *xes,
                 void *baton,
                 int leaving_state,
                 const svn_string_t *cdata,
                 apr_hash_t *attrs,
                 apr_pool_t *scratch_pool)
{
  mergeinfo_context_t *mergeinfo_ctx = baton;

  if (leaving_state == MERGEINFO_ITEM)
    {
      /* Placed here from the child elements.  */
      const char *path = svn_hash_gets(attrs, "path");
      const char *info = svn_hash_gets(attrs, "info");

src/subversion/subversion/libsvn_ra_serf/mergeinfo.c  view on Meta::CPAN

  else
    {
      SVN_ERR_ASSERT(leaving_state == MERGEINFO_PATH
                     || leaving_state == MERGEINFO_INFO);

      /* Stash the value onto the parent MERGEINFO_ITEM.  */
      svn_ra_serf__xml_note(xes, MERGEINFO_ITEM,
                            leaving_state == MERGEINFO_PATH
                              ? "path"
                              : "info",
                            cdata->data);
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
create_mergeinfo_body(serf_bucket_t **bkt,
                      void *baton,
                      serf_bucket_alloc_t *alloc,

src/subversion/subversion/libsvn_ra_serf/options.c  view on Meta::CPAN


  { 0 }
};


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
options_closed(svn_ra_serf__xml_estate_t *xes,
               void *baton,
               int leaving_state,
               const svn_string_t *cdata,
               apr_hash_t *attrs,
               apr_pool_t *scratch_pool)
{
  options_context_t *opt_ctx = baton;

  SVN_ERR_ASSERT(leaving_state == HREF);
  SVN_ERR_ASSERT(cdata != NULL);

  opt_ctx->activity_collection = svn_urlpath__canonicalize(cdata->data,
                                                           opt_ctx->pool);

  return SVN_NO_ERROR;
}


static svn_error_t *
create_options_body(serf_bucket_t **body_bkt,
                    void *baton,
                    serf_bucket_alloc_t *alloc,

src/subversion/subversion/libsvn_ra_serf/property.c  view on Meta::CPAN


  return SVN_NO_ERROR;
}


/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
propfind_closed(svn_ra_serf__xml_estate_t *xes,
                void *baton,
                int leaving_state,
                const svn_string_t *cdata,
                apr_hash_t *attrs,
                apr_pool_t *scratch_pool)
{
  propfind_context_t *ctx = baton;

  if (leaving_state == MULTISTATUS)
    {
      /* We've gathered all the data from the reponse. Add this item
         onto the "done list". External callers will then know this
         request has been completed (tho stray response bytes may still

src/subversion/subversion/libsvn_ra_serf/property.c  view on Meta::CPAN

          ctx->done_item.next = *ctx->done_list;
          *ctx->done_list = &ctx->done_item;
        }
    }
  else if (leaving_state == HREF)
    {
      const char *path;
      const svn_string_t *val_str;

      if (strcmp(ctx->depth, "1") == 0)
        path = svn_urlpath__canonicalize(cdata->data, scratch_pool);
      else
        path = ctx->path;

      svn_ra_serf__xml_note(xes, RESPONSE, "path", path);

      /* Copy the value into the right pool, then save the HREF.  */
      val_str = svn_string_dup(cdata, ctx->pool);
      svn_ra_serf__set_ver_prop(ctx->ret_props,
                                path, ctx->rev, D_, "href", val_str,
                                ctx->pool);
    }
  else if (leaving_state == COLLECTION)
    {
      svn_ra_serf__xml_note(xes, PROPVAL, "altvalue", "collection");
    }
  else if (leaving_state == HREF_VALUE)
    {
      svn_ra_serf__xml_note(xes, PROPVAL, "altvalue", cdata->data);
    }
  else if (leaving_state == STATUS)
    {
      /* Parse the status field, and remember if this is a property
         that we wish to ignore.  (Typically, if it's not a 200, the
         status will be 404 to indicate that a property we
         specifically requested from the server doesn't exist.)  */
      int status = parse_status_code(cdata->data);
      if (status != 200)
        svn_ra_serf__xml_note(xes, PROPSTAT, "ignore-prop", "*");
    }
  else if (leaving_state == PROPVAL)
    {
      const char *encoding = svn_hash_gets(attrs, "V:encoding");
      const svn_string_t *val_str;
      apr_hash_t *gathered;
      const char *path;
      const char *ns;

src/subversion/subversion/libsvn_ra_serf/property.c  view on Meta::CPAN


      if (encoding)
        {
          if (strcmp(encoding, "base64") != 0)
            return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
                                     NULL,
                                     _("Got unrecognized encoding '%s'"),
                                     encoding);

          /* Decode into the right pool.  */
          val_str = svn_base64_decode_string(cdata, ctx->pool);
        }
      else
        {
          /* Copy into the right pool.  */
          val_str = svn_string_dup(cdata, ctx->pool);
        }

      /* The current path sits on the RESPONSE state. Gather up all the
         state from this PROPVAL to the (grandparent) RESPONSE state,
         and grab the path from there.

         Now, it would be nice if we could, at this point, know that
         the status code for this property indicated a problem -- then
         we could simply bail out here and ignore the property.
         Sadly, though, we might get the status code *after* we get

src/subversion/subversion/libsvn_ra_serf/ra_serf.h  view on Meta::CPAN

(*svn_ra_serf__xml_end_element_t)(svn_ra_serf__xml_parser_t *parser,
                                  svn_ra_serf__dav_props_t name,
                                  apr_pool_t *scratch_pool);

/* Callback invoked with @a baton by our XML @a parser when a CDATA portion
 * of @a data with size @a len is encountered.
 *
 * This may be invoked multiple times for the same tag.
 */
typedef svn_error_t *
(*svn_ra_serf__xml_cdata_chunk_handler_t)(svn_ra_serf__xml_parser_t *parser,
                                          const char *data,
                                          apr_size_t len,
                                          apr_pool_t *scratch_pool);

/*
 * Helper structure associated with handle_xml_parser handler that will
 * specify how an XML response will be processed.
 */
struct svn_ra_serf__xml_parser_t {
  /* Temporary allocations should be made in this pool. */
  apr_pool_t *pool;

  /* What kind of response are we parsing? If set, this should typically
     define the report name.  */
  const char *response_type;

  /* Caller-specific data passed to the start, end, cdata callbacks.  */
  void *user_data;

  /* Callback invoked when a tag is opened. */
  svn_ra_serf__xml_start_element_t start;

  /* Callback invoked when a tag is closed. */
  svn_ra_serf__xml_end_element_t end;

  /* Callback invoked when a cdata chunk is received. */
  svn_ra_serf__xml_cdata_chunk_handler_t cdata;

  /* Our associated expat-based XML parser. */
  XML_Parser xmlp;

  /* Our current state. */
  svn_ra_serf__xml_state_t *state;

  /* Our previously used states (will be reused). */
  svn_ra_serf__xml_state_t *free_state;

src/subversion/subversion/libsvn_ra_serf/ra_serf.h  view on Meta::CPAN

typedef svn_error_t *
(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes,
                             void *baton,
                             int entered_state,
                             const svn_ra_serf__dav_props_t *tag,
                             apr_pool_t *scratch_pool);


/* Called just before the parser leaves LEAVING_STATE.

   If cdata collection was enabled for this state, then CDATA will be
   non-NULL and contain the collected cdata.

   If attribute collection was enabled for this state, then ATTRS will
   contain the attributes collected for this element only, along with
   any values stored via svn_ra_serf__xml_note().

   Use svn_ra_serf__xml_gather_since() to gather up data from outer states.

   ATTRS is char* -> char*.

   Temporary allocations may be made in SCRATCH_POOL.  */
typedef svn_error_t *
(*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes,
                             void *baton,
                             int leaving_state,
                             const svn_string_t *cdata,
                             apr_hash_t *attrs,
                             apr_pool_t *scratch_pool);


/* Called for all states that are not using the builtin cdata collection.
   This callback is (only) appropriate for unbounded-size cdata content.

   CURRENT_STATE may be used to decide what to do with the data.

   Temporary allocations may be made in SCRATCH_POOL.  */
typedef svn_error_t *
(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
                            void *baton,
                            int current_state,
                            const char *data,
                            apr_size_t len,
                            apr_pool_t *scratch_pool);


/* State transition table.

   When the XML Context is constructed, it is in state 0. User states are

src/subversion/subversion/libsvn_ra_serf/ra_serf.h  view on Meta::CPAN

  /* This transition applies when in this state  */
  int from_state;

  /* And when this tag is observed  */
  const char *ns;
  const char *name;

  /* Moving to this state  */
  int to_state;

  /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should
     be TRUE in order to capture this cdata.  */
  svn_boolean_t collect_cdata;

  /* Which attributes of NAME should be collected? Terminate with NULL.
     Maximum of 10 attributes may be collected. Note that attribute
     namespaces are ignored at this time.

     Attribute names beginning with "?" are optional. Other names must
     exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised.  */
  const char *collect_attrs[11];

  /* When NAME is closed, should the callback be invoked?  */

src/subversion/subversion/libsvn_ra_serf/ra_serf.h  view on Meta::CPAN



/* Construct an XML parsing context, based on the TTABLE transition table.
   As content is parsed, the CLOSED_CB callback will be invoked according
   to the definition in the table.

   If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
   event. The callback will need to use the ENTERED_STATE and TAG parameters
   to decide what it would like to do.

   If CDATA_CB is not NULL, then it will be called for all cdata that is
   not be automatically collected (based on the transition table record's
   COLLECT_CDATA flag). It will be called in every state, so the callback
   must examine the CURRENT_STATE parameter to decide what to do.

   The same BATON value will be passed to all three callbacks.

   The context will be created within RESULT_POOL.  */
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);

/* Destroy all subpools for this structure. */
void
svn_ra_serf__xml_context_destroy(
  svn_ra_serf__xml_context_t *xmlctx);

/* Construct a handler with the response function/baton set up to parse
   a response body using the given XML context. The handler and its

src/subversion/subversion/libsvn_ra_serf/ra_serf.h  view on Meta::CPAN

                          const char *const *attrs);


/* When a close tag is seen, call this function to feed the information
   into XMLCTX.  */
svn_error_t *
svn_ra_serf__xml_cb_end(svn_ra_serf__xml_context_t *xmlctx,
                        const char *raw_name);


/* When cdata is parsed by the wrapping XML parser, call this function to
   feed the cdata into the XMLCTX.  */
svn_error_t *
svn_ra_serf__xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx,
                          const char *data,
                          apr_size_t len);


/*
 * Parses a server-side error message into a local Subversion error.
 */
struct svn_ra_serf__server_error_t {
  /* Our local representation of the error. */
  svn_error_t *error;

  /* Are we done with the response? */
  svn_boolean_t done;

  /* Have we seen an error tag? */
  svn_boolean_t in_error;

  /* Have we seen a HTTP "412 Precondition Failed" error? */
  svn_boolean_t contains_precondition_error;

  /* Should we be collecting the XML cdata? */
  svn_boolean_t collect_cdata;

  /* Collected cdata. NULL if cdata not needed. */
  svn_stringbuf_t *cdata;

  /* XML parser and namespace used to parse the remote response */
  svn_ra_serf__xml_parser_t parser;
};


/*
 * Handler that discards the entire @a response body associated with a
 * @a request.  Implements svn_ra_serf__response_handler_t.
 *

src/subversion/subversion/libsvn_ra_serf/ra_serf.h  view on Meta::CPAN

                                   serf_bucket_alloc_t *bkt_alloc,
                                   const char *tag);

/*
 * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped
 * version of DATA.
 *
 * The bucket will be allocated from BKT_ALLOC.
 */
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);
/*
 * Look up the @a attrs array for namespace definitions and add each one
 * to the @a ns_list of namespaces.
 *
 * New namespaces will be allocated in RESULT_POOL.
 */
void
svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list,

src/subversion/subversion/libsvn_ra_serf/replay.c  view on Meta::CPAN

                           info->parent->pool));
      svn_ra_serf__xml_pop_state(parser);

      svn_pool_destroy(info->pool);
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
cdata_replay(svn_ra_serf__xml_parser_t *parser,
             const char *data,
             apr_size_t len,
             apr_pool_t *scratch_pool)
{
  replay_context_t *replay_ctx = parser->user_data;
  replay_state_e state;

  UNUSED_CTX(replay_ctx);

  state = parser->state->current_state;

src/subversion/subversion/libsvn_ra_serf/replay.c  view on Meta::CPAN

  handler->body_type = "text/xml";
  handler->conn = session->conns[0];
  handler->session = session;

  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));

  parser_ctx->pool = pool;
  parser_ctx->user_data = replay_ctx;
  parser_ctx->start = start_replay;
  parser_ctx->end = end_replay;
  parser_ctx->cdata = cdata_replay;
  parser_ctx->done = &replay_ctx->done;

  handler->response_handler = svn_ra_serf__handle_xml_parser;
  handler->response_baton = parser_ctx;

  /* This is only needed to handle errors during XML parsing. */
  replay_ctx->parser_ctx = parser_ctx;
  replay_ctx->report_handler = handler; /* unused */

  svn_ra_serf__request_create(handler);

src/subversion/subversion/libsvn_ra_serf/replay.c  view on Meta::CPAN

             Because we have not one but a list of requests, the 'done' property
             on the replay_ctx is not of much use. Instead, use 'done_list'.
             On each handled response (succesfully or not), the parser will add
             done_item to done_list, so by keeping track of the state of
             done_list we know how many requests have been handled completely.
          */
          parser_ctx->pool = replay_ctx->src_rev_pool;
          parser_ctx->user_data = replay_ctx;
          parser_ctx->start = start_replay;
          parser_ctx->end = end_replay;
          parser_ctx->cdata = cdata_replay;
          parser_ctx->done = &replay_ctx->done;
          parser_ctx->done_list = &done_reports;
          parser_ctx->done_item = &replay_ctx->done_item;
          handler->response_handler = svn_ra_serf__handle_xml_parser;
          handler->response_baton = parser_ctx;
          replay_ctx->report_handler = handler;

          /* This is only needed to handle errors during XML parsing. */
          replay_ctx->parser_ctx = parser_ctx;

src/subversion/subversion/libsvn_ra_serf/update.c  view on Meta::CPAN

  return SVN_NO_ERROR;
}



/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
update_closed(svn_ra_serf__xml_estate_t *xes,
              void *baton,
              int leaving_state,
              const svn_string_t *cdata,
              apr_hash_t *attrs,
              apr_pool_t *scratch_pool)
{
  report_context_t *ctx = baton;

  if (leaving_state == TARGET_REVISION)
    {
      const char *rev = svn_hash_gets(attrs, "rev");

      SVN_ERR(ctx->update_editor->set_target_revision(ctx->update_baton,
                                                      SVN_STR_TO_REV(rev),
                                                      ctx->sess->pool));
    }

  return SVN_NO_ERROR;
}


/* Conforms to svn_ra_serf__xml_cdata_t  */
static svn_error_t *
update_cdata(svn_ra_serf__xml_estate_t *xes,
             void *baton,
             int current_state,
             const char *data,
             apr_size_t len,
             apr_pool_t *scratch_pool)
{
  report_context_t *ctx = baton;

  return SVN_NO_ERROR;
}

src/subversion/subversion/libsvn_ra_serf/update.c  view on Meta::CPAN

    }
  else if (state == IGNORE_PROP_NAME || state == NEED_PROP_NAME)
    {
      svn_ra_serf__xml_pop_state(parser);
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
cdata_report(svn_ra_serf__xml_parser_t *parser,
             const char *data,
             apr_size_t len,
             apr_pool_t *scratch_pool)
{
  report_context_t *ctx = parser->user_data;

  UNUSED_CTX(ctx);

  if (parser->state->current_state == PROP)
    {

src/subversion/subversion/libsvn_ra_serf/update.c  view on Meta::CPAN

  return SVN_NO_ERROR;
}


/** Editor callbacks given to callers to create request body */

/* Helper to create simple xml tag without attributes. */
static void
make_simple_xml_tag(svn_stringbuf_t **buf_p,
                    const char *tagname,
                    const char *cdata,
                    apr_pool_t *pool)
{
  svn_xml_make_open_tag(buf_p, pool, svn_xml_protect_pcdata, tagname, NULL);
  svn_xml_escape_cdata_cstring(buf_p, cdata, pool);
  svn_xml_make_close_tag(buf_p, pool, tagname);
}

static svn_error_t *
set_path(void *report_baton,
         const char *path,
         svn_revnum_t revision,
         svn_depth_t depth,
         svn_boolean_t start_empty,
         const char *lock_token,
         apr_pool_t *pool)
{
  report_context_t *report = report_baton;
  svn_stringbuf_t *buf = NULL;

  svn_xml_make_open_tag(&buf, pool, svn_xml_protect_pcdata, "S:entry",
                        "rev", apr_ltoa(pool, revision),
                        "lock-token", lock_token,
                        "depth", svn_depth_to_word(depth),
                        "start-empty", start_empty ? "true" : NULL,
                        NULL);
  svn_xml_escape_cdata_cstring(&buf, path, pool);
  svn_xml_make_close_tag(&buf, pool, "S:entry");

  SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
                                 NULL, pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
delete_path(void *report_baton,

src/subversion/subversion/libsvn_ra_serf/update.c  view on Meta::CPAN

                               _("Unable to parse URL '%s'"), url);
    }

  SVN_ERR(svn_ra_serf__report_resource(&report_target, report->sess,
                                       NULL, pool));
  SVN_ERR(svn_ra_serf__get_relative_path(&link, uri.path, report->sess,
                                         NULL, pool));

  link = apr_pstrcat(pool, "/", link, (char *)NULL);

  svn_xml_make_open_tag(&buf, pool, svn_xml_protect_pcdata, "S:entry",
                        "rev", apr_ltoa(pool, revision),
                        "lock-token", lock_token,
                        "depth", svn_depth_to_word(depth),
                        "linkpath", link,
                        "start-empty", start_empty ? "true" : NULL,
                        NULL);
  svn_xml_escape_cdata_cstring(&buf, path, pool);
  svn_xml_make_close_tag(&buf, pool, "S:entry");

  SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
                                 NULL, pool));

  /* Store the switch roots to allow generating repos_relpaths from just
     the working copy paths. (Needed for HTTPv2) */
  path = apr_pstrdup(report->pool, path);
  svn_hash_sets(report->switched_paths,
                path, apr_pstrdup(report->pool, link + 1));

src/subversion/subversion/libsvn_ra_serf/update.c  view on Meta::CPAN

  handler->conn = sess->conns[0];
  handler->session = sess;

  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));

  parser_ctx->pool = pool;
  parser_ctx->response_type = "update-report";
  parser_ctx->user_data = report;
  parser_ctx->start = start_report;
  parser_ctx->end = end_report;
  parser_ctx->cdata = cdata_report;
  parser_ctx->done = &report->done;

  handler->response_handler = svn_ra_serf__handle_xml_parser;
  handler->response_baton = parser_ctx;

  report->parser_ctx = parser_ctx;

  svn_ra_serf__request_create(handler);

  /* Open the first extra connection. */

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN


      /* If there's no error code provided, or if the provided code is
         0 (which can happen sometimes depending on how the error is
         constructed on the server-side), just pick a generic error
         code to run with. */
      if (! ctx->error->apr_err)
        {
          ctx->error->apr_err = SVN_ERR_RA_DAV_REQUEST_FAILED;
        }

      /* Start collecting cdata. */
      svn_stringbuf_setempty(ctx->cdata);
      ctx->collect_cdata = TRUE;
    }

  return SVN_NO_ERROR;
}

/*
 * Expat callback invoked on an end element tag for a PROPFIND response.
 */
static svn_error_t *
end_error(svn_ra_serf__xml_parser_t *parser,

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

      strcmp(name.namespace, "DAV:") == 0 &&
      strcmp(name.name, "error") == 0)
    {
      ctx->in_error = FALSE;
    }
  if (ctx->in_error && strcmp(name.name, "human-readable") == 0)
    {
      /* On the server dav_error_response_tag() will add a leading
         and trailing newline if DEBUG_CR is defined in mod_dav.h,
         so remove any such characters here. */
      svn_stringbuf_strip_whitespace(ctx->cdata);

      ctx->error->message = apr_pstrmemdup(ctx->error->pool, ctx->cdata->data,
                                           ctx->cdata->len);
      ctx->collect_cdata = FALSE;
    }

  return SVN_NO_ERROR;
}

/*
 * Expat callback invoked on CDATA elements in an error response.
 *
 * This callback can be called multiple times.
 */
static svn_error_t *
cdata_error(svn_ra_serf__xml_parser_t *parser,
            const char *data,
            apr_size_t len,
            apr_pool_t *scratch_pool)
{
  svn_ra_serf__server_error_t *ctx = parser->user_data;

  if (ctx->collect_cdata)
    {
      svn_stringbuf_appendbytes(ctx->cdata, data, len);
    }

  return SVN_NO_ERROR;
}


static apr_status_t
drain_bucket(serf_bucket_t *bucket)
{
  /* Read whatever is in the bucket, and just drop it.  */

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

      status = serf_bucket_read(bucket, SERF_READ_ALL_AVAIL, &data, &len);
      if (status)
        return status;
    }
}


static svn_ra_serf__server_error_t *
begin_error_parsing(svn_ra_serf__xml_start_element_t start,
                    svn_ra_serf__xml_end_element_t end,
                    svn_ra_serf__xml_cdata_chunk_handler_t cdata,
                    apr_pool_t *result_pool)
{
  svn_ra_serf__server_error_t *server_err;

  server_err = apr_pcalloc(result_pool, sizeof(*server_err));
  server_err->error = svn_error_create(APR_SUCCESS, NULL, NULL);
  server_err->contains_precondition_error = FALSE;
  server_err->cdata = svn_stringbuf_create_empty(server_err->error->pool);
  server_err->collect_cdata = FALSE;
  server_err->parser.pool = server_err->error->pool;
  server_err->parser.user_data = server_err;
  server_err->parser.start = start;
  server_err->parser.end = end;
  server_err->parser.cdata = cdata;
  server_err->parser.ignore_errors = TRUE;

  return server_err;
}

/* Implements svn_ra_serf__response_handler_t */
svn_error_t *
svn_ra_serf__handle_discard_body(serf_request_t *request,
                                 serf_bucket_t *response,
                                 void *baton,

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

     not to parse an error, then we'll never return here (because we
     change the response handler).  */
  SVN_ERR_ASSERT(handler->server_error == NULL);

  hdrs = serf_bucket_response_get_headers(response);
  val = serf_bucket_headers_get(hdrs, "Content-Type");
  if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
    {
      svn_ra_serf__server_error_t *server_err;

      server_err = begin_error_parsing(start_error, end_error, cdata_error,
                                       handler->handler_pool);

      /* Get the parser to set our DONE flag.  */
      server_err->parser.done = &handler->done;

      handler->server_error = server_err;
    }
  else
    {
      /* The body was not text/xml, so we don't know what to do with it.

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

  svn_ra_serf__server_error_t *ctx = parser->user_data;

  if (!ctx->in_error &&
      strcmp(name.namespace, "DAV:") == 0 &&
      strcmp(name.name, "multistatus") == 0)
    {
      ctx->in_error = TRUE;
    }
  else if (ctx->in_error && strcmp(name.name, "responsedescription") == 0)
    {
      /* Start collecting cdata. */
      svn_stringbuf_setempty(ctx->cdata);
      ctx->collect_cdata = TRUE;
    }
  else if (ctx->in_error &&
           strcmp(name.namespace, "DAV:") == 0 &&
           strcmp(name.name, "status") == 0)
    {
      /* Start collecting cdata. */
      svn_stringbuf_setempty(ctx->cdata);
      ctx->collect_cdata = TRUE;
    }

  return SVN_NO_ERROR;
}

/*
 * Expat callback invoked on an end element tag for a 207 response.
 */
static svn_error_t *
end_207(svn_ra_serf__xml_parser_t *parser,

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN


  if (ctx->in_error &&
      strcmp(name.namespace, "DAV:") == 0 &&
      strcmp(name.name, "multistatus") == 0)
    {
      ctx->in_error = FALSE;
    }
  if (ctx->in_error && strcmp(name.name, "responsedescription") == 0)
    {
      /* Remove leading newline added by DEBUG_CR on server */
      svn_stringbuf_strip_whitespace(ctx->cdata);

      ctx->collect_cdata = FALSE;
      ctx->error->message = apr_pstrmemdup(ctx->error->pool, ctx->cdata->data,
                                           ctx->cdata->len);
      if (ctx->contains_precondition_error)
        ctx->error->apr_err = SVN_ERR_FS_PROP_BASEVALUE_MISMATCH;
      else
        ctx->error->apr_err = SVN_ERR_RA_DAV_REQUEST_FAILED;
    }
  else if (ctx->in_error &&
           strcmp(name.namespace, "DAV:") == 0 &&
           strcmp(name.name, "status") == 0)
    {
      int status_code;

      ctx->collect_cdata = FALSE;

      SVN_ERR(parse_dav_status(&status_code, ctx->cdata, parser->pool));
      if (status_code == 412)
        ctx->contains_precondition_error = TRUE;
    }

  return SVN_NO_ERROR;
}

/*
 * Expat callback invoked on CDATA elements in a 207 response.
 *
 * This callback can be called multiple times.
 */
static svn_error_t *
cdata_207(svn_ra_serf__xml_parser_t *parser,
          const char *data,
          apr_size_t len,
          apr_pool_t *scratch_pool)
{
  svn_ra_serf__server_error_t *ctx = parser->user_data;

  if (ctx->collect_cdata)
    {
      svn_stringbuf_appendbytes(ctx->cdata, data, len);
    }

  return SVN_NO_ERROR;
}

/* Implements svn_ra_serf__response_handler_t */
svn_error_t *
svn_ra_serf__handle_multistatus_only(serf_request_t *request,
                                     serf_bucket_t *response,
                                     void *baton,

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

    {
      serf_bucket_t *hdrs;
      const char *val;

      hdrs = serf_bucket_response_get_headers(response);
      val = serf_bucket_headers_get(hdrs, "Content-Type");
      if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
        {
          svn_ra_serf__server_error_t *server_err;

          server_err = begin_error_parsing(start_207, end_207, cdata_207,
                                           handler->handler_pool);

          /* Get the parser to set our DONE flag.  */
          server_err->parser.done = &handler->done;

          handler->server_error = server_err;
        }
      else
        {
          /* The body was not text/xml, so we don't know what to do with it.

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

  err = parser->end(parser, name, scratch_pool);
  if (err && !SERF_BUCKET_READ_ERROR(err->apr_err))
    err = svn_error_create(SVN_ERR_RA_SERF_WRAPPED_ERROR, err, NULL);

  parser->error = err;
}


/* Conforms to Expat's XML_CharacterDataHandler  */
static void
cdata_xml(void *userData, const char *data, int len)
{
  svn_ra_serf__xml_parser_t *parser = userData;
  svn_error_t *err;
  apr_pool_t *scratch_pool;

  if (parser->error)
    return;

  if (!parser->state)
    svn_ra_serf__xml_push_state(parser, 0);

  /* ### get a real scratch_pool  */
  scratch_pool = parser->state->pool;

  err = parser->cdata(parser, data, len, scratch_pool);
  if (err && !SERF_BUCKET_READ_ERROR(err->apr_err))
    err = svn_error_create(SVN_ERR_RA_SERF_WRAPPED_ERROR, err, NULL);

  parser->error = err;
}

/* Flip the requisite bits in CTX to indicate that processing of the
   response is complete, adding the current "done item" to the list of
   completed items. */
static void

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

  apr_status_t err;

  hdrs = serf_bucket_response_get_headers(response);
  val = serf_bucket_headers_get(hdrs, "Content-Type");
  if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
    {
      /* ### we should figure out how to reuse begin_error_parsing  */

      server_err.error = svn_error_create(APR_SUCCESS, NULL, NULL);
      server_err.contains_precondition_error = FALSE;
      server_err.cdata = svn_stringbuf_create_empty(scratch_pool);
      server_err.collect_cdata = FALSE;
      server_err.parser.pool = server_err.error->pool;
      server_err.parser.user_data = &server_err;
      server_err.parser.start = start_error;
      server_err.parser.end = end_error;
      server_err.parser.cdata = cdata_error;
      server_err.parser.done = &server_err.done;
      server_err.parser.ignore_errors = TRUE;

      /* We don't care about any errors except for SERVER_ERR.ERROR  */
      svn_error_clear(svn_ra_serf__handle_xml_parser(request,
                                                     response,
                                                     &server_err.parser,
                                                     scratch_pool));

      /* ### checking DONE is silly. the above only parses whatever has

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

      return svn_error_trace(err);
    }

  if (!ctx->xmlp)
    {
      ctx->xmlp = XML_ParserCreate(NULL);
      apr_pool_cleanup_register(ctx->pool, &ctx->xmlp, xml_parser_cleanup,
                                apr_pool_cleanup_null);
      XML_SetUserData(ctx->xmlp, ctx);
      XML_SetElementHandler(ctx->xmlp, start_xml, end_xml);
      if (ctx->cdata)
        {
          XML_SetCharacterDataHandler(ctx->xmlp, cdata_xml);
        }
    }

  while (1)
    {
      const char *data;
      apr_size_t len;

      status = serf_bucket_read(response, PARSE_CHUNK_SIZE, &data, &len);
      if (SERF_BUCKET_READ_ERROR(status))

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

         5xx (Internal) Server error. */
      serf_bucket_t *hdrs;
      const char *val;

      hdrs = serf_bucket_response_get_headers(response);
      val = serf_bucket_headers_get(hdrs, "Content-Type");
      if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
        {
          svn_ra_serf__server_error_t *server_err;

          server_err = begin_error_parsing(start_error, end_error, cdata_error,
                                           handler->handler_pool);
          /* Get the parser to set our DONE flag.  */
          server_err->parser.done = &handler->done;

          handler->server_error = server_err;
        }
      else
        {
          handler->discard_body = TRUE;

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN


#ifdef EXPAT_HAS_STOPPARSER
  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(
                        svn_ra_serf__xml_cb_cdata(ectx->xmlctx, data, len));

#ifdef EXPAT_HAS_STOPPARSER
  if (ectx->inner_error)
    (void) XML_StopParser(ectx->parser, 0 /* resumable */);
#endif
}


/* Implements svn_ra_serf__response_handler_t */
static svn_error_t *

src/subversion/subversion/libsvn_ra_serf/util.c  view on Meta::CPAN

{
  struct expat_ctx_t *ectx = baton;

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

  /* ### TODO: sline.code < 200 should really be handled by the core */
  if ((ectx->handler->sline.code < 200) || (ectx->handler->sline.code >= 300))
    {
      /* 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.  */
      return svn_error_trace(svn_ra_serf__expect_empty_body(
                               request, response, ectx->handler,

src/subversion/subversion/libsvn_ra_serf/xml.c  view on Meta::CPAN

  /* If WAITING.NAMESPACE != NULL, wait for NAMESPACE:NAME element to be
     closed before looking for transitions from CURRENT->STATE.  */
  svn_ra_serf__dav_props_t 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;

src/subversion/subversion/libsvn_ra_serf/xml.c  view on Meta::CPAN


  /* 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;

};


static void
define_namespaces(svn_ra_serf__ns_t **ns_list,
                  const char *const *attrs,

src/subversion/subversion/libsvn_ra_serf/xml.c  view on Meta::CPAN

  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

src/subversion/subversion/libsvn_ra_serf/xml.c  view on Meta::CPAN

}

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

void
svn_ra_serf__xml_push_state(svn_ra_serf__xml_parser_t *parser,
                            int state)
{

src/subversion/subversion/libsvn_ra_serf/xml.c  view on Meta::CPAN

  svn_ra_serf__xml_context_t *xmlctx)
{
  svn_pool_destroy(xmlctx->scratch_pool);
}

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;

src/subversion/subversion/libsvn_ra_serf/xml.c  view on Meta::CPAN

                        SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                        _("XML Parsing failed: Unexpected root element '%s'"),
                        elemname.name);
        }

      xmlctx->waiting = elemname;
      /* ### return?  */
      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;

src/subversion/subversion/libsvn_ra_serf/xml.c  view on Meta::CPAN

     Known elements push a new state for a given tag. Some other elemname
     would imply closing an ancestor tag (where did ours go?) or a spurious
     tag closure.  */
  if (strcmp(elemname.name, xes->tag.name) != 0
      || strcmp(elemname.namespace, xes->tag.namespace) != 0)
    return svn_error_create(SVN_ERR_XML_MALFORMED, NULL,
                            _("The response contains invalid XML"));

  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.  */

src/subversion/subversion/libsvn_ra_serf/xml.c  view on Meta::CPAN

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


svn_error_t *
svn_ra_serf__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.namespace != NULL)
    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;
}

src/subversion/subversion/libsvn_subr/cmdline.c  view on Meta::CPAN

{
  const char *xml_safe;
  const char *encoding = NULL;

  if (*outstr == NULL)
    *outstr = svn_stringbuf_create_empty(pool);

  if (svn_xml_is_xml_safe(propval->data, propval->len))
    {
      svn_stringbuf_t *xml_esc = NULL;
      svn_xml_escape_cdata_string(&xml_esc, propval, pool);
      xml_safe = xml_esc->data;
    }
  else
    {
      const svn_string_t *base64ed = svn_base64_encode_string2(propval, TRUE,
                                                               pool);
      encoding = "base64";
      xml_safe = base64ed->data;
    }

  if (encoding)
    svn_xml_make_open_tag(
      outstr, pool, svn_xml_protect_pcdata,
      inherited_prop ? "inherited_property" : "property",
      "name", propname,
      "encoding", encoding, NULL);
  else
    svn_xml_make_open_tag(
      outstr, pool, svn_xml_protect_pcdata,
      inherited_prop ? "inherited_property" : "property",
      "name", propname, NULL);

  svn_stringbuf_appendcstr(*outstr, xml_safe);

  svn_xml_make_close_tag(
    outstr, pool,
    inherited_prop ? "inherited_property" : "property");

  return;

src/subversion/subversion/libsvn_subr/xml.c  view on Meta::CPAN



/*** XML escaping. ***/

/* ### ...?
 *
 * If *OUTSTR is @c NULL, set *OUTSTR to a new stringbuf allocated
 * in POOL, else append to the existing stringbuf there.
 */
static void
xml_escape_cdata(svn_stringbuf_t **outstr,
                 const char *data,
                 apr_size_t len,
                 apr_pool_t *pool)
{
  const char *end = data + len;
  const char *p = data, *q;

  if (*outstr == NULL)
    *outstr = svn_stringbuf_create_empty(pool);

src/subversion/subversion/libsvn_subr/xml.c  view on Meta::CPAN

        svn_stringbuf_appendcstr(*outstr, "&lt;");
      else if (*q == '>')
        svn_stringbuf_appendcstr(*outstr, "&gt;");
      else if (*q == '\r')
        svn_stringbuf_appendcstr(*outstr, "&#13;");

      p = q + 1;
    }
}

/* Essentially the same as xml_escape_cdata, with the addition of
   whitespace and quote characters. */
static void
xml_escape_attr(svn_stringbuf_t **outstr,
                const char *data,
                apr_size_t len,
                apr_pool_t *pool)
{
  const char *end = data + len;
  const char *p = data, *q;

src/subversion/subversion/libsvn_subr/xml.c  view on Meta::CPAN

        svn_stringbuf_appendcstr(*outstr, "&#10;");
      else if (*q == '\t')
        svn_stringbuf_appendcstr(*outstr, "&#9;");

      p = q + 1;
    }
}


void
svn_xml_escape_cdata_stringbuf(svn_stringbuf_t **outstr,
                               const svn_stringbuf_t *string,
                               apr_pool_t *pool)
{
  xml_escape_cdata(outstr, string->data, string->len, pool);
}


void
svn_xml_escape_cdata_string(svn_stringbuf_t **outstr,
                            const svn_string_t *string,
                            apr_pool_t *pool)
{
  xml_escape_cdata(outstr, string->data, string->len, pool);
}


void
svn_xml_escape_cdata_cstring(svn_stringbuf_t **outstr,
                             const char *string,
                             apr_pool_t *pool)
{
  xml_escape_cdata(outstr, string, (apr_size_t) strlen(string), pool);
}


void
svn_xml_escape_attr_stringbuf(svn_stringbuf_t **outstr,
                              const svn_stringbuf_t *string,
                              apr_pool_t *pool)
{
  xml_escape_attr(outstr, string->data, string->len, pool);
}

src/subversion/subversion/libsvn_subr/xml.c  view on Meta::CPAN

      svn_stringbuf_appendcstr(*str, "\n   ");
      svn_stringbuf_appendcstr(*str, key);
      svn_stringbuf_appendcstr(*str, "=\"");
      svn_xml_escape_attr_cstring(str, val, pool);
      svn_stringbuf_appendcstr(*str, "\"");
    }

  if (style == svn_xml_self_closing)
    svn_stringbuf_appendcstr(*str, "/");
  svn_stringbuf_appendcstr(*str, ">");
  if (style != svn_xml_protect_pcdata)
    svn_stringbuf_appendcstr(*str, "\n");
}


void
svn_xml_make_open_tag_v(svn_stringbuf_t **str,
                        apr_pool_t *pool,
                        enum svn_xml_open_tag_style style,
                        const char *tagname,
                        va_list ap)

src/subversion/subversion/mod_dav_svn/deadprops.c  view on Meta::CPAN

      if (! svn_xml_is_xml_safe(propval->data, propval->len))
        {
          const svn_string_t *enc_propval
            = svn_base64_encode_string2(propval, TRUE, pool);
          xml_safe = enc_propval->data;
          encoding = " V:encoding=\"base64\"";
        }
      else
        {
          svn_stringbuf_t *xmlval = NULL;
          svn_xml_escape_cdata_string(&xmlval, propval, pool);
          xml_safe = xmlval->data;
        }

      s = apr_psprintf(pool, "<%s%s%s>", prefix, name->name, encoding);
      apr_text_append(pool, phdr, s);

      /* the value is in our pool which means it has the right lifetime. */
      /* ### at least, per the current mod_dav architecture/API */
      apr_text_append(pool, phdr, xml_safe);

src/subversion/subversion/mod_dav_svn/deadprops.c  view on Meta::CPAN

{
  const svn_string_t *const *old_propval_p;
  const svn_string_t *old_propval;
  const svn_string_t *propval;
  svn_boolean_t absent;
  apr_pool_t *pool = db->p;
  dav_error *derr;

  /* SVN sends property values as a big blob of bytes. Thus, there should be
     no child elements of the property-name element. That also means that
     the entire contents of the blob is located in elem->first_cdata. The
     dav_xml_get_cdata() will figure it all out for us, but (normally) it
     should be awfully fast and not need to copy any data. */

  propval = svn_string_create
    (dav_xml_get_cdata(elem, pool, 0 /* strip_white */), pool);

  derr = decode_property_value(&propval, &absent, propval, elem, pool);
  if (derr)
    return derr;

  if (absent && ! elem->first_child)
    /* ### better error check */
    return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                              apr_psprintf(pool,
                                           "'%s' cannot be specified on the "
                                           "value without specifying an "
                                           "expectation",
                                           SVN_DAV__OLD_VALUE__ABSENT));

  /* ### namespace check? */
  if (elem->first_child && !strcmp(elem->first_child->name, SVN_DAV__OLD_VALUE))
    {
      /* Parse OLD_PROPVAL. */
      old_propval = svn_string_create(dav_xml_get_cdata(elem->first_child, pool,
                                                        0 /* strip_white */),
                                      pool);
      derr = decode_property_value(&old_propval, &absent,
                                   old_propval, elem->first_child, pool);
      if (derr)
        return derr;

      old_propval_p = (const svn_string_t *const *) &old_propval;
    }
  else

src/subversion/subversion/mod_dav_svn/lock.c  view on Meta::CPAN

  lock->path = apr_pstrdup(pool, path);
  lock->token = apr_pstrdup(pool, dlock->locktoken->uuid_str);

  /* DAV has no concept of lock creationdate, so assume 'now' */
  lock->creation_date = apr_time_now();

  if (dlock->auth_user)
    lock->owner = apr_pstrdup(pool, dlock->auth_user);

  /* We need to be very careful about stripping the <D:owner> tag away
     from the cdata.  It's okay to do for svn clients, but not other
     DAV clients! */
  if (dlock->owner)
    {
      if (is_svn_client)
        {
          /* mod_dav has forcibly xml-escaped the comment before
             handing it to us; we need to xml-unescape it (and remove
             the <D:owner> wrapper) when storing in the repository, so
             it looks reasonable to the rest of svn. */
          dav_error *derr;

src/subversion/subversion/mod_dav_svn/reports/dated-rev.c  view on Meta::CPAN

  ns = dav_svn__find_ns(doc->namespaces, "DAV:");
  if (ns != -1)
    {
      for (child = doc->root->first_child; child != NULL; child = child->next)
        {
          if (child->ns != ns ||
              strcmp(child->name, SVN_DAV__CREATIONDATE) != 0)
            continue;
          /* If this fails, we'll notice below, so ignore any error for now. */
          svn_error_clear
            (svn_time_from_cstring(&tm, dav_xml_get_cdata(child,
                                                          resource->pool, 1),
                                   resource->pool));
        }
    }

  if (tm == (apr_time_t) -1)
    {
      return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
                                "The request does not contain a valid "
                                "'DAV:" SVN_DAV__CREATIONDATE "' element.");

src/subversion/subversion/mod_dav_svn/reports/deleted-rev.c  view on Meta::CPAN

                                  SVN_DAV_ERROR_TAG);

  for (child = doc->root->first_child; child != NULL; child = child->next)
    {
      /* If this element isn't one of ours, then skip it. */
      if (child->ns != ns )
        continue;

      if (strcmp(child->name, "peg-revision") == 0)
        {
          peg_rev = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                     resource->pool, 1));
        }
      else if (strcmp(child->name, "end-revision") == 0)
        {
          end_rev = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                     resource->pool, 1));
        }
      else if (strcmp(child->name, "path") == 0)
        {
          rel_path = dav_xml_get_cdata(child, resource->pool, 0);
          if ((derr = dav_svn__test_canonical(rel_path, resource->pool)))
            return derr;
          /* Force REL_PATH to be a relative path, not an fspath. */
          rel_path = svn_relpath_canonicalize(rel_path, resource->pool);

          /* Append REL_PATH to the base FS path to get an absolute
             repository path. */
          abs_path = svn_fspath__join(resource->info->repos_path, rel_path,
                                      resource->pool);
        }

src/subversion/subversion/mod_dav_svn/reports/file-revs.c  view on Meta::CPAN

          const char *elem_name,
          const char *name,
          const svn_string_t *val,
          apr_pool_t *pool)
{
  name = apr_xml_quote_string(pool, name, 1);

  if (svn_xml_is_xml_safe(val->data, val->len))
    {
      svn_stringbuf_t *tmp = NULL;
      svn_xml_escape_cdata_string(&tmp, val, pool);
      val = svn_string_create(tmp->data, pool);
      SVN_ERR(dav_svn__brigade_printf(frb->bb, frb->output,
                                      "<S:%s name=\"%s\">%s</S:%s>" DEBUG_CR,
                                      elem_name, name, val->data, elem_name));
    }
  else
    {
      val = svn_base64_encode_string2(val, TRUE, pool);
      SVN_ERR(dav_svn__brigade_printf(frb->bb, frb->output,
                                      "<S:%s name=\"%s\" encoding=\"base64\">"

src/subversion/subversion/mod_dav_svn/reports/file-revs.c  view on Meta::CPAN

    }

  /* Get request information. */
  for (child = doc->root->first_child; child != NULL; child = child->next)
    {
      /* if this element isn't one of ours, then skip it */
      if (child->ns != ns)
        continue;

      if (strcmp(child->name, "start-revision") == 0)
        start = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1));
      else if (strcmp(child->name, "end-revision") == 0)
        end = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1));
      else if (strcmp(child->name, "include-merged-revisions") == 0)
        include_merged_revisions = TRUE; /* presence indicates positivity */
      else if (strcmp(child->name, "path") == 0)
        {
          const char *rel_path = dav_xml_get_cdata(child, resource->pool, 0);
          if ((derr = dav_svn__test_canonical(rel_path, resource->pool)))
            return derr;

          /* Force REL_PATH to be a relative path, not an fspath. */
          rel_path = svn_relpath_canonicalize(rel_path, resource->pool);

          /* Append the REL_PATH to the base FS path to get an
             absolute repository path. */
          abs_path = svn_fspath__join(resource->info->repos_path, rel_path,
                                      resource->pool);

src/subversion/subversion/mod_dav_svn/reports/get-location-segments.c  view on Meta::CPAN


  /* Gather the parameters. */
  for (child = doc->root->first_child; child != NULL; child = child->next)
    {
      /* If this element isn't one of ours, then skip it. */
      if (child->ns != ns)
        continue;

      if (strcmp(child->name, "peg-revision") == 0)
        {
          peg_revision = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                          resource->pool, 1));
        }
      else if (strcmp(child->name, "start-revision") == 0)
        {
          start_rev = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                       resource->pool, 1));
        }
      else if (strcmp(child->name, "end-revision") == 0)
        {
          end_rev = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                     resource->pool, 1));
        }
      else if (strcmp(child->name, "path") == 0)
        {
          const char *rel_path = dav_xml_get_cdata(child, resource->pool, 0);
          if ((derr = dav_svn__test_canonical(rel_path, resource->pool)))
            return derr;

          /* Force REL_PATH to be a relative path, not an fspath. */
          rel_path = svn_relpath_canonicalize(rel_path, resource->pool);

          /* Append the REL_PATH to the base FS path to get an
             absolute repository path. */
          abs_path = svn_fspath__join(resource->info->repos_path, rel_path,
                                      resource->pool);

src/subversion/subversion/mod_dav_svn/reports/get-locations.c  view on Meta::CPAN

    }

  /* Gather the parameters. */
  for (child = doc->root->first_child; child != NULL; child = child->next)
    {
      /* If this element isn't one of ours, then skip it. */
      if (child->ns != ns)
        continue;

      if (strcmp(child->name, "peg-revision") == 0)
        peg_revision = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                        resource->pool, 1));
      else if (strcmp(child->name, "location-revision") == 0)
        {
          svn_revnum_t revision
            = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1));
          APR_ARRAY_PUSH(location_revisions, svn_revnum_t) = revision;
        }
      else if (strcmp(child->name, "path") == 0)
        {
          const char *rel_path = dav_xml_get_cdata(child, resource->pool, 0);
          if ((derr = dav_svn__test_canonical(rel_path, resource->pool)))
            return derr;

          /* Force REL_PATH to be a relative path, not an fspath. */
          rel_path = svn_relpath_canonicalize(rel_path, resource->pool);

          /* Append the REL_PATH to the base FS path to get an absolute
             repository path. */
          abs_path = svn_fspath__join(resource->info->repos_path, rel_path,
                                      resource->pool);



( run in 0.352 second using v1.01-cache-2.11-cpan-454fe037f31 )