Alien-SVN

 view release on metacpan or  search on metacpan

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

{
  dav_xmlns_add(xi, "S", SVN_DAV_PROP_NS_SVN);
  dav_xmlns_add(xi, "C", SVN_DAV_PROP_NS_CUSTOM);
  dav_xmlns_add(xi, "V", SVN_DAV_PROP_NS_DAV);

  /* ### we don't have any other possible namespaces right now. */

  return NULL;
}

static dav_error *
db_output_value(dav_db *db,
                const dav_prop_name *name,
                dav_xmlns_info *xi,
                apr_text_header *phdr,
                int *found)
{
  const char *prefix;
  const char *s;
  svn_string_t *propval;
  dav_error *err;
  apr_pool_t *pool = db->resource->pool;

  if ((err = get_value(db, name, &propval)) != NULL)
    return err;

  /* return whether the prop was found, then punt or handle it. */
  *found = (propval != NULL);
  if (propval == NULL)
    return NULL;

  if (strcmp(name->ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
    prefix = "C:";
  else
    prefix = "S:";

  if (propval->len == 0)
    {
      /* empty value. add an empty elem. */
      s = apr_psprintf(pool, "<%s%s/>" DEBUG_CR, prefix, name->name);
      apr_text_append(pool, phdr, s);
    }
  else
    {
      /* add <prefix:name [V:encoding="base64"]>value</prefix:name> */
      const char *xml_safe;
      const char *encoding = "";

      /* Ensure XML-safety of our property values before sending them
         across the wire. */
      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);

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

  return NULL;
}


static dav_error *
db_map_namespaces(dav_db *db,
                  const apr_array_header_t *namespaces,
                  dav_namespace_map **mapping)
{
  /* we don't need a namespace mapping right now. nothing to do */
  return NULL;
}


static dav_error *
decode_property_value(const svn_string_t **out_propval_p,
                      svn_boolean_t *absent,
                      const svn_string_t *maybe_encoded_propval,
                      const apr_xml_elem *elem,
                      apr_pool_t *pool)
{
  apr_xml_attr *attr = elem->attr;

  /* Default: no "encoding" attribute. */
  *absent = FALSE;
  *out_propval_p = maybe_encoded_propval;

  /* Check for special encodings of the property value. */
  while (attr)
    {
      if (strcmp(attr->name, "encoding") == 0) /* ### namespace check? */
        {
          const char *enc_type = attr->value;

          /* Handle known encodings here. */
          if (enc_type && (strcmp(enc_type, "base64") == 0))
            *out_propval_p = svn_base64_decode_string(maybe_encoded_propval,
                                                      pool);
          else
            return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                                      "Unknown property encoding");
          break;
        }

      if (strcmp(attr->name, SVN_DAV__OLD_VALUE__ABSENT) == 0)
        {
          /* ### parse attr->value */
          *absent = TRUE;
          *out_propval_p = NULL;
        }

      /* Next attribute, please. */
      attr = attr->next;
    }

  return NULL;
}

static dav_error *
db_store(dav_db *db,
         const dav_prop_name *name,
         const apr_xml_elem *elem,
         dav_namespace_map *mapping)
{
  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
    old_propval_p = NULL;


  return save_value(db, name, old_propval_p, propval);
}


static dav_error *
db_remove(dav_db *db, const dav_prop_name *name)
{
  svn_error_t *serr;
  const char *propname;
  apr_pool_t *subpool;

  /* get the repos-local name */
  get_repos_propname(db, name, &propname);

  /* ### non-svn props aren't in our repos, so punt for now */
  if (propname == NULL)
    return NULL;

  /* A subpool to cope with mod_dav making multiple calls, e.g. during
     PROPPATCH with multiple values. */
  subpool = svn_pool_create(db->resource->pool);

  /* Working Baseline or Working (Version) Resource */
  if (db->resource->baselined)
    if (db->resource->working)
      serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn,
                                          propname, NULL, subpool);
    else
      /* ### VIOLATING deltaV: you can't proppatch a baseline, it's
         not a working resource!  But this is how we currently
         (hackily) allow the svn client to change unversioned rev
         props.  See issue #916. */
      serr = svn_repos_fs_change_rev_prop4(db->resource->info->repos->repos,
                                           db->resource->info->root.rev,
                                           db->resource->info->repos->username,
                                           propname, NULL, NULL, TRUE, TRUE,
                                           db->authz_read_func,
                                           db->authz_read_baton,
                                           subpool);
  else
    serr = svn_repos_fs_change_node_prop(db->resource->info->root.root,
                                         get_repos_path(db->resource->info),
                                         propname, NULL, subpool);
  svn_pool_destroy(subpool);
  if (serr != NULL)
    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                "could not remove a property",



( run in 1.520 second using v1.01-cache-2.11-cpan-e1769b4cff6 )