You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/06/14 22:58:16 UTC
svn commit: r1685464 [9/43] - in /subversion/branches/fsx-1.10: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/
contrib/client-side/svncopy/ doc/ notes/ subversion/bindings/javahl/
subversion/bindings/javahl/native/ subversion/bi...
Modified: subversion/branches/fsx-1.10/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_delta/svndiff.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_delta/svndiff.c Sun Jun 14 20:58:10 2015
@@ -36,6 +36,20 @@
#include "private/svn_string_private.h"
#include "private/svn_dep_compat.h"
+static const char SVNDIFF_V0[] = { 'S', 'V', 'N', 0 };
+static const char SVNDIFF_V1[] = { 'S', 'V', 'N', 1 };
+
+#define SVNDIFF_HEADER_SIZE (sizeof(SVNDIFF_V0))
+
+static const char *
+get_svndiff_header(int version)
+{
+ if (version == 1)
+ return SVNDIFF_V1;
+ else
+ return SVNDIFF_V0;
+}
+
/* ----- Text delta to svndiff ----- */
/* We make one of these and get it passed back to us in calls to the
@@ -46,7 +60,8 @@ struct encoder_baton {
svn_boolean_t header_done;
int version;
int compression_level;
- apr_pool_t *pool;
+ /* Pool for temporary allocations, will be cleared periodically. */
+ apr_pool_t *scratch_pool;
};
/* This is at least as big as the largest size for a single instruction. */
@@ -72,7 +87,7 @@ static svn_error_t *
send_simple_insertion_window(svn_txdelta_window_t *window,
struct encoder_baton *eb)
{
- unsigned char headers[4 + 5 * SVN__MAX_ENCODED_UINT_LEN
+ unsigned char headers[SVNDIFF_HEADER_SIZE + 5 * SVN__MAX_ENCODED_UINT_LEN
+ MAX_INSTRUCTION_LEN];
unsigned char ibuf[MAX_INSTRUCTION_LEN];
unsigned char *header_current;
@@ -89,11 +104,8 @@ send_simple_insertion_window(svn_txdelta
if (!eb->header_done)
{
eb->header_done = TRUE;
- headers[0] = 'S';
- headers[1] = 'V';
- headers[2] = 'N';
- headers[3] = (unsigned char)eb->version;
- header_current = headers + 4;
+ memcpy(headers, get_svndiff_header(eb->version), SVNDIFF_HEADER_SIZE);
+ header_current = headers + SVNDIFF_HEADER_SIZE;
}
else
{
@@ -135,58 +147,28 @@ send_simple_insertion_window(svn_txdelta
return SVN_NO_ERROR;
}
+/* Encodes delta window WINDOW to svndiff-format.
+ The svndiff version is VERSION. COMPRESSION_LEVEL is the zlib
+ compression level to use.
+ Returned values will be allocated in POOL or refer to *WINDOW
+ fields. */
static svn_error_t *
-window_handler(svn_txdelta_window_t *window, void *baton)
+encode_window(svn_stringbuf_t **instructions_p,
+ svn_stringbuf_t **header_p,
+ const svn_string_t **newdata_p,
+ svn_txdelta_window_t *window,
+ int version,
+ int compression_level,
+ apr_pool_t *pool)
{
- struct encoder_baton *eb = baton;
- apr_pool_t *pool;
svn_stringbuf_t *instructions;
- svn_stringbuf_t *i1;
svn_stringbuf_t *header;
const svn_string_t *newdata;
unsigned char ibuf[MAX_INSTRUCTION_LEN], *ip;
const svn_txdelta_op_t *op;
- apr_size_t len;
-
- /* use specialized code if there is no source */
- if (window && !window->src_ops && window->num_ops == 1 && !eb->version)
- return svn_error_trace(send_simple_insertion_window(window, eb));
-
- /* Make sure we write the header. */
- if (!eb->header_done)
- {
- char svnver[4] = {'S','V','N','\0'};
- len = 4;
- svnver[3] = (char)eb->version;
- SVN_ERR(svn_stream_write(eb->output, svnver, &len));
- eb->header_done = TRUE;
- }
-
- if (window == NULL)
- {
- svn_stream_t *output = eb->output;
-
- /* We're done; clean up.
-
- We clean our pool first. Given that the output stream was passed
- TO us, we'll assume it has a longer lifetime, and that it will not
- be affected by our pool destruction.
-
- The contrary point of view (close the stream first): that could
- tell our user that everything related to the output stream is done,
- and a cleanup of the user pool should occur. However, that user
- pool could include the subpool we created for our work (eb->pool),
- which would then make our call to svn_pool_destroy() puke.
- */
- svn_pool_destroy(eb->pool);
-
- return svn_stream_close(output);
- }
/* create the necessary data buffers */
- pool = svn_pool_create(eb->pool);
instructions = svn_stringbuf_create_empty(pool);
- i1 = svn_stringbuf_create_empty(pool);
header = svn_stringbuf_create_empty(pool);
/* Encode the instructions. */
@@ -213,21 +195,21 @@ window_handler(svn_txdelta_window_t *win
append_encoded_int(header, window->sview_offset);
append_encoded_int(header, window->sview_len);
append_encoded_int(header, window->tview_len);
- if (eb->version == 1)
+ if (version == 1)
{
- SVN_ERR(svn__compress(instructions, i1, eb->compression_level));
- instructions = i1;
+ svn_stringbuf_t *compressed_instructions;
+ compressed_instructions = svn_stringbuf_create_empty(pool);
+ SVN_ERR(svn__compress(instructions->data, instructions->len,
+ compressed_instructions, compression_level));
+ instructions = compressed_instructions;
}
append_encoded_int(header, instructions->len);
- if (eb->version == 1)
+ if (version == 1)
{
svn_stringbuf_t *compressed = svn_stringbuf_create_empty(pool);
- svn_stringbuf_t *original = svn_stringbuf_create_empty(pool);
- original->data = (char *)window->new_data->data; /* won't be modified */
- original->len = window->new_data->len;
- original->blocksize = window->new_data->len + 1;
- SVN_ERR(svn__compress(original, compressed, eb->compression_level));
+ SVN_ERR(svn__compress(window->new_data->data, window->new_data->len,
+ compressed, compression_level));
newdata = svn_stringbuf__morph_into_string(compressed);
}
else
@@ -235,6 +217,51 @@ window_handler(svn_txdelta_window_t *win
append_encoded_int(header, newdata->len);
+ *instructions_p = instructions;
+ *header_p = header;
+ *newdata_p = newdata;
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+window_handler(svn_txdelta_window_t *window, void *baton)
+{
+ struct encoder_baton *eb = baton;
+ apr_size_t len;
+ svn_stringbuf_t *instructions;
+ svn_stringbuf_t *header;
+ const svn_string_t *newdata;
+
+ /* use specialized code if there is no source */
+ if (window && !window->src_ops && window->num_ops == 1 && !eb->version)
+ return svn_error_trace(send_simple_insertion_window(window, eb));
+
+ /* Make sure we write the header. */
+ if (!eb->header_done)
+ {
+ len = SVNDIFF_HEADER_SIZE;
+ SVN_ERR(svn_stream_write(eb->output, get_svndiff_header(eb->version),
+ &len));
+ eb->header_done = TRUE;
+ }
+
+ if (window == NULL)
+ {
+ /* We're done; clean up. */
+ SVN_ERR(svn_stream_close(eb->output));
+
+ svn_pool_destroy(eb->scratch_pool);
+
+ return SVN_NO_ERROR;
+ }
+
+ svn_pool_clear(eb->scratch_pool);
+
+ SVN_ERR(encode_window(&instructions, &header, &newdata, window,
+ eb->version, eb->compression_level,
+ eb->scratch_pool));
+
/* Write out the window. */
len = header->len;
SVN_ERR(svn_stream_write(eb->output, header->data, &len));
@@ -249,7 +276,6 @@ window_handler(svn_txdelta_window_t *win
SVN_ERR(svn_stream_write(eb->output, newdata->data, &len));
}
- svn_pool_destroy(pool);
return SVN_NO_ERROR;
}
@@ -261,13 +287,12 @@ svn_txdelta_to_svndiff3(svn_txdelta_wind
int compression_level,
apr_pool_t *pool)
{
- apr_pool_t *subpool = svn_pool_create(pool);
struct encoder_baton *eb;
- eb = apr_palloc(subpool, sizeof(*eb));
+ eb = apr_palloc(pool, sizeof(*eb));
eb->output = output;
eb->header_done = FALSE;
- eb->pool = subpool;
+ eb->scratch_pool = svn_pool_create(pool);
eb->version = svndiff_version;
eb->compression_level = compression_level;
@@ -334,6 +359,17 @@ struct decode_baton
/* svndiff version in use by delta. */
unsigned char version;
+
+ /* Length of parsed delta window header. 0 if window is not parsed yet. */
+ apr_size_t window_header_len;
+
+ /* Five integer fields of parsed delta window header. Valid only if
+ WINDOW_HEADER_LEN > 0 */
+ svn_filesize_t sview_offset;
+ apr_size_t sview_len;
+ apr_size_t tview_len;
+ apr_size_t inslen;
+ apr_size_t newlen;
};
@@ -360,7 +396,7 @@ decode_size(apr_size_t *val,
const unsigned char *result = svn__decode_uint(&temp, p, end);
if (temp > APR_SIZE_MAX)
return NULL;
-
+
*val = (apr_size_t)temp;
return result;
}
@@ -483,21 +519,6 @@ count_and_verify_instructions(int *ninst
return SVN_NO_ERROR;
}
-static svn_error_t *
-zlib_decode(const unsigned char *in, apr_size_t inLen, svn_stringbuf_t *out,
- apr_size_t limit)
-{
- /* construct a fake string buffer as parameter to svn__decompress.
- This is fine as that function never writes to it. */
- svn_stringbuf_t compressed;
- compressed.pool = NULL;
- compressed.data = (char *)in;
- compressed.len = inLen;
- compressed.blocksize = inLen + 1;
-
- return svn__decompress(&compressed, out, limit);
-}
-
/* Given the five integer fields of a window header and a pointer to
the remainder of the window contents, fill in a delta window
structure *WINDOW. New allocations will be performed in POOL;
@@ -513,7 +534,7 @@ decode_window(svn_txdelta_window_t *wind
int ninst;
apr_size_t npos;
svn_txdelta_op_t *ops, *op;
- svn_string_t *new_data = apr_palloc(pool, sizeof(*new_data));
+ svn_string_t *new_data;
window->sview_offset = sview_offset;
window->sview_len = sview_len;
@@ -526,28 +547,22 @@ decode_window(svn_txdelta_window_t *wind
svn_stringbuf_t *instout = svn_stringbuf_create_empty(pool);
svn_stringbuf_t *ndout = svn_stringbuf_create_empty(pool);
- SVN_ERR(zlib_decode(insend, newlen, ndout,
- SVN_DELTA_WINDOW_SIZE));
- SVN_ERR(zlib_decode(data, insend - data, instout,
- MAX_INSTRUCTION_SECTION_LEN));
+ SVN_ERR(svn__decompress(insend, newlen, ndout,
+ SVN_DELTA_WINDOW_SIZE));
+ SVN_ERR(svn__decompress(data, insend - data, instout,
+ MAX_INSTRUCTION_SECTION_LEN));
newlen = ndout->len;
data = (unsigned char *)instout->data;
insend = (unsigned char *)instout->data + instout->len;
- new_data->data = (const char *) ndout->data;
- new_data->len = newlen;
+ new_data = svn_stringbuf__morph_into_string(ndout);
}
else
{
/* Copy the data because an svn_string_t must have the invariant
data[len]=='\0'. */
- char *buf = apr_palloc(pool, newlen + 1);
-
- memcpy(buf, insend, newlen);
- buf[newlen] = '\0';
- new_data->data = buf;
- new_data->len = newlen;
+ new_data = svn_string_ncreate((const char*)insend, newlen, pool);
}
/* Count the instructions and make sure they are all valid. */
@@ -578,10 +593,6 @@ decode_window(svn_txdelta_window_t *wind
return SVN_NO_ERROR;
}
-static const char SVNDIFF_V0[] = { 'S', 'V', 'N', 0 };
-static const char SVNDIFF_V1[] = { 'S', 'V', 'N', 1 };
-#define SVNDIFF_HEADER_SIZE (sizeof(SVNDIFF_V0))
-
static svn_error_t *
write_handler(void *baton,
const char *buffer,
@@ -589,8 +600,6 @@ write_handler(void *baton,
{
struct decode_baton *db = (struct decode_baton *) baton;
const unsigned char *p, *end;
- svn_filesize_t sview_offset;
- apr_size_t sview_len, tview_len, inslen, newlen, remaining;
apr_size_t buflen = *len;
/* Chew up four bytes at the beginning for the header. */
@@ -628,90 +637,114 @@ write_handler(void *baton,
while (1)
{
- apr_pool_t *newpool;
svn_txdelta_window_t window;
/* Read the header, if we have enough bytes for that. */
p = (const unsigned char *) db->buffer->data;
end = (const unsigned char *) db->buffer->data + db->buffer->len;
- p = decode_file_offset(&sview_offset, p, end);
- if (p == NULL)
- return SVN_NO_ERROR;
-
- p = decode_size(&sview_len, p, end);
- if (p == NULL)
- return SVN_NO_ERROR;
-
- p = decode_size(&tview_len, p, end);
- if (p == NULL)
- return SVN_NO_ERROR;
-
- p = decode_size(&inslen, p, end);
- if (p == NULL)
- return SVN_NO_ERROR;
-
- p = decode_size(&newlen, p, end);
- if (p == NULL)
- return SVN_NO_ERROR;
-
- if (tview_len > SVN_DELTA_WINDOW_SIZE ||
- sview_len > SVN_DELTA_WINDOW_SIZE ||
- /* for svndiff1, newlen includes the original length */
- newlen > SVN_DELTA_WINDOW_SIZE + SVN__MAX_ENCODED_UINT_LEN ||
- inslen > MAX_INSTRUCTION_SECTION_LEN)
- return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
- _("Svndiff contains a too-large window"));
-
- /* Check for integer overflow. */
- if (sview_offset < 0 || inslen + newlen < inslen
- || sview_len + tview_len < sview_len
- || (apr_size_t)sview_offset + sview_len < (apr_size_t)sview_offset)
- return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
- _("Svndiff contains corrupt window header"));
-
- /* Check for source windows which slide backwards. */
- if (sview_len > 0
- && (sview_offset < db->last_sview_offset
+ if (db->window_header_len == 0)
+ {
+ svn_filesize_t sview_offset;
+ apr_size_t sview_len, tview_len, inslen, newlen;
+ const unsigned char *hdr_start = p;
+
+ p = decode_file_offset(&sview_offset, p, end);
+ if (p == NULL)
+ break;
+
+ p = decode_size(&sview_len, p, end);
+ if (p == NULL)
+ break;
+
+ p = decode_size(&tview_len, p, end);
+ if (p == NULL)
+ break;
+
+ p = decode_size(&inslen, p, end);
+ if (p == NULL)
+ break;
+
+ p = decode_size(&newlen, p, end);
+ if (p == NULL)
+ break;
+
+ if (tview_len > SVN_DELTA_WINDOW_SIZE ||
+ sview_len > SVN_DELTA_WINDOW_SIZE ||
+ /* for svndiff1, newlen includes the original length */
+ newlen > SVN_DELTA_WINDOW_SIZE + SVN__MAX_ENCODED_UINT_LEN ||
+ inslen > MAX_INSTRUCTION_SECTION_LEN)
+ return svn_error_create(
+ SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
+ _("Svndiff contains a too-large window"));
+
+ /* Check for integer overflow. */
+ if (sview_offset < 0 || inslen + newlen < inslen
+ || sview_len + tview_len < sview_len
+ || (apr_size_t)sview_offset + sview_len < (apr_size_t)sview_offset)
+ return svn_error_create(
+ SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
+ _("Svndiff contains corrupt window header"));
+
+ /* Check for source windows which slide backwards. */
+ if (sview_len > 0
+ && (sview_offset < db->last_sview_offset
|| (sview_offset + sview_len
< db->last_sview_offset + db->last_sview_len)))
- return svn_error_create
- (SVN_ERR_SVNDIFF_BACKWARD_VIEW, NULL,
- _("Svndiff has backwards-sliding source views"));
+ return svn_error_create(
+ SVN_ERR_SVNDIFF_BACKWARD_VIEW, NULL,
+ _("Svndiff has backwards-sliding source views"));
+
+ /* Remember parsed window header. */
+ db->window_header_len = p - hdr_start;
+ db->sview_offset = sview_offset;
+ db->sview_len = sview_len;
+ db->tview_len = tview_len;
+ db->inslen = inslen;
+ db->newlen = newlen;
+ }
+ else
+ {
+ /* Skip already parsed window header. */
+ p += db->window_header_len;
+ }
/* Wait for more data if we don't have enough bytes for the
whole window. */
- if ((apr_size_t) (end - p) < inslen + newlen)
+ if ((apr_size_t) (end - p) < db->inslen + db->newlen)
return SVN_NO_ERROR;
/* Decode the window and send it off. */
- SVN_ERR(decode_window(&window, sview_offset, sview_len, tview_len,
- inslen, newlen, p, db->subpool,
- db->version));
+ SVN_ERR(decode_window(&window, db->sview_offset, db->sview_len,
+ db->tview_len, db->inslen, db->newlen, p,
+ db->subpool, db->version));
SVN_ERR(db->consumer_func(&window, db->consumer_baton));
- /* Make a new subpool and buffer, saving aside the remaining
- data in the old buffer. */
- newpool = svn_pool_create(db->pool);
- p += inslen + newlen;
- remaining = db->buffer->data + db->buffer->len - (const char *) p;
- db->buffer =
- svn_stringbuf_ncreate((const char *) p, remaining, newpool);
+ p += db->inslen + db->newlen;
+
+ /* Remove processed data from the buffer. */
+ svn_stringbuf_remove(db->buffer, 0, db->buffer->len - (end - p));
+
+ /* Reset window header length. */
+ db->window_header_len = 0;
/* Remember the offset and length of the source view for next time. */
- db->last_sview_offset = sview_offset;
- db->last_sview_len = sview_len;
+ db->last_sview_offset = db->sview_offset;
+ db->last_sview_len = db->sview_len;
- /* We've copied stuff out of the old pool. Toss that pool and use
- our new pool.
- ### might be nice to avoid the copy and just use svn_pool_clear
- ### to get rid of whatever the "other stuff" is. future project...
- */
- svn_pool_destroy(db->subpool);
- db->subpool = newpool;
+ /* Clear subpool. */
+ svn_pool_clear(db->subpool);
}
- /* NOTREACHED */
+ /* At this point we processed all integral windows and DB->BUFFER is empty
+ or contains partially read window header.
+ Check that unprocessed data is not larger than theoretical maximum
+ window header size. */
+ if (db->buffer->len > 5 * SVN__MAX_ENCODED_UINT_LEN)
+ return svn_error_create(SVN_ERR_SVNDIFF_CORRUPT_WINDOW, NULL,
+ _("Svndiff contains a too-large window header"));
+
+ return SVN_NO_ERROR;
}
/* Minimal svn_stream_t write handler, doing nothing */
@@ -749,23 +782,25 @@ svn_txdelta_parse_svndiff(svn_txdelta_wi
svn_boolean_t error_on_early_close,
apr_pool_t *pool)
{
- apr_pool_t *subpool = svn_pool_create(pool);
- struct decode_baton *db = apr_palloc(pool, sizeof(*db));
svn_stream_t *stream;
- db->consumer_func = handler;
- db->consumer_baton = handler_baton;
- db->pool = subpool;
- db->subpool = svn_pool_create(subpool);
- db->buffer = svn_stringbuf_create_empty(db->subpool);
- db->last_sview_offset = 0;
- db->last_sview_len = 0;
- db->header_bytes = 0;
- db->error_on_early_close = error_on_early_close;
- stream = svn_stream_create(db, pool);
-
if (handler != svn_delta_noop_window_handler)
{
+ apr_pool_t *subpool = svn_pool_create(pool);
+ struct decode_baton *db = apr_palloc(pool, sizeof(*db));
+
+ db->consumer_func = handler;
+ db->consumer_baton = handler_baton;
+ db->pool = subpool;
+ db->subpool = svn_pool_create(subpool);
+ db->buffer = svn_stringbuf_create_empty(db->pool);
+ db->last_sview_offset = 0;
+ db->last_sview_len = 0;
+ db->header_bytes = 0;
+ db->error_on_early_close = error_on_early_close;
+ db->window_header_len = 0;
+ stream = svn_stream_create(db, pool);
+
svn_stream_set_write(stream, write_handler);
svn_stream_set_close(stream, close_handler);
}
@@ -773,6 +808,7 @@ svn_txdelta_parse_svndiff(svn_txdelta_wi
{
/* And else we just ignore everything as efficiently as we can.
by only hooking a no-op handler */
+ stream = svn_stream_create(NULL, pool);
svn_stream_set_write(stream, noop_write_handler);
}
return stream;
@@ -796,7 +832,7 @@ read_one_byte(unsigned char *byte, svn_s
return SVN_NO_ERROR;
}
-/* Read and decode one integer from STREAM into *SIZE.
+/* Read and decode one integer from STREAM into *SIZE.
Increment *BYTE_COUNTER by the number of chars we have read. */
static svn_error_t *
read_one_size(apr_size_t *size,
Modified: subversion/branches/fsx-1.10/subversion/libsvn_delta/text_delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_delta/text_delta.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_delta/text_delta.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_delta/text_delta.c Sun Jun 14 20:58:10 2015
@@ -180,8 +180,7 @@ svn_txdelta_window_dup(const svn_txdelta
build_baton.num_ops = window->num_ops;
build_baton.src_ops = window->src_ops;
build_baton.ops_size = window->num_ops;
- build_baton.ops = apr_palloc(pool, ops_size);
- memcpy(build_baton.ops, window->ops, ops_size);
+ build_baton.ops = apr_pmemdup(pool, window->ops, ops_size);
build_baton.new_data =
svn_stringbuf_create_from_string(window->new_data, pool);
Modified: subversion/branches/fsx-1.10/subversion/libsvn_diff/binary_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_diff/binary_diff.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_diff/binary_diff.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_diff/binary_diff.c Sun Jun 14 20:58:10 2015
@@ -42,7 +42,6 @@ create_compressed(apr_file_t **result,
{
svn_stream_t *compressed;
svn_filesize_t bytes_read = 0;
- apr_finfo_t finfo;
apr_size_t rd;
SVN_ERR(svn_io_open_uniquely_named(result, NULL, NULL, "diffgz",
@@ -56,7 +55,7 @@ create_compressed(apr_file_t **result,
if (original_stream)
do
{
- char buffer[SVN_STREAM_CHUNK_SIZE];
+ char buffer[SVN__STREAM_CHUNK_SIZE];
rd = sizeof(buffer);
if (cancel_func)
@@ -67,7 +66,7 @@ create_compressed(apr_file_t **result,
bytes_read += rd;
SVN_ERR(svn_stream_write(compressed, buffer, &rd));
}
- while(rd == SVN_STREAM_CHUNK_SIZE);
+ while(rd == SVN__STREAM_CHUNK_SIZE);
else
{
apr_size_t zero = 0;
@@ -77,8 +76,7 @@ create_compressed(apr_file_t **result,
SVN_ERR(svn_stream_close(compressed)); /* Flush compression */
*full_size = bytes_read;
- SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE, *result, scratch_pool));
- *compressed_size = finfo.size;
+ SVN_ERR(svn_io_file_size_get(compressed_size, *result, scratch_pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/fsx-1.10/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_diff/diff_file.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_diff/diff_file.c Sun Jun 14 20:58:10 2015
@@ -777,7 +777,6 @@ datasources_open(void *baton,
{
svn_diff__file_baton_t *file_baton = baton;
struct file_info files[4];
- apr_finfo_t finfo[4];
apr_off_t length[4];
#ifndef SVN_DISABLE_PREFIX_SUFFIX_SCANNING
svn_boolean_t reached_one_eof;
@@ -792,14 +791,14 @@ datasources_open(void *baton,
/* Open datasources and read first chunk */
for (i = 0; i < datasources_len; i++)
{
+ svn_filesize_t filesize;
struct file_info *file
= &file_baton->files[datasource_to_index(datasources[i])];
SVN_ERR(svn_io_file_open(&file->file, file->path,
APR_READ, APR_OS_DEFAULT, file_baton->pool));
- SVN_ERR(svn_io_file_info_get(&finfo[i], APR_FINFO_SIZE,
- file->file, file_baton->pool));
- file->size = finfo[i].size;
- length[i] = finfo[i].size > CHUNK_SIZE ? CHUNK_SIZE : finfo[i].size;
+ SVN_ERR(svn_io_file_size_get(&filesize, file->file, file_baton->pool));
+ file->size = filesize;
+ length[i] = filesize > CHUNK_SIZE ? CHUNK_SIZE : filesize;
file->buffer = apr_palloc(file_baton->pool, (apr_size_t) length[i]);
SVN_ERR(read_chunk(file->file, file->buffer,
length[i], 0, file_baton->pool));
@@ -1956,7 +1955,7 @@ typedef struct context_saver_t {
const char **data; /* const char *data[context_size] */
apr_size_t *len; /* apr_size_t len[context_size] */
apr_size_t next_slot;
- apr_size_t total_written;
+ apr_ssize_t total_writes;
} context_saver_t;
@@ -1972,7 +1971,7 @@ context_saver_stream_write(void *baton,
cs->data[cs->next_slot] = data;
cs->len[cs->next_slot] = *len;
cs->next_slot = (cs->next_slot + 1) % cs->context_size;
- cs->total_written++;
+ cs->total_writes++;
}
return SVN_NO_ERROR;
}
@@ -2252,7 +2251,7 @@ output_conflict_with_context(svn_diff3__
trailing context)? If so, flush it. */
if (btn->output_stream == btn->context_saver->stream)
{
- if (btn->context_saver->total_written > btn->context_size)
+ if (btn->context_saver->total_writes > btn->context_size)
SVN_ERR(svn_stream_puts(btn->real_output_stream, "@@\n"));
SVN_ERR(flush_context_saver(btn->context_saver, btn->real_output_stream));
}
@@ -2360,7 +2359,7 @@ svn_diff_file_output_merge3(svn_stream_t
svn_diff_conflict_display_style_t style,
svn_cancel_func_t cancel_func,
void *cancel_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
svn_diff3__file_output_baton_t baton;
apr_file_t *file[3];
@@ -2376,7 +2375,7 @@ svn_diff_file_output_merge3(svn_stream_t
baton.context_size = SVN_DIFF__UNIFIED_CONTEXT_SIZE;
if (conflicts_only)
{
- baton.pool = svn_pool_create(pool);
+ baton.pool = svn_pool_create(scratch_pool);
make_context_saver(&baton);
baton.real_output_stream = output_stream;
}
@@ -2387,22 +2386,22 @@ svn_diff_file_output_merge3(svn_stream_t
baton.path[2] = latest_path;
SVN_ERR(svn_utf_cstring_from_utf8(&baton.conflict_modified,
conflict_modified ? conflict_modified
- : apr_psprintf(pool, "<<<<<<< %s",
+ : apr_psprintf(scratch_pool, "<<<<<<< %s",
modified_path),
- pool));
+ scratch_pool));
SVN_ERR(svn_utf_cstring_from_utf8(&baton.conflict_original,
conflict_original ? conflict_original
- : apr_psprintf(pool, "||||||| %s",
+ : apr_psprintf(scratch_pool, "||||||| %s",
original_path),
- pool));
+ scratch_pool));
SVN_ERR(svn_utf_cstring_from_utf8(&baton.conflict_separator,
conflict_separator ? conflict_separator
- : "=======", pool));
+ : "=======", scratch_pool));
SVN_ERR(svn_utf_cstring_from_utf8(&baton.conflict_latest,
conflict_latest ? conflict_latest
- : apr_psprintf(pool, ">>>>>>> %s",
+ : apr_psprintf(scratch_pool, ">>>>>>> %s",
latest_path),
- pool));
+ scratch_pool));
baton.conflict_style = style;
@@ -2413,7 +2412,7 @@ svn_diff_file_output_merge3(svn_stream_t
SVN_ERR(map_or_read_file(&file[idx],
MMAP_T_ARG(mm[idx])
&baton.buffer[idx], &size,
- baton.path[idx], pool));
+ baton.path[idx], scratch_pool));
baton.curp[idx] = baton.buffer[idx];
baton.endp[idx] = baton.buffer[idx];
@@ -2454,7 +2453,7 @@ svn_diff_file_output_merge3(svn_stream_t
if (file[idx])
{
- SVN_ERR(svn_io_file_close(file[idx], pool));
+ SVN_ERR(svn_io_file_close(file[idx], scratch_pool));
}
}
Modified: subversion/branches/fsx-1.10/subversion/libsvn_diff/diff_memory.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_diff/diff_memory.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_diff/diff_memory.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_diff/diff_memory.c Sun Jun 14 20:58:10 2015
@@ -622,7 +622,7 @@ svn_diff_mem_string_output_unified3(svn_
int context_size,
svn_cancel_func_t cancel_func,
void *cancel_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
if (svn_diff_contains_diffs(diff))
@@ -631,9 +631,9 @@ svn_diff_mem_string_output_unified3(svn_
memset(&baton, 0, sizeof(baton));
baton.output_stream = output_stream;
- baton.pool = svn_pool_create(pool);
+ baton.pool = svn_pool_create(scratch_pool);
baton.header_encoding = header_encoding;
- baton.hunk = svn_stringbuf_create_empty(pool);
+ baton.hunk = svn_stringbuf_create_empty(scratch_pool);
baton.hunk_delimiter = hunk_delimiter;
baton.no_newline_string
= (hunk_delimiter == NULL || strcmp(hunk_delimiter, "##") != 0)
@@ -644,22 +644,22 @@ svn_diff_mem_string_output_unified3(svn_
SVN_ERR(svn_utf_cstring_from_utf8_ex2
(&(baton.prefix_str[unified_output_context]), " ",
- header_encoding, pool));
+ header_encoding, scratch_pool));
SVN_ERR(svn_utf_cstring_from_utf8_ex2
(&(baton.prefix_str[unified_output_delete]), "-",
- header_encoding, pool));
+ header_encoding, scratch_pool));
SVN_ERR(svn_utf_cstring_from_utf8_ex2
(&(baton.prefix_str[unified_output_insert]), "+",
- header_encoding, pool));
+ header_encoding, scratch_pool));
- fill_source_tokens(&baton.sources[0], original, pool);
- fill_source_tokens(&baton.sources[1], modified, pool);
+ fill_source_tokens(&baton.sources[0], original, scratch_pool);
+ fill_source_tokens(&baton.sources[1], modified, scratch_pool);
if (with_diff_header)
{
SVN_ERR(svn_diff__unidiff_write_header(
output_stream, header_encoding,
- original_header, modified_header, pool));
+ original_header, modified_header, scratch_pool));
}
SVN_ERR(svn_diff_output2(diff, &baton,
@@ -688,7 +688,7 @@ typedef struct context_saver_t {
const char **data; /* const char *data[context_size] */
apr_size_t *len; /* apr_size_t len[context_size] */
apr_size_t next_slot;
- apr_size_t total_written;
+ apr_ssize_t total_writes;
} context_saver_t;
@@ -701,7 +701,7 @@ context_saver_stream_write(void *baton,
cs->data[cs->next_slot] = data;
cs->len[cs->next_slot] = *len;
cs->next_slot = (cs->next_slot + 1) % cs->context_size;
- cs->total_written++;
+ cs->total_writes++;
return SVN_NO_ERROR;
}
@@ -822,13 +822,11 @@ make_trailing_context_printer(merge_outp
static svn_error_t *
-output_merge_token_range(apr_size_t *lines_printed_p,
- merge_output_baton_t *btn,
+output_merge_token_range(merge_output_baton_t *btn,
int idx, apr_off_t first,
apr_off_t length)
{
apr_array_header_t *tokens = btn->sources[idx].tokens;
- apr_size_t lines_printed = 0;
for (; length > 0 && first < tokens->nelts; length--, first++)
{
@@ -838,12 +836,8 @@ output_merge_token_range(apr_size_t *lin
/* Note that the trailing context printer assumes that
svn_stream_write is called exactly once per line. */
SVN_ERR(svn_stream_write(btn->output_stream, token->data, &len));
- lines_printed++;
}
- if (lines_printed_p)
- *lines_printed_p = lines_printed;
-
return SVN_NO_ERROR;
}
@@ -866,7 +860,7 @@ output_common_modified(void *baton,
apr_off_t modified_start, apr_off_t modified_length,
apr_off_t latest_start, apr_off_t latest_length)
{
- return output_merge_token_range(NULL, baton, 1/*modified*/,
+ return output_merge_token_range(baton, 1/*modified*/,
modified_start, modified_length);
}
@@ -876,7 +870,7 @@ output_latest(void *baton,
apr_off_t modified_start, apr_off_t modified_length,
apr_off_t latest_start, apr_off_t latest_length)
{
- return output_merge_token_range(NULL, baton, 2/*latest*/,
+ return output_merge_token_range(baton, 2/*latest*/,
latest_start, latest_length);
}
@@ -920,26 +914,26 @@ output_conflict(void *baton,
style == svn_diff_conflict_display_modified_original_latest)
{
SVN_ERR(output_merge_marker(btn, 1/*modified*/));
- SVN_ERR(output_merge_token_range(NULL, btn, 1/*modified*/,
+ SVN_ERR(output_merge_token_range(btn, 1/*modified*/,
modified_start, modified_length));
if (style == svn_diff_conflict_display_modified_original_latest)
{
SVN_ERR(output_merge_marker(btn, 0/*original*/));
- SVN_ERR(output_merge_token_range(NULL, btn, 0/*original*/,
+ SVN_ERR(output_merge_token_range(btn, 0/*original*/,
original_start, original_length));
}
SVN_ERR(output_merge_marker(btn, 2/*separator*/));
- SVN_ERR(output_merge_token_range(NULL, btn, 2/*latest*/,
+ SVN_ERR(output_merge_token_range(btn, 2/*latest*/,
latest_start, latest_length));
SVN_ERR(output_merge_marker(btn, 3/*latest (end)*/));
}
else if (style == svn_diff_conflict_display_modified)
- SVN_ERR(output_merge_token_range(NULL, btn, 1/*modified*/,
+ SVN_ERR(output_merge_token_range(btn, 1/*modified*/,
modified_start, modified_length));
else if (style == svn_diff_conflict_display_latest)
- SVN_ERR(output_merge_token_range(NULL, btn, 2/*latest*/,
+ SVN_ERR(output_merge_token_range(btn, 2/*latest*/,
latest_start, latest_length));
else /* unknown style */
SVN_ERR_MALFUNCTION();
@@ -983,7 +977,7 @@ output_conflict_with_context(void *baton
trailing context)? If so, flush it. */
if (btn->output_stream == btn->context_saver->stream)
{
- if (btn->context_saver->total_written > btn->context_size)
+ if (btn->context_saver->total_writes > btn->context_size)
SVN_ERR(svn_stream_puts(btn->real_output_stream, "@@\n"));
SVN_ERR(flush_context_saver(btn->context_saver, btn->real_output_stream));
}
@@ -995,17 +989,17 @@ output_conflict_with_context(void *baton
SVN_ERR(output_conflict_with_context_marker(btn, btn->markers[1],
modified_start,
modified_length));
- SVN_ERR(output_merge_token_range(NULL, btn, 1/*modified*/,
+ SVN_ERR(output_merge_token_range(btn, 1/*modified*/,
modified_start, modified_length));
SVN_ERR(output_conflict_with_context_marker(btn, btn->markers[0],
original_start,
original_length));
- SVN_ERR(output_merge_token_range(NULL, btn, 0/*original*/,
+ SVN_ERR(output_merge_token_range(btn, 0/*original*/,
original_start, original_length));
SVN_ERR(output_merge_marker(btn, 2/*separator*/));
- SVN_ERR(output_merge_token_range(NULL, btn, 2/*latest*/,
+ SVN_ERR(output_merge_token_range(btn, 2/*latest*/,
latest_start, latest_length));
SVN_ERR(output_conflict_with_context_marker(btn, btn->markers[3],
latest_start,
@@ -1066,7 +1060,7 @@ svn_diff_mem_string_output_merge3(svn_st
svn_diff_conflict_display_style_t style,
svn_cancel_func_t cancel_func,
void *cancel_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
merge_output_baton_t btn;
const char *eol;
@@ -1080,16 +1074,16 @@ svn_diff_mem_string_output_merge3(svn_st
if (conflicts_only)
{
- btn.pool = svn_pool_create(pool);
+ btn.pool = svn_pool_create(scratch_pool);
make_context_saver(&btn);
btn.real_output_stream = output_stream;
}
else
btn.output_stream = output_stream;
- fill_source_tokens(&(btn.sources[0]), original, pool);
- fill_source_tokens(&(btn.sources[1]), modified, pool);
- fill_source_tokens(&(btn.sources[2]), latest, pool);
+ fill_source_tokens(&(btn.sources[0]), original, scratch_pool);
+ fill_source_tokens(&(btn.sources[1]), modified, scratch_pool);
+ fill_source_tokens(&(btn.sources[2]), latest, scratch_pool);
btn.conflict_style = style;
@@ -1110,22 +1104,22 @@ svn_diff_mem_string_output_merge3(svn_st
conflict_modified
? conflict_modified
: "<<<<<<< (modified)",
- pool));
+ scratch_pool));
SVN_ERR(svn_utf_cstring_from_utf8(&btn.markers[0],
conflict_original
? conflict_original
: "||||||| (original)",
- pool));
+ scratch_pool));
SVN_ERR(svn_utf_cstring_from_utf8(&btn.markers[2],
conflict_separator
? conflict_separator
: "=======",
- pool));
+ scratch_pool));
SVN_ERR(svn_utf_cstring_from_utf8(&btn.markers[3],
conflict_latest
? conflict_latest
: ">>>>>>> (latest)",
- pool));
+ scratch_pool));
SVN_ERR(svn_diff_output2(diff, &btn, vtable, cancel_func, cancel_baton));
if (conflicts_only)
Modified: subversion/branches/fsx-1.10/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_diff/parse-diff.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_diff/parse-diff.c Sun Jun 14 20:58:10 2015
@@ -532,7 +532,7 @@ parse_mergeinfo(svn_boolean_t *found_mer
}
else
SVN_ERR(err);
-
+
if (mergeinfo)
{
if (hunk->original_length > 0) /* reverse merges */
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs/editor.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs/editor.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs/editor.c Sun Jun 14 20:58:10 2015
@@ -249,7 +249,7 @@ can_modify(svn_fs_root_t *txn_root,
svn_fs_close_root(rev_root);
/* Has the target node changed in the future? */
- if (relation != svn_fs_node_same)
+ if (relation != svn_fs_node_unchanged)
{
/* Restarting the commit will base the txn on the future/new
revision, allowing the modification at REVISION. */
@@ -777,16 +777,24 @@ svn_fs__editor_commit(svn_revnum_t *revi
/* Clean up internal resources (eg. eb->root). This also allows the
editor infrastructure to know this editor is "complete". */
err = svn_editor_complete(editor);
+ if (err)
+ {
+ svn_fs_txn_t *txn = eb->txn;
+
+ eb->txn = NULL;
+ return svn_error_trace(svn_error_compose_create(
+ err,
+ svn_fs_abort_txn(txn, scratch_pool)));
+ }
/* Note: docco for svn_fs_commit_txn() states that CONFLICT_PATH will
be allocated in the txn's pool. But it lies. Regardless, we want
it placed into RESULT_POOL. */
- if (!err)
- err = svn_fs_commit_txn(&inner_conflict_path,
- revision,
- eb->txn,
- scratch_pool);
+ err = svn_fs_commit_txn(&inner_conflict_path,
+ revision,
+ eb->txn,
+ scratch_pool);
if (SVN_IS_VALID_REVNUM(*revision))
{
if (err)
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs/fs-loader.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs/fs-loader.c Sun Jun 14 20:58:10 2015
@@ -27,7 +27,6 @@
#include <apr_atomic.h>
#include <apr_hash.h>
#include <apr_md5.h>
-#include <apr_thread_mutex.h>
#include <apr_uuid.h>
#include <apr_strings.h>
@@ -140,7 +139,7 @@ load_module(fs_init_func_t *initfunc, co
_("Invalid name for FS type '%s'"),
name);
- libname = apr_psprintf(pool, "libsvn_fs_%s-%d.so.%d",
+ libname = apr_psprintf(pool, "libsvn_fs_%s-" SVN_DSO_SUFFIX_FMT,
name, SVN_VER_MAJOR, SVN_SOVERSION);
funcname = apr_psprintf(pool, "svn_fs_%s__init", name);
@@ -408,6 +407,11 @@ synchronized_initialize(void *baton, apr
svn_error_t *
svn_fs_initialize(apr_pool_t *pool)
{
+#if defined(SVN_USE_DSO) && APR_HAS_DSO
+ /* Ensure that DSO subsystem is initialized early as possible if
+ we're going to use it. */
+ SVN_ERR(svn_dso_initialize2());
+#endif
/* Protect against multiple calls. */
return svn_error_trace(svn_atomic__init_once(&common_pool_initialized,
synchronized_initialize,
@@ -436,6 +440,8 @@ default_warning_func(void *baton, svn_er
svn_error_t *
svn_fs__path_valid(const char *path, apr_pool_t *pool)
{
+ char *c;
+
/* UTF-8 encoded string without NULs. */
if (! svn_utf__cstring_is_valid(path))
{
@@ -452,6 +458,18 @@ svn_fs__path_valid(const char *path, apr
path);
}
+ /* Raise an error if PATH contains a newline because svn:mergeinfo and
+ friends can't handle them. Issue #4340 describes a similar problem
+ in the FSFS code itself.
+ */
+ c = strchr(path, '\n');
+ if (c)
+ {
+ return svn_error_createf(SVN_ERR_FS_PATH_SYNTAX, NULL,
+ _("Invalid control character '0x%02x' in path '%s'"),
+ (unsigned char)*c, svn_path_illegal_path_escape(path, pool));
+ }
+
/* That's good enough. */
return SVN_NO_ERROR;
}
@@ -542,19 +560,19 @@ svn_fs_upgrade2(const char *path,
void *notify_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
fs_library_vtable_t *vtable;
svn_fs_t *fs;
- SVN_ERR(fs_library_vtable(&vtable, path, pool));
- fs = fs_new(NULL, pool);
+ SVN_ERR(fs_library_vtable(&vtable, path, scratch_pool));
+ fs = fs_new(NULL, scratch_pool);
SVN_ERR(vtable->upgrade_fs(fs, path,
notify_func, notify_baton,
cancel_func, cancel_baton,
common_pool_lock,
- pool, common_pool));
+ scratch_pool, common_pool));
return SVN_NO_ERROR;
}
@@ -897,26 +915,48 @@ svn_fs_list_transactions(apr_array_heade
return svn_error_trace(fs->vtable->list_transactions(names_p, fs, pool));
}
+static svn_boolean_t
+is_internal_txn_prop(const char *name)
+{
+ return strcmp(name, SVN_FS__PROP_TXN_CHECK_LOCKS) == 0 ||
+ strcmp(name, SVN_FS__PROP_TXN_CHECK_OOD) == 0 ||
+ strcmp(name, SVN_FS__PROP_TXN_CLIENT_DATE) == 0;
+}
+
svn_error_t *
svn_fs_txn_prop(svn_string_t **value_p, svn_fs_txn_t *txn,
const char *propname, apr_pool_t *pool)
{
+ if (is_internal_txn_prop(propname))
+ {
+ *value_p = NULL;
+ return SVN_NO_ERROR;
+ }
+
return svn_error_trace(txn->vtable->get_prop(value_p, txn, propname, pool));
}
svn_error_t *
svn_fs_txn_proplist(apr_hash_t **table_p, svn_fs_txn_t *txn, apr_pool_t *pool)
{
- return svn_error_trace(txn->vtable->get_proplist(table_p, txn, pool));
+ SVN_ERR(txn->vtable->get_proplist(table_p, txn, pool));
+
+ /* Don't give away internal transaction properties. */
+ svn_hash_sets(*table_p, SVN_FS__PROP_TXN_CHECK_LOCKS, NULL);
+ svn_hash_sets(*table_p, SVN_FS__PROP_TXN_CHECK_OOD, NULL);
+ svn_hash_sets(*table_p, SVN_FS__PROP_TXN_CLIENT_DATE, NULL);
+
+ return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_change_txn_prop(svn_fs_txn_t *txn, const char *name,
const svn_string_t *value, apr_pool_t *pool)
{
- /* Silently drop attempts to modify the internal property. */
- if (!strcmp(name, SVN_FS__PROP_TXN_CLIENT_DATE))
- return SVN_NO_ERROR;
+ if (is_internal_txn_prop(name))
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+ _("Attempt to modify internal transaction "
+ "property '%s'"), name);
return svn_error_trace(txn->vtable->change_prop(txn, name, value, pool));
}
@@ -927,25 +967,14 @@ svn_fs_change_txn_props(svn_fs_txn_t *tx
{
int i;
- /* Silently drop attempts to modify the internal property. */
for (i = 0; i < props->nelts; ++i)
{
svn_prop_t *prop = &APR_ARRAY_IDX(props, i, svn_prop_t);
- if (!strcmp(prop->name, SVN_FS__PROP_TXN_CLIENT_DATE))
- {
- apr_array_header_t *reduced_props
- = apr_array_make(pool, props->nelts - 1, sizeof(svn_prop_t));
-
- for (i = 0; i < props->nelts; ++i)
- {
- prop = &APR_ARRAY_IDX(props, i, svn_prop_t);
- if (strcmp(prop->name, SVN_FS__PROP_TXN_CLIENT_DATE))
- APR_ARRAY_PUSH(reduced_props, svn_prop_t) = *prop;
- }
- props = reduced_props;
- break;
- }
+ if (is_internal_txn_prop(prop->name))
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+ _("Attempt to modify internal transaction "
+ "property '%s'"), prop->name);
}
return svn_error_trace(txn->vtable->change_props(txn, props, pool));
@@ -1111,7 +1140,7 @@ svn_error_t *
svn_fs_node_relation(svn_fs_node_relation_t *relation,
svn_fs_root_t *root_a, const char *path_a,
svn_fs_root_t *root_b, const char *path_b,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
/* Different repository types? */
if (root_a->fs != root_b->fs)
@@ -1120,9 +1149,10 @@ svn_fs_node_relation(svn_fs_node_relatio
return SVN_NO_ERROR;
}
- return svn_error_trace(root_a->vtable->node_relation(relation, root_a,
- path_a, root_b,
- path_b, pool));
+ return svn_error_trace(root_a->vtable->node_relation(relation,
+ root_a, path_a,
+ root_b, path_b,
+ scratch_pool));
}
svn_error_t *
@@ -1166,6 +1196,16 @@ svn_fs_node_proplist(apr_hash_t **table_
}
svn_error_t *
+svn_fs_node_has_props(svn_boolean_t *has_props,
+ svn_fs_root_t *root,
+ const char *path,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(root->vtable->node_has_props(has_props, root, path,
+ scratch_pool));
+}
+
+svn_error_t *
svn_fs_change_node_prop(svn_fs_root_t *root, const char *path,
const char *name, const svn_string_t *value,
apr_pool_t *pool)
@@ -1177,12 +1217,12 @@ svn_fs_change_node_prop(svn_fs_root_t *r
svn_error_t *
svn_fs_props_different(svn_boolean_t *changed_p, svn_fs_root_t *root1,
const char *path1, svn_fs_root_t *root2,
- const char *path2, apr_pool_t *pool)
+ const char *path2, apr_pool_t *scratch_pool)
{
return svn_error_trace(root1->vtable->props_changed(changed_p,
root1, path1,
root2, path2,
- TRUE, pool));
+ TRUE, scratch_pool));
}
svn_error_t *
@@ -1290,10 +1330,13 @@ svn_error_t *
svn_fs_dir_optimal_order(apr_array_header_t **ordered_p,
svn_fs_root_t *root,
apr_hash_t *entries,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
return svn_error_trace(root->vtable->dir_optimal_order(ordered_p, root,
- entries, pool));
+ entries,
+ result_pool,
+ scratch_pool));
}
svn_error_t *
@@ -1454,12 +1497,13 @@ svn_fs_apply_text(svn_stream_t **content
svn_error_t *
svn_fs_contents_different(svn_boolean_t *changed_p, svn_fs_root_t *root1,
const char *path1, svn_fs_root_t *root2,
- const char *path2, apr_pool_t *pool)
+ const char *path2, apr_pool_t *scratch_pool)
{
return svn_error_trace(root1->vtable->contents_changed(changed_p,
root1, path1,
root2, path2,
- TRUE, pool));
+ TRUE,
+ scratch_pool));
}
svn_error_t *
@@ -1617,20 +1661,24 @@ svn_fs_lock_many(svn_fs_t *fs,
target->token, "opaquelocktoken");
if (!err)
- for (c = target->token; *c && !err; c++)
- if (! svn_ctype_isascii(*c) || svn_ctype_iscntrl(*c))
+ {
+ for (c = target->token; *c && !err; c++)
+ if (! svn_ctype_isascii(*c) || svn_ctype_iscntrl(*c))
+ err = svn_error_createf(
+ SVN_ERR_FS_BAD_LOCK_TOKEN, NULL,
+ _("Lock token '%s' is not ASCII or is a "
+ "control character at byte %u"),
+ target->token,
+ (unsigned)(c - target->token));
+
+ /* strlen(token) == c - token. */
+ if (!err && !svn_xml_is_xml_safe(target->token,
+ c - target->token))
err = svn_error_createf(
- SVN_ERR_FS_BAD_LOCK_TOKEN, NULL,
- _("Lock token '%s' is not ASCII or is a "
- "control character at byte %u"),
- target->token,
- (unsigned)(c - target->token));
-
- /* strlen(token) == c - token. */
- if (!err && !svn_xml_is_xml_safe(target->token, c - target->token))
- err = svn_error_createf(SVN_ERR_FS_BAD_LOCK_TOKEN, NULL,
- _("Lock token URI '%s' is not XML-safe"),
- target->token);
+ SVN_ERR_FS_BAD_LOCK_TOKEN, NULL,
+ _("Lock token URI '%s' is not XML-safe"),
+ target->token);
+ }
}
if (err)
@@ -1691,7 +1739,7 @@ svn_fs_lock(svn_lock_t **lock, svn_fs_t
apr_pool_t *pool)
{
apr_hash_t *targets = apr_hash_make(pool);
- svn_fs_lock_target_t target;
+ svn_fs_lock_target_t target;
svn_error_t *err;
struct lock_baton_t baton = {0};
@@ -1710,7 +1758,7 @@ svn_fs_lock(svn_lock_t **lock, svn_fs_t
svn_error_compose(err, baton.fs_err);
else if (!err)
err = baton.fs_err;
-
+
return svn_error_trace(err);
}
@@ -1723,9 +1771,10 @@ svn_fs_generate_lock_token(const char **
svn_fs_lock_target_t *
svn_fs_lock_target_create(const char *token,
svn_revnum_t current_rev,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
- svn_fs_lock_target_t *target = apr_palloc(pool, sizeof(svn_fs_lock_target_t));
+ svn_fs_lock_target_t *target = apr_palloc(result_pool,
+ sizeof(svn_fs_lock_target_t));
target->token = token;
target->current_rev = current_rev;
@@ -1863,7 +1912,7 @@ svn_fs_compare_ids(const svn_fs_id_t *a,
{
switch (a->vtable->compare(a, b))
{
- case svn_fs_node_same:
+ case svn_fs_node_unchanged:
return 0;
case svn_fs_node_common_ancestor:
return 1;
@@ -1958,7 +2007,7 @@ svn_fs_info_dup(const void *info_void,
fs_library_vtable_t *vtable;
SVN_ERR(get_library_vtable(&vtable, info->fs_type, scratch_pool));
-
+
if (vtable->info_fsap_dup)
return vtable->info_fsap_dup(info_void, result_pool);
else
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs/fs-loader.h?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs/fs-loader.h Sun Jun 14 20:58:10 2015
@@ -99,7 +99,7 @@ typedef struct fs_library_vtable_t
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_mutex__t *common_pool_lock,
- apr_pool_t *pool,
+ apr_pool_t *scratch_pool,
apr_pool_t *common_pool);
svn_error_t *(*verify_fs)(svn_fs_t *fs, const char *path,
svn_revnum_t start,
@@ -314,7 +314,7 @@ typedef struct root_vtable_t
svn_error_t *(*node_relation)(svn_fs_node_relation_t *relation,
svn_fs_root_t *root_a, const char *path_a,
svn_fs_root_t *root_b, const char *path_b,
- apr_pool_t *pool);
+ apr_pool_t *scratch_pool);
svn_error_t *(*node_created_rev)(svn_revnum_t *revision,
svn_fs_root_t *root, const char *path,
apr_pool_t *pool);
@@ -346,6 +346,8 @@ typedef struct root_vtable_t
apr_pool_t *pool);
svn_error_t *(*node_proplist)(apr_hash_t **table_p, svn_fs_root_t *root,
const char *path, apr_pool_t *pool);
+ svn_error_t *(*node_has_props)(svn_boolean_t *has_props, svn_fs_root_t *root,
+ const char *path, apr_pool_t *scratch_pool);
svn_error_t *(*change_node_prop)(svn_fs_root_t *root, const char *path,
const char *name,
const svn_string_t *value,
@@ -353,7 +355,7 @@ typedef struct root_vtable_t
svn_error_t *(*props_changed)(int *changed_p, svn_fs_root_t *root1,
const char *path1, svn_fs_root_t *root2,
const char *path2, svn_boolean_t strict,
- apr_pool_t *pool);
+ apr_pool_t *scratch_pool);
/* Directories */
svn_error_t *(*dir_entries)(apr_hash_t **entries_p, svn_fs_root_t *root,
@@ -361,7 +363,8 @@ typedef struct root_vtable_t
svn_error_t *(*dir_optimal_order)(apr_array_header_t **ordered_p,
svn_fs_root_t *root,
apr_hash_t *entries,
- apr_pool_t *pool);
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
svn_error_t *(*make_dir)(svn_fs_root_t *root, const char *path,
apr_pool_t *pool);
@@ -394,7 +397,7 @@ typedef struct root_vtable_t
svn_error_t *(*contents_changed)(int *changed_p, svn_fs_root_t *root1,
const char *path1, svn_fs_root_t *root2,
const char *path2, svn_boolean_t strict,
- apr_pool_t *pool);
+ apr_pool_t *scratch_pool);
svn_error_t *(*get_file_delta_stream)(svn_txdelta_stream_t **stream_p,
svn_fs_root_t *source_root,
const char *source_path,
@@ -446,7 +449,7 @@ typedef struct id_vtable_t
/*** Definitions of the abstract FS object types ***/
/* These are transaction properties that correspond to the bitfields
- in the 'flags' argument to svn_fs_lock(). */
+ in the 'flags' argument to svn_fs_begin_txn2(). */
#define SVN_FS__PROP_TXN_CHECK_LOCKS SVN_PROP_PREFIX "check-locks"
#define SVN_FS__PROP_TXN_CHECK_OOD SVN_PROP_PREFIX "check-ood"
/* Set to "0" at the start of the txn, to "1" when svn:date changes. */
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs_base/bdb/rev-table.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs_base/bdb/rev-table.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs_base/bdb/rev-table.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs_base/bdb/rev-table.c Sun Jun 14 20:58:10 2015
@@ -79,6 +79,9 @@ svn_fs_bdb__get_rev(revision_t **revisio
numbers begin with one. */
db_recno_t recno = (db_recno_t) rev + 1;
+ if (!SVN_IS_VALID_REVNUM(rev))
+ return svn_fs_base__err_dangling_rev(fs, rev);
+
svn_fs_base__trail_debug(trail, "revisions", "get");
db_err = bfd->revisions->get(bfd->revisions, trail->db_txn,
svn_fs_base__set_dbt(&key, &recno,
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs_base/fs.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs_base/fs.c Sun Jun 14 20:58:10 2015
@@ -780,7 +780,7 @@ base_create(svn_fs_t *fs,
((base_fs_data_t *) fs->fsap_data)->format = format;
SVN_ERR(populate_opened_fs(fs, pool));
- return SVN_NO_ERROR;;
+ return SVN_NO_ERROR;
error:
return svn_error_compose_create(svn_err,
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs_base/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs_base/id.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs_base/id.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs_base/id.c Sun Jun 14 20:58:10 2015
@@ -113,7 +113,7 @@ svn_fs_base__id_compare(const svn_fs_id_
const svn_fs_id_t *b)
{
if (svn_fs_base__id_eq(a, b))
- return svn_fs_node_same;
+ return svn_fs_node_unchanged;
return (svn_fs_base__id_check_related(a, b) ? svn_fs_node_common_ancestor
: svn_fs_node_unrelated);
}
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs_base/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs_base/lock.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs_base/lock.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs_base/lock.c Sun Jun 14 20:58:10 2015
@@ -39,6 +39,7 @@
#include "private/svn_fs_util.h"
#include "private/svn_subr_private.h"
#include "private/svn_dep_compat.h"
+#include "revs-txns.h"
/* Add LOCK and its associated LOCK_TOKEN (associated with PATH) as
@@ -241,8 +242,11 @@ svn_fs_base__lock(svn_fs_t *fs,
{
apr_hash_index_t *hi;
svn_error_t *cb_err = SVN_NO_ERROR;
+ svn_revnum_t youngest_rev = SVN_INVALID_REVNUM;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
SVN_ERR(svn_fs__check_fs(fs, TRUE));
+ SVN_ERR(svn_fs_base__youngest_rev(&youngest_rev, fs, scratch_pool));
for (hi = apr_hash_first(scratch_pool, targets); hi; hi = apr_hash_next(hi))
{
@@ -250,8 +254,9 @@ svn_fs_base__lock(svn_fs_t *fs,
const char *path = apr_hash_this_key(hi);
const svn_fs_lock_target_t *target = apr_hash_this_val(hi);
svn_lock_t *lock;
- svn_error_t *err;
+ svn_error_t *err = NULL;
+ svn_pool_clear(iterpool);
args.lock_p = &lock;
args.path = svn_fs__canonicalize_abspath(path, result_pool);
args.token = target->token;
@@ -261,13 +266,23 @@ svn_fs_base__lock(svn_fs_t *fs,
args.expiration_date = expiration_date;
args.current_rev = target->current_rev;
args.result_pool = result_pool;
-
- err = svn_fs_base__retry_txn(fs, txn_body_lock, &args, TRUE,
- scratch_pool);
+
+ if (SVN_IS_VALID_REVNUM(target->current_rev))
+ {
+ if (target->current_rev > youngest_rev)
+ err = svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+ _("No such revision %ld"),
+ target->current_rev);
+ }
+
+ if (!err)
+ err = svn_fs_base__retry_txn(fs, txn_body_lock, &args, TRUE,
+ iterpool);
if (!cb_err && lock_callback)
- cb_err = lock_callback(lock_baton, args.path, lock, err, scratch_pool);
+ cb_err = lock_callback(lock_baton, args.path, lock, err, iterpool);
svn_error_clear(err);
}
+ svn_pool_destroy(iterpool);
return svn_error_trace(cb_err);
}
@@ -356,6 +371,7 @@ svn_fs_base__unlock(svn_fs_t *fs,
{
apr_hash_index_t *hi;
svn_error_t *cb_err = SVN_NO_ERROR;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
SVN_ERR(svn_fs__check_fs(fs, TRUE));
@@ -366,16 +382,18 @@ svn_fs_base__unlock(svn_fs_t *fs,
const char *token = apr_hash_this_val(hi);
svn_error_t *err;
+ svn_pool_clear(iterpool);
args.path = svn_fs__canonicalize_abspath(path, result_pool);
args.token = token;
args.break_lock = break_lock;
err = svn_fs_base__retry_txn(fs, txn_body_unlock, &args, TRUE,
- scratch_pool);
+ iterpool);
if (!cb_err && lock_callback)
- cb_err = lock_callback(lock_baton, path, NULL, err, scratch_pool);
+ cb_err = lock_callback(lock_baton, path, NULL, err, iterpool);
svn_error_clear(err);
}
+ svn_pool_destroy(iterpool);
return svn_error_trace(cb_err);
}
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs_base/revs-txns.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs_base/revs-txns.c Sun Jun 14 20:58:10 2015
@@ -711,6 +711,23 @@ txn_body_begin_txn(void *baton, trail_t
SVN_ERR(txn_body_change_txn_prop(&cpargs, trail));
}
+ /* Put a datestamp on the newly created txn, so we always know
+ exactly how old it is. (This will help sysadmins identify
+ long-abandoned txns that may need to be manually removed.) Do
+ this before setting CLIENT_DATE so that it is not recorded as an
+ explicit setting. */
+ {
+ struct change_txn_prop_args cpargs;
+ svn_string_t date;
+ cpargs.fs = trail->fs;
+ cpargs.id = txn_id;
+ cpargs.name = SVN_PROP_REVISION_DATE;
+ date.data = svn_time_to_cstring(apr_time_now(), trail->pool);
+ date.len = strlen(date.data);
+ cpargs.value = &date;
+ SVN_ERR(txn_body_change_txn_prop(&cpargs, trail));
+ }
+
if (args->flags & SVN_FS_TXN_CLIENT_DATE)
{
struct change_txn_prop_args cpargs;
@@ -737,7 +754,6 @@ svn_fs_base__begin_txn(svn_fs_txn_t **tx
{
svn_fs_txn_t *txn;
struct begin_txn_args args;
- svn_string_t date;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
@@ -748,15 +764,7 @@ svn_fs_base__begin_txn(svn_fs_txn_t **tx
*txn_p = txn;
- /* Put a datestamp on the newly created txn, so we always know
- exactly how old it is. (This will help sysadmins identify
- long-abandoned txns that may need to be manually removed.) When
- a txn is promoted to a revision, this property will be
- automatically overwritten with a revision datestamp. */
- date.data = svn_time_to_cstring(apr_time_now(), pool);
- date.len = strlen(date.data);
- return svn_fs_base__change_txn_prop(txn, SVN_PROP_REVISION_DATE,
- &date, pool);
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/fsx-1.10/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_fs_base/tree.c?rev=1685464&r1=1685463&r2=1685464&view=diff
==============================================================================
--- subversion/branches/fsx-1.10/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/fsx-1.10/subversion/libsvn_fs_base/tree.c Sun Jun 14 20:58:10 2015
@@ -1285,6 +1285,21 @@ base_node_proplist(apr_hash_t **table_p,
return SVN_NO_ERROR;
}
+static svn_error_t *
+base_node_has_props(svn_boolean_t *has_props,
+ svn_fs_root_t *root,
+ const char *path,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *props;
+
+ SVN_ERR(base_node_proplist(&props, root, path, scratch_pool));
+
+ *has_props = (0 < apr_hash_count(props));
+
+ return SVN_NO_ERROR;
+}
+
struct change_node_prop_args {
svn_fs_root_t *root;
@@ -1608,13 +1623,15 @@ static svn_error_t *
base_dir_optimal_order(apr_array_header_t **ordered_p,
svn_fs_root_t *root,
apr_hash_t *entries,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
/* 1:1 copy of entries with no differnce in ordering */
apr_hash_index_t *hi;
- apr_array_header_t *result = apr_array_make(pool, apr_hash_count(entries),
- sizeof(svn_fs_dirent_t *));
- for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
+ apr_array_header_t *result
+ = apr_array_make(result_pool, apr_hash_count(entries),
+ sizeof(svn_fs_dirent_t *));
+ for (hi = apr_hash_first(scratch_pool, entries); hi; hi = apr_hash_next(hi))
APR_ARRAY_PUSH(result, svn_fs_dirent_t *) = apr_hash_this_val(hi);
*ordered_p = result;
@@ -3164,7 +3181,8 @@ txn_body_copy(void *baton,
if ((to_parent_path->node)
&& (svn_fs_base__id_compare(svn_fs_base__dag_get_id(from_node),
svn_fs_base__dag_get_id
- (to_parent_path->node)) == svn_fs_node_same))
+ (to_parent_path->node))
+ == svn_fs_node_unchanged))
return SVN_NO_ERROR;
if (! from_root->is_txn_root)
@@ -5489,6 +5507,7 @@ static root_vtable_t root_vtable = {
base_closest_copy,
base_node_prop,
base_node_proplist,
+ base_node_has_props,
base_change_node_prop,
base_props_changed,
base_dir_entries,