예제 #1
0
/* Decode the possibly-zlib compressed string of length INLEN that is in
   IN, into OUT.  We expect an integer is prepended to IN that specifies
   the original size, and that if encoded size == original size, that the
   remaining data is not compressed.
   In that case, we will simply return pointer into IN as data pointer for
   OUT, COPYLESS_ALLOWED has been set.  The, the caller is expected not to
   modify the contents of OUT.
   An error is returned if the decoded length exceeds the given LIMIT.
 */
static svn_error_t *
zlib_decode(const unsigned char *in, apr_size_t inLen, svn_stringbuf_t *out,
            apr_size_t limit)
{
  apr_size_t len;
  apr_uint64_t size;
  const unsigned char *oldplace = in;

  /* First thing in the string is the original length.  */
  in = svn__decode_uint(&size, in, in + inLen);
  len = (apr_size_t)size;
  if (in == NULL || len != size)
    return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA, NULL,
                            _("Decompression of zlib compressed data failed: no size"));
  if (len > limit)
    return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA, NULL,
                            _("Decompression of zlib compressed data failed: "
                              "size too large"));

  /* We need to subtract the size of the encoded original length off the
   *      still remaining input length.  */
  inLen -= (in - oldplace);
  if (inLen == len)
    {
      svn_stringbuf_ensure(out, len);
      memcpy(out->data, in, len);
      out->data[len] = 0;
      out->len = len;

      return SVN_NO_ERROR;
    }
  else
    {
      unsigned long zlen = len;
      int zerr;

      svn_stringbuf_ensure(out, len);
      zerr = uncompress((unsigned char *)out->data, &zlen, in, inLen);
      if (zerr != Z_OK)
        return svn_error_trace(svn_error__wrap_zlib(
                                 zerr, "uncompress",
                                 _("Decompression of svndiff data failed")));

      /* Zlib should not produce something that has a different size than the
         original length we stored. */
      if (zlen != len)
        return svn_error_create(SVN_ERR_SVNDIFF_INVALID_COMPRESSED_DATA,
                                NULL,
                                _("Size of uncompressed data "
                                  "does not match stored original length"));
      out->data[zlen] = 0;
      out->len = zlen;
    }
  return SVN_NO_ERROR;
}
예제 #2
0
/* Append the concrete representation of SKEL to the string STR.
   Grow S with new space from POOL as necessary.  */
static svn_stringbuf_t *
unparse(const svn_skel_t *skel, svn_stringbuf_t *str, apr_pool_t *pool)
{
  if (skel->is_atom)
    {
      /* Append an atom to STR.  */
      if (use_implicit(skel))
        svn_stringbuf_appendbytes(str, skel->data, skel->len);
      else
        {
          /* Append the length to STR.  */
          char buf[200];
          int length_len;

          length_len = putsize(buf, sizeof(buf), skel->len);

          SVN_ERR_ASSERT_NO_RETURN(length_len > 0);

          /* Make sure we have room for the length, the space, and the
             atom's contents.  */
          svn_stringbuf_ensure(str, str->len + length_len + 1 + skel->len);
          svn_stringbuf_appendbytes(str, buf, length_len);
          str->data[str->len++] = ' ';
          svn_stringbuf_appendbytes(str, skel->data, skel->len);
        }
    }
  else
    {
      /* Append a list to STR.  */
      svn_skel_t *child;

      /* Emit an opening parenthesis.  */
      svn_stringbuf_ensure(str, str->len + 1);
      str->data[str->len++] = '(';

      /* Append each element.  Emit a space between each pair of elements.  */
      for (child = skel->children; child; child = child->next)
        {
          unparse(child, str, pool);
          if (child->next)
            {
              svn_stringbuf_ensure(str, str->len + 1);
              str->data[str->len++] = ' ';
            }
        }

      /* Emit a closing parenthesis.  */
      svn_stringbuf_appendbyte(str, ')');
    }

  return str;
}
예제 #3
0
파일: config_win.c 프로젝트: vocho/openqnx
static svn_error_t *
parse_section(svn_config_t *cfg, HKEY hkey, const char *section,
              svn_stringbuf_t *option, svn_stringbuf_t *value)
{
  DWORD option_len, type, index;
  LONG err;

  /* Start with a reasonable size for the buffers. */
  svn_stringbuf_ensure(option, SVN_REG_DEFAULT_NAME_SIZE);
  svn_stringbuf_ensure(value, SVN_REG_DEFAULT_VALUE_SIZE);
  for (index = 0; ; ++index)
    {
      option_len = option->blocksize;
      err = RegEnumValue(hkey, index, option->data, &option_len,
                         NULL, &type, NULL, NULL);
      if (err == ERROR_NO_MORE_ITEMS)
          break;
      if (err == ERROR_INSUFFICIENT_BUFFER)
        {
          svn_stringbuf_ensure(option, option_len);
          err = RegEnumValue(hkey, index, option->data, &option_len,
                             NULL, &type, NULL, NULL);
        }
      if (err != ERROR_SUCCESS)
        return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                "Can't enumerate registry values");

      /* Ignore option names that start with '#', see
         http://subversion.tigris.org/issues/show_bug.cgi?id=671 */
      if (type == REG_SZ && option->data[0] != '#')
        {
          DWORD value_len = value->blocksize;
          err = RegQueryValueEx(hkey, option->data, NULL, NULL,
                                value->data, &value_len);
          if (err == ERROR_MORE_DATA)
            {
              svn_stringbuf_ensure(value, value_len);
              err = RegQueryValueEx(hkey, option->data, NULL, NULL,
                                    value->data, &value_len);
            }
          if (err != ERROR_SUCCESS)
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                    "Can't read registry value data");

          svn_config_set(cfg, section, option->data, value->data);
        }
    }

  return SVN_NO_ERROR;
}
CContentInstance* CContentFieldSvnPresentProps::getInstance(const char* pchPath)
{
	CSvnPool oPool;
	apr_hash_t* pProps = getParent().getPropsForPath(pchPath, oPool);

	if (!pProps)
	{
		return new CContentInstanceEmpty(*this, pchPath);
	}

	svn_stringbuf_t* pBuf = svn_stringbuf_create("", oPool);
	svn_stringbuf_ensure(pBuf, apr_hash_count(pProps) * 16);

	for (apr_hash_index_t* pIdx = apr_hash_first(oPool, pProps); pIdx; pIdx = apr_hash_next(pIdx))
	{
		const char* pchPropName;
		int iSize = 0;

		apr_hash_this(pIdx, reinterpret_cast<const void**>(&pchPropName), &iSize, NULL);
		svn_stringbuf_appendcstr(pBuf, pchPropName);
		svn_stringbuf_appendcstr(pBuf, " ");
	}

	svn_stringbuf_chop(pBuf, 1);
	return new CContentInstanceString(*this, pchPath, pBuf->data, pBuf->len);
}
예제 #5
0
void
svn_stringbuf_replace(svn_stringbuf_t *str,
                      apr_size_t pos,
                      apr_size_t old_count,
                      const char *bytes,
                      apr_size_t new_count)
{
  if (bytes + new_count > str->data && bytes < str->data + str->blocksize)
    {
      /* special case: BYTES overlaps with this string -> copy the source */
      const char *temp = apr_pstrndup(str->pool, bytes, new_count);
      svn_stringbuf_replace(str, pos, old_count, temp, new_count);
    }
  else
    {
      if (pos > str->len)
        pos = str->len;
      if (pos + old_count > str->len)
        old_count = str->len - pos;

      if (old_count < new_count)
        {
          apr_size_t delta = new_count - old_count;
          svn_stringbuf_ensure(str, str->len + delta);
        }

      if (old_count != new_count)
        memmove(str->data + pos + new_count, str->data + pos + old_count,
                str->len - pos - old_count + 1);

      memcpy(str->data + pos, bytes, new_count);
      str->len += new_count - old_count;
    }
}
예제 #6
0
void
svn_stringbuf_set(svn_stringbuf_t *str, const char *value)
{
  apr_size_t amt = strlen(value);

  svn_stringbuf_ensure(str, amt + 1);
  memcpy(str->data, value, amt + 1);
  str->len = amt;
}
예제 #7
0
파일: win32_xlate.c 프로젝트: vocho/openqnx
apr_status_t
svn_subr__win32_xlate_to_stringbuf(win32_xlate_t *handle,
                                   const char *src_data,
                                   apr_size_t src_length,
                                   svn_stringbuf_t **dest,
                                   apr_pool_t *pool)
{
  WCHAR * wide_str;
  int retval, wide_size;

  *dest = svn_stringbuf_create("", pool);

  if (src_length == 0)
    return APR_SUCCESS;

  retval = MultiByteToWideChar(handle->from_page_id, 0, src_data, src_length,
                               NULL, 0);
  if (retval == 0)
    return apr_get_os_error();

  wide_size = retval;

  /* Allocate temporary buffer for small strings on stack instead of heap. */
  if (wide_size <= MAX_PATH)
    {
      wide_str = alloca(wide_size * sizeof(WCHAR));
    }
  else
    {
      wide_str = apr_palloc(pool, wide_size * sizeof(WCHAR));
    }

  retval = MultiByteToWideChar(handle->from_page_id, 0, src_data, src_length,
                               wide_str, wide_size);

  if (retval == 0)
    return apr_get_os_error();

  retval = WideCharToMultiByte(handle->to_page_id, 0, wide_str, wide_size,
                               NULL, 0, NULL, NULL);

  if (retval == 0)
    return apr_get_os_error();

  /* Ensure that buffer is enough to hold result string and termination
     character. */
  svn_stringbuf_ensure(*dest, retval + 1);
  (*dest)->len = retval;

  retval = WideCharToMultiByte(handle->to_page_id, 0, wide_str, wide_size,
                               (*dest)->data, (*dest)->len, NULL, NULL);
  if (retval == 0)
    return apr_get_os_error();

  (*dest)->len = retval;
  return APR_SUCCESS;
}
예제 #8
0
/* If IN is a string that is >= MIN_COMPRESS_SIZE and the COMPRESSION_LEVEL
   is not SVN_DELTA_COMPRESSION_LEVEL_NONE, zlib compress it and places the
   result in OUT, with an integer prepended specifying the original size.
   If IN is < MIN_COMPRESS_SIZE, or if the compressed version of IN was no
   smaller than the original IN, OUT will be a copy of IN with the size
   prepended as an integer. */
static svn_error_t *
zlib_encode(const char *data,
            apr_size_t len,
            svn_stringbuf_t *out,
            int compression_level)
{
  unsigned long endlen;
  apr_size_t intlen;
  unsigned char buf[SVN__MAX_ENCODED_UINT_LEN], *p;

  svn_stringbuf_setempty(out);
  p = svn__encode_uint(buf, (apr_uint64_t)len);
  svn_stringbuf_appendbytes(out, (const char *)buf, p - buf);

  intlen = out->len;

  /* Compression initialization overhead is considered to large for
     short buffers.  Also, if we don't actually want to compress data,
     ZLIB will produce an output no shorter than the input.  Hence,
     the DATA would directly appended to OUT, so we can do that directly
     without calling ZLIB before. */
  if (len < MIN_COMPRESS_SIZE || compression_level == SVN__COMPRESSION_NONE)
    {
      svn_stringbuf_appendbytes(out, data, len);
    }
  else
    {
      int zerr;

      svn_stringbuf_ensure(out, svnCompressBound(len) + intlen);
      endlen = out->blocksize;

      zerr = compress2((unsigned char *)out->data + intlen, &endlen,
                       (const unsigned char *)data, len,
                       compression_level);
      if (zerr != Z_OK)
        return svn_error_trace(svn_error__wrap_zlib(
                                 zerr, "compress2",
                                 _("Compression of svndiff data failed")));

      /* Compression didn't help :(, just append the original text */
      if (endlen >= len)
        {
          svn_stringbuf_appendbytes(out, data, len);
          return SVN_NO_ERROR;
        }
      out->len = endlen + intlen;
      out->data[out->len] = 0;
    }
  return SVN_NO_ERROR;
}
예제 #9
0
파일: skel.c 프로젝트: 2asoft/freebsd
/* Append the concrete representation of SKEL to the string STR. */
static svn_stringbuf_t *
unparse(const svn_skel_t *skel, svn_stringbuf_t *str)
{
  if (skel->is_atom)
    {
      /* Append an atom to STR.  */
      if (use_implicit(skel))
        svn_stringbuf_appendbytes(str, skel->data, skel->len);
      else
        {
          /* Append the length to STR.  Ensure enough space for at least
           * one 64 bit int. */
          char buf[200 + SVN_INT64_BUFFER_SIZE];
          apr_size_t length_len;

          length_len = svn__ui64toa(buf, skel->len);

          SVN_ERR_ASSERT_NO_RETURN(length_len > 0);

          /* Make sure we have room for the length, the space, and the
             atom's contents.  */
          svn_stringbuf_ensure(str, str->len + length_len + 1 + skel->len);
          svn_stringbuf_appendbytes(str, buf, length_len);
          svn_stringbuf_appendbyte(str, ' ');
          svn_stringbuf_appendbytes(str, skel->data, skel->len);
        }
    }
  else
    {
      /* Append a list to STR: an opening parenthesis, the list elements
       * separated by a space, and a closing parenthesis.  */
      svn_skel_t *child;

      svn_stringbuf_appendbyte(str, '(');

      for (child = skel->children; child; child = child->next)
        {
          unparse(child, str);
          if (child->next)
            svn_stringbuf_appendbyte(str, ' ');
        }

      svn_stringbuf_appendbyte(str, ')');
    }

  return str;
}
예제 #10
0
파일: config.c 프로젝트: 2asoft/freebsd
/* Return the value for KEY in HASH.  If CASE_SENSITIVE is FALSE,
   BUFFER will be used to construct the normalized hash key. */
static void *
get_hash_value(apr_hash_t *hash,
               svn_stringbuf_t *buffer,
               const char *key,
               svn_boolean_t case_sensitive)
{
  apr_size_t i;
  apr_size_t len = strlen(key);

  if (case_sensitive)
    return apr_hash_get(hash, key, len);

  svn_stringbuf_ensure(buffer, len);
  for (i = 0; i < len; ++i)
    buffer->data[i] = (char)apr_tolower(key[i]);

  return apr_hash_get(hash, buffer->data, len);
}
예제 #11
0
void
svn_stringbuf_appendbytes(svn_stringbuf_t *str, const char *bytes,
                          apr_size_t count)
{
  apr_size_t total_len;
  void *start_address;

  total_len = str->len + count;  /* total size needed */

  /* +1 for null terminator. */
  svn_stringbuf_ensure(str, (total_len + 1));

  /* get address 1 byte beyond end of original bytestring */
  start_address = (str->data + str->len);

  memcpy(start_address, bytes, count);
  str->len = total_len;

  str->data[str->len] = '\0';  /* We don't know if this is binary
                                  data or not, but convention is
                                  to null-terminate. */
}
예제 #12
0
void
svn_stringbuf_insert(svn_stringbuf_t *str,
                     apr_size_t pos,
                     const char *bytes,
                     apr_size_t count)
{
  if (bytes + count > str->data && bytes < str->data + str->blocksize)
    {
      /* special case: BYTES overlaps with this string -> copy the source */
      const char *temp = apr_pstrndup(str->pool, bytes, count);
      svn_stringbuf_insert(str, pos, temp, count);
    }
  else
    {
      if (pos > str->len)
        pos = str->len;

      svn_stringbuf_ensure(str, str->len + count);
      memmove(str->data + pos + count, str->data + pos, str->len - pos + 1);
      memcpy(str->data + pos, bytes, count);

      str->len += count;
    }
}
예제 #13
0
static svn_error_t *
stream_readline_chunky(svn_stringbuf_t **stringbuf,
                       svn_boolean_t *eof,
                       const char *eol,
                       svn_stream_t *stream,
                       apr_pool_t *pool)
{
  /* Read larger chunks of data at once into this buffer and scan
   * that for EOL. A good chunk size should be about 80 chars since
   * most text lines will be shorter. However, don't use a much
   * larger value because filling the buffer from the stream takes
   * time as well.
   */
  char buffer[LINE_CHUNK_SIZE+1];

  /* variables */
  svn_stream_mark_t *mark;
  apr_size_t numbytes;
  const char *eol_pos;
  apr_size_t total_parsed = 0;

  /* invariant for this call */
  const size_t eol_len = strlen(eol);

  /* Remember the line start so this plus the line length will be
   * the position to move to at the end of this function.
   */
  SVN_ERR(svn_stream_mark(stream, &mark, pool));

  /* Read the first chunk. */
  numbytes = LINE_CHUNK_SIZE;
  SVN_ERR(svn_stream_read(stream, buffer, &numbytes));
  buffer[numbytes] = '\0';

  /* Look for the EOL in this first chunk. If we find it, we are done here.
   */
  eol_pos = strstr(buffer, eol);
  if (eol_pos != NULL)
    {
      *stringbuf = svn_stringbuf_ncreate(buffer, eol_pos - buffer, pool);
      total_parsed = eol_pos - buffer + eol_len;
    }
  else if (numbytes < LINE_CHUNK_SIZE)
    {
      /* We hit EOF but not EOL.
       */
      *stringbuf = svn_stringbuf_ncreate(buffer, numbytes, pool);
      *eof = TRUE;
      return SVN_NO_ERROR;
     }
  else
    {
      /* A larger buffer for the string is needed. */
      svn_stringbuf_t *str;
      str = svn_stringbuf_create_ensure(2*LINE_CHUNK_SIZE, pool);
      svn_stringbuf_appendbytes(str, buffer, numbytes);
      *stringbuf = str;

      /* Loop reading chunks until an EOL was found. If we hit EOF, fall
       * back to the standard implementation. */
      do
      {
        /* Append the next chunk to the string read so far.
         */
        svn_stringbuf_ensure(str, str->len + LINE_CHUNK_SIZE);
        numbytes = LINE_CHUNK_SIZE;
        SVN_ERR(svn_stream_read(stream, str->data + str->len, &numbytes));
        str->len += numbytes;
        str->data[str->len] = '\0';

        /* Look for the EOL in the new data plus the last part of the
         * previous chunk because the EOL may span over the boundary
         * between both chunks.
         */
        eol_pos = strstr(str->data + str->len - numbytes - (eol_len-1), eol);

        if ((numbytes < LINE_CHUNK_SIZE) && (eol_pos == NULL))
        {
          /* We hit EOF instead of EOL. */
          *eof = TRUE;
          return SVN_NO_ERROR;
        }
      }
      while (eol_pos == NULL);

      /* Number of bytes we actually consumed (i.e. line + EOF).
       * We need to "return" the rest to the stream by moving its
       * read pointer.
       */
      total_parsed = eol_pos - str->data + eol_len;

      /* Terminate the string at the EOL postion and return it. */
      str->len = eol_pos - str->data;
      str->data[str->len] = 0;
    }

  /* Move the stream read pointer to the first position behind the EOL.
   */
  SVN_ERR(svn_stream_seek(stream, mark));
  return svn_error_trace(svn_stream_skip(stream, total_parsed));
}
예제 #14
0
파일: config_win.c 프로젝트: vocho/openqnx
svn_error_t *
svn_config__parse_registry(svn_config_t *cfg, const char *file,
                           svn_boolean_t must_exist, apr_pool_t *pool)
{
  apr_pool_t *subpool;
  svn_stringbuf_t *section, *option, *value;
  svn_error_t *svn_err = SVN_NO_ERROR;
  HKEY base_hkey, hkey;
  DWORD index;
  LONG err;

  if (0 == strncmp(file, SVN_REGISTRY_HKLM, SVN_REGISTRY_HKLM_LEN))
    {
      base_hkey = HKEY_LOCAL_MACHINE;
      file += SVN_REGISTRY_HKLM_LEN;
    }
  else if (0 == strncmp(file, SVN_REGISTRY_HKCU, SVN_REGISTRY_HKCU_LEN))
    {
      base_hkey = HKEY_CURRENT_USER;
      file += SVN_REGISTRY_HKCU_LEN;
    }
  else
    {
      return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
                               "Unrecognised registry path '%s'",
                               svn_path_local_style(file, pool));
    }

  err = RegOpenKeyEx(base_hkey, file, 0,
                     KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
                     &hkey);
  if (err != ERROR_SUCCESS)
    {
      const int is_enoent = APR_STATUS_IS_ENOENT(APR_FROM_OS_ERROR(err));
      if (!is_enoent)
        return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
                                 "Can't open registry key '%s'",
                                 svn_path_local_style(file, pool));
      else if (must_exist && is_enoent)
        return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
                                 "Can't find registry key '%s'",
                                 svn_path_local_style(file, pool));
      else
        return SVN_NO_ERROR;
    }


  subpool = svn_pool_create(pool);
  section = svn_stringbuf_create("", subpool);
  option = svn_stringbuf_create("", subpool);
  value = svn_stringbuf_create("", subpool);

  /* The top-level values belong to the [DEFAULT] section */
  svn_err = parse_section(cfg, hkey, SVN_CONFIG__DEFAULT_SECTION,
                          option, value);
  if (svn_err)
    goto cleanup;

  /* Now enumerate the rest of the keys. */
  svn_stringbuf_ensure(section, SVN_REG_DEFAULT_NAME_SIZE);
  for (index = 0; ; ++index)
    {
      DWORD section_len = section->blocksize;
      FILETIME last_write_time;
      HKEY sub_hkey;

      err = RegEnumKeyEx(hkey, index, section->data, &section_len,
                         NULL, NULL, NULL, &last_write_time);
      if (err == ERROR_NO_MORE_ITEMS)
          break;
      if (err == ERROR_MORE_DATA)
        {
          svn_stringbuf_ensure(section, section_len);
          err = RegEnumKeyEx(hkey, index, section->data, &section_len,
                             NULL, NULL, NULL, &last_write_time);
        }
      if (err != ERROR_SUCCESS)
        {
          svn_err =  svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                      "Can't enumerate registry keys");
          goto cleanup;
        }

      err = RegOpenKeyEx(hkey, section->data, 0,
                         KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
                         &sub_hkey);
      if (err != ERROR_SUCCESS)
        {
          svn_err =  svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
                                      "Can't open existing subkey");
          goto cleanup;
        }

      svn_err = parse_section(cfg, sub_hkey, section->data, option, value);
      RegCloseKey(sub_hkey);
      if (svn_err)
        goto cleanup;
    }

 cleanup:
  RegCloseKey(hkey);
  svn_pool_destroy(subpool);
  return svn_err;
}