diff options
Diffstat (limited to 'subversion/libsvn_subr')
-rw-r--r-- | subversion/libsvn_subr/config_file.c | 36 | ||||
-rw-r--r-- | subversion/libsvn_subr/gpg_agent.c | 101 | ||||
-rw-r--r-- | subversion/libsvn_subr/internal_statements.h | 2 | ||||
-rw-r--r-- | subversion/libsvn_subr/io.c | 3 | ||||
-rw-r--r-- | subversion/libsvn_subr/named_atomic.c | 18 | ||||
-rw-r--r-- | subversion/libsvn_subr/sqlite.c | 20 | ||||
-rw-r--r-- | subversion/libsvn_subr/stream.c | 9 | ||||
-rw-r--r-- | subversion/libsvn_subr/subst.c | 6 | ||||
-rw-r--r-- | subversion/libsvn_subr/utf.c | 10 |
9 files changed, 147 insertions, 58 deletions
diff --git a/subversion/libsvn_subr/config_file.c b/subversion/libsvn_subr/config_file.c index 9d15f6b149f80..c705b14fd40a9 100644 --- a/subversion/libsvn_subr/config_file.c +++ b/subversion/libsvn_subr/config_file.c @@ -94,7 +94,7 @@ parser_getc(parse_context_t *ctx, int *c) } else if (ctx->buffer_pos < ctx->buffer_size) { - *c = ctx->parser_buffer[ctx->buffer_pos]; + *c = (unsigned char)ctx->parser_buffer[ctx->buffer_pos]; ctx->buffer_pos++; } else @@ -107,7 +107,7 @@ parser_getc(parse_context_t *ctx, int *c) if (ctx->buffer_pos < ctx->buffer_size) { - *c = ctx->parser_buffer[ctx->buffer_pos]; + *c = (unsigned char)ctx->parser_buffer[ctx->buffer_pos]; ctx->buffer_pos++; } else @@ -131,7 +131,7 @@ parser_getc_plain(parse_context_t *ctx, int *c) { if (ctx->buffer_pos < ctx->buffer_size) { - *c = ctx->parser_buffer[ctx->buffer_pos]; + *c = (unsigned char)ctx->parser_buffer[ctx->buffer_pos]; ctx->buffer_pos++; return SVN_NO_ERROR; @@ -189,6 +189,32 @@ skip_to_eoln(parse_context_t *ctx, int *c) return SVN_NO_ERROR; } +/* Skip a UTF-8 Byte Order Mark if found. */ +static APR_INLINE svn_error_t * +skip_bom(parse_context_t *ctx) +{ + int ch; + + SVN_ERR(parser_getc(ctx, &ch)); + if (ch == 0xEF) + { + const unsigned char *buf = (unsigned char *)ctx->parser_buffer; + /* This makes assumptions about the implementation of parser_getc and + * the use of skip_bom. Specifically that parser_getc() will get all + * of the BOM characters into the parse_context_t buffer. This can + * safely be assumed as long as we only try to use skip_bom() at the + * start of the stream and the buffer is longer than 3 characters. */ + SVN_ERR_ASSERT(ctx->buffer_size > ctx->buffer_pos + 1); + if (buf[ctx->buffer_pos] == 0xBB && buf[ctx->buffer_pos + 1] == 0xBF) + ctx->buffer_pos += 2; + else + SVN_ERR(parser_ungetc(ctx, ch)); + } + else + SVN_ERR(parser_ungetc(ctx, ch)); + + return SVN_NO_ERROR; +} /* Parse a single option value */ static svn_error_t * @@ -450,6 +476,8 @@ svn_config__parse_stream(svn_config_t *cfg, svn_stream_t *stream, ctx->buffer_pos = 0; ctx->buffer_size = 0; + SVN_ERR(skip_bom(ctx)); + do { SVN_ERR(skip_whitespace(ctx, &ch, &count)); @@ -806,6 +834,8 @@ svn_config_ensure(const char *config_dir, apr_pool_t *pool) "### http-max-connections Maximum number of parallel server" NL "### connections to use for any given" NL "### HTTP operation." NL + "### http-chunked-requests Whether to use chunked transfer" NL + "### encoding for HTTP requests body." NL "### neon-debug-mask Debug mask for Neon HTTP library" NL "### ssl-authority-files List of files, each of a trusted CA" NL diff --git a/subversion/libsvn_subr/gpg_agent.c b/subversion/libsvn_subr/gpg_agent.c index f0395c00c750c..e23339074a408 100644 --- a/subversion/libsvn_subr/gpg_agent.c +++ b/subversion/libsvn_subr/gpg_agent.c @@ -156,42 +156,28 @@ send_option(int sd, char *buf, size_t n, const char *option, const char *value, return (strncmp(buf, "OK", 2) == 0); } -/* Implementation of svn_auth__password_get_t that retrieves the password - from gpg-agent */ + +/* Locate a running GPG Agent, and return an open file descriptor + * for communication with the agent in *NEW_SD. If no running agent + * can be found, set *NEW_SD to -1. */ static svn_error_t * -password_get_gpg_agent(svn_boolean_t *done, - const char **password, - apr_hash_t *creds, - const char *realmstring, - const char *username, - apr_hash_t *parameters, - svn_boolean_t non_interactive, - apr_pool_t *pool) +find_running_gpg_agent(int *new_sd, apr_pool_t *pool) { - int sd; + char *buffer; char *gpg_agent_info = NULL; + const char *socket_name = NULL; + const char *request = NULL; const char *p = NULL; char *ep = NULL; - char *buffer; - - apr_array_header_t *socket_details; - const char *request = NULL; - const char *cache_id = NULL; - struct sockaddr_un addr; - const char *tty_name; - const char *tty_type; - const char *lc_ctype; - const char *display; - const char *socket_name = NULL; - svn_checksum_t *digest = NULL; - char *password_prompt; - char *realm_prompt; + int sd; - *done = FALSE; + *new_sd = -1; gpg_agent_info = getenv("GPG_AGENT_INFO"); if (gpg_agent_info != NULL) { + apr_array_header_t *socket_details; + socket_details = svn_cstring_split(gpg_agent_info, ":", TRUE, pool); socket_name = APR_ARRAY_IDX(socket_details, 0, const char *); @@ -201,6 +187,8 @@ password_get_gpg_agent(svn_boolean_t *done, if (socket_name != NULL) { + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path) - 1); addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; @@ -273,6 +261,44 @@ password_get_gpg_agent(svn_boolean_t *done, return SVN_NO_ERROR; } + *new_sd = sd; + return SVN_NO_ERROR; +} + +/* Implementation of svn_auth__password_get_t that retrieves the password + from gpg-agent */ +static svn_error_t * +password_get_gpg_agent(svn_boolean_t *done, + const char **password, + apr_hash_t *creds, + const char *realmstring, + const char *username, + apr_hash_t *parameters, + svn_boolean_t non_interactive, + apr_pool_t *pool) +{ + int sd; + const char *p = NULL; + char *ep = NULL; + char *buffer; + const char *request = NULL; + const char *cache_id = NULL; + const char *tty_name; + const char *tty_type; + const char *lc_ctype; + const char *display; + svn_checksum_t *digest = NULL; + char *password_prompt; + char *realm_prompt; + + *done = FALSE; + + SVN_ERR(find_running_gpg_agent(&sd, pool)); + if (sd == -1) + return SVN_NO_ERROR; + + buffer = apr_palloc(pool, BUFFER_SIZE); + /* Send TTY_NAME to the gpg-agent daemon. */ tty_name = getenv("GPG_TTY"); if (tty_name != NULL) @@ -283,11 +309,6 @@ password_get_gpg_agent(svn_boolean_t *done, return SVN_NO_ERROR; } } - else - { - close(sd); - return SVN_NO_ERROR; - } /* Send TTY_TYPE to the gpg-agent daemon. */ tty_type = getenv("TERM"); @@ -299,11 +320,6 @@ password_get_gpg_agent(svn_boolean_t *done, return SVN_NO_ERROR; } } - else - { - close(sd); - return SVN_NO_ERROR; - } /* Compute LC_CTYPE. */ lc_ctype = getenv("LC_ALL"); @@ -388,8 +404,8 @@ password_get_gpg_agent(svn_boolean_t *done, password in GPG Agent if that's how this particular integration worked. But it isn't. GPG Agent stores the password provided by the user via the pinentry program immediately upon its provision - (and regardless of its accuracy as passwords go), so there's - nothing really to do here. */ + (and regardless of its accuracy as passwords go), so we just need + to check if a running GPG Agent exists. */ static svn_error_t * password_set_gpg_agent(svn_boolean_t *done, apr_hash_t *creds, @@ -400,6 +416,15 @@ password_set_gpg_agent(svn_boolean_t *done, svn_boolean_t non_interactive, apr_pool_t *pool) { + int sd; + + *done = FALSE; + + SVN_ERR(find_running_gpg_agent(&sd, pool)); + if (sd == -1) + return SVN_NO_ERROR; + + close(sd); *done = TRUE; return SVN_NO_ERROR; diff --git a/subversion/libsvn_subr/internal_statements.h b/subversion/libsvn_subr/internal_statements.h index 9e31e74badae1..dd81d9fb7deb4 100644 --- a/subversion/libsvn_subr/internal_statements.h +++ b/subversion/libsvn_subr/internal_statements.h @@ -1,4 +1,4 @@ -/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.8.0/subversion/libsvn_subr/token-map.h. +/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.8.1/subversion/libsvn_subr/token-map.h. * Do not edit this file -- edit the source and rerun gen-make.py */ #define STMT_INTERNAL_SAVEPOINT_SVN 0 diff --git a/subversion/libsvn_subr/io.c b/subversion/libsvn_subr/io.c index 58bc5403653b4..d31819410f050 100644 --- a/subversion/libsvn_subr/io.c +++ b/subversion/libsvn_subr/io.c @@ -3533,6 +3533,9 @@ svn_io_read_length_line(apr_file_t *file, char *buf, apr_size_t *limit, apr_size_t bytes_read = 0; char *eol; + if (to_read == 0) + break; + /* read data block (or just a part of it) */ SVN_ERR(svn_io_file_read_full2(file, buf, to_read, &bytes_read, &eof, pool)); diff --git a/subversion/libsvn_subr/named_atomic.c b/subversion/libsvn_subr/named_atomic.c index d07e7424f6381..cd58bbb388170 100644 --- a/subversion/libsvn_subr/named_atomic.c +++ b/subversion/libsvn_subr/named_atomic.c @@ -251,6 +251,7 @@ struct svn_atomic_namespace__t */ static svn_mutex__t *thread_mutex = NULL; +#if APR_HAS_MMAP /* Initialization flag for the above used by svn_atomic__init_once. */ static volatile svn_atomic_t mutex_initialized = FALSE; @@ -266,6 +267,7 @@ init_thread_mutex(void *baton, apr_pool_t *pool) return svn_mutex__init(&thread_mutex, USE_THREAD_MUTEX, global_pool); } +#endif /* APR_HAS_MMAP */ /* Utility that acquires our global mutex and converts error types. */ @@ -297,6 +299,7 @@ unlock(struct mutex_t *mutex, svn_error_t * outer_err) unlock_err)); } +#if APR_HAS_MMAP /* The last user to close a particular namespace should also remove the * lock file. Failure to do so, however, does not affect further uses * of the same namespace. @@ -318,6 +321,7 @@ delete_lock_file(void *arg) return status; } +#endif /* APR_HAS_MMAP */ /* Validate the ATOMIC parameter, i.e it's address. Correct code will * never need this but if someone should accidentally to use a NULL or @@ -351,7 +355,11 @@ return_atomic(svn_named_atomic__t **atomic, svn_boolean_t svn_named_atomic__is_supported(void) { -#ifdef _WIN32 +#if !APR_HAS_MMAP + return FALSE; +#elif !defined(_WIN32) + return TRUE; +#else static svn_tristate_t result = svn_tristate_unknown; if (result == svn_tristate_unknown) @@ -373,9 +381,7 @@ svn_named_atomic__is_supported(void) } return result == svn_tristate_true; -#else - return TRUE; -#endif +#endif /* _WIN32 */ } svn_boolean_t @@ -389,6 +395,9 @@ svn_atomic_namespace__create(svn_atomic_namespace__t **ns, const char *name, apr_pool_t *result_pool) { +#if !APR_HAS_MMAP + return svn_error_create(APR_ENOTIMPL, NULL, NULL); +#else apr_status_t apr_err; svn_error_t *err; apr_file_t *file; @@ -489,6 +498,7 @@ svn_atomic_namespace__create(svn_atomic_namespace__t **ns, /* Unlock to allow other processes may access the shared memory as well. */ return unlock(&new_ns->mutex, err); +#endif /* APR_HAS_MMAP */ } svn_error_t * diff --git a/subversion/libsvn_subr/sqlite.c b/subversion/libsvn_subr/sqlite.c index 0afceffe6617c..149b0253be923 100644 --- a/subversion/libsvn_subr/sqlite.c +++ b/subversion/libsvn_subr/sqlite.c @@ -140,9 +140,9 @@ struct svn_sqlite__value_t int sqlite_err__temp = (x); \ if (sqlite_err__temp != SQLITE_OK) \ return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \ - NULL, "sqlite: %s (S%d)", \ - sqlite3_errmsg((db)->db3), \ - sqlite_err__temp); \ + NULL, "sqlite[S%d]: %s", \ + sqlite_err__temp, \ + sqlite3_errmsg((db)->db3)); \ } while (0) #define SQLITE_ERR_MSG(x, msg) do \ @@ -150,8 +150,8 @@ struct svn_sqlite__value_t int sqlite_err__temp = (x); \ if (sqlite_err__temp != SQLITE_OK) \ return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \ - NULL, "sqlite: %s (S%d)", (msg), \ - sqlite_err__temp); \ + NULL, "sqlite[S%d]: %s", \ + sqlite_err__temp, msg); \ } while (0) @@ -173,9 +173,9 @@ exec_sql2(svn_sqlite__db_t *db, const char *sql, int ignored_err) if (sqlite_err != SQLITE_OK && sqlite_err != ignored_err) { svn_error_t *err = svn_error_createf(SQLITE_ERROR_CODE(sqlite_err), NULL, - _("sqlite: %s (S%d)," + _("sqlite[S%d]: %s," " executing statement '%s'"), - err_msg, sqlite_err, sql); + sqlite_err, err_msg, sql); sqlite3_free(err_msg); return err; } @@ -292,8 +292,8 @@ svn_sqlite__step(svn_boolean_t *got_row, svn_sqlite__stmt_t *stmt) svn_error_t *err1, *err2; err1 = svn_error_createf(SQLITE_ERROR_CODE(sqlite_result), NULL, - "sqlite: %s (S%d)", - sqlite3_errmsg(stmt->db->db3), sqlite_result); + "sqlite[S%d]: %s", + sqlite_result, sqlite3_errmsg(stmt->db->db3)); err2 = svn_sqlite__reset(stmt); return svn_error_compose_create(err1, err2); } @@ -744,7 +744,7 @@ init_sqlite(void *baton, apr_pool_t *pool) int err = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); if (err != SQLITE_OK && err != SQLITE_MISUSE) return svn_error_createf(SQLITE_ERROR_CODE(err), NULL, - _("Could not configure SQLite (S%d)"), err); + _("Could not configure SQLite [S%d]"), err); } SQLITE_ERR_MSG(sqlite3_initialize(), _("Could not initialize SQLite")); diff --git a/subversion/libsvn_subr/stream.c b/subversion/libsvn_subr/stream.c index e2529c7467652..93a4c423c9a98 100644 --- a/subversion/libsvn_subr/stream.c +++ b/subversion/libsvn_subr/stream.c @@ -56,6 +56,7 @@ struct svn_stream_t { svn_stream_mark_fn_t mark_fn; svn_stream_seek_fn_t seek_fn; svn_stream__is_buffered_fn_t is_buffered_fn; + apr_file_t *file; /* Maybe NULL */ }; @@ -81,6 +82,7 @@ svn_stream_create(void *baton, apr_pool_t *pool) stream->mark_fn = NULL; stream->seek_fn = NULL; stream->is_buffered_fn = NULL; + stream->file = NULL; return stream; } @@ -913,6 +915,7 @@ svn_stream_from_aprfile2(apr_file_t *file, svn_stream_set_mark(stream, mark_handler_apr); svn_stream_set_seek(stream, seek_handler_apr); svn_stream__set_is_buffered(stream, is_buffered_handler_apr); + stream->file = file; if (! disown) svn_stream_set_close(stream, close_handler_apr); @@ -920,6 +923,12 @@ svn_stream_from_aprfile2(apr_file_t *file, return stream; } +apr_file_t * +svn_stream__aprfile(svn_stream_t *stream) +{ + return stream->file; +} + /* Compressed stream support */ diff --git a/subversion/libsvn_subr/subst.c b/subversion/libsvn_subr/subst.c index f69dcf8f2bae9..3545289baf81a 100644 --- a/subversion/libsvn_subr/subst.c +++ b/subversion/libsvn_subr/subst.c @@ -1944,7 +1944,11 @@ svn_subst_translate_string2(svn_string_t **new_value, return SVN_NO_ERROR; } - if (encoding) + if (encoding && !strcmp(encoding, "UTF-8")) + { + val_utf8 = value->data; + } + else if (encoding) { SVN_ERR(svn_utf_cstring_to_utf8_ex2(&val_utf8, value->data, encoding, scratch_pool)); diff --git a/subversion/libsvn_subr/utf.c b/subversion/libsvn_subr/utf.c index 355e068f5e55f..535e3daf9f5cf 100644 --- a/subversion/libsvn_subr/utf.c +++ b/subversion/libsvn_subr/utf.c @@ -233,6 +233,8 @@ xlate_alloc_handle(xlate_handle_node_t **ret, else if (apr_err != APR_SUCCESS) { const char *errstr; + char apr_strerr[512]; + /* Can't use svn_error_wrap_apr here because it calls functions in this file, leading to infinite recursion. */ if (frompage == SVN_APR_LOCALE_CHARSET) @@ -248,7 +250,13 @@ xlate_alloc_handle(xlate_handle_node_t **ret, _("Can't create a character converter from " "'%s' to '%s'"), frompage, topage); - return svn_error_create(apr_err, NULL, errstr); + /* Just put the error on the stack, since svn_error_create duplicates it + later. APR_STRERR will be in the local encoding, not in UTF-8, though. + */ + svn_strerror(apr_err, apr_strerr, sizeof(apr_strerr)); + return svn_error_create(apr_err, + svn_error_create(apr_err, NULL, apr_strerr), + errstr); } /* Allocate and initialize the node. */ |