diff options
Diffstat (limited to 'subversion/libsvn_subr')
-rw-r--r-- | subversion/libsvn_subr/config_file.c | 22 | ||||
-rw-r--r-- | subversion/libsvn_subr/deprecated.c | 10 | ||||
-rw-r--r-- | subversion/libsvn_subr/gpg_agent.c | 20 | ||||
-rw-r--r-- | subversion/libsvn_subr/internal_statements.h | 2 | ||||
-rw-r--r-- | subversion/libsvn_subr/sqlite.c | 142 | ||||
-rw-r--r-- | subversion/libsvn_subr/sysinfo.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_subr/win32_crashrpt.c | 82 | ||||
-rw-r--r-- | subversion/libsvn_subr/xml.c | 39 |
8 files changed, 214 insertions, 105 deletions
diff --git a/subversion/libsvn_subr/config_file.c b/subversion/libsvn_subr/config_file.c index eede717575b67..8b4d7a35220c4 100644 --- a/subversion/libsvn_subr/config_file.c +++ b/subversion/libsvn_subr/config_file.c @@ -74,6 +74,9 @@ typedef struct parse_context_t char parser_buffer[SVN__STREAM_CHUNK_SIZE]; /* Larger than most config files */ size_t buffer_pos; /* Current position within parser_buffer */ size_t buffer_size; /* parser_buffer contains this many bytes */ + + /* Non-zero if we hit EOF on the stream. */ + svn_boolean_t hit_stream_eof; } parse_context_t; @@ -101,11 +104,15 @@ parser_getc(parse_context_t *ctx, int *c) } else { - ctx->buffer_pos = 0; - ctx->buffer_size = sizeof(ctx->parser_buffer); + if (!ctx->hit_stream_eof) + { + ctx->buffer_pos = 0; + ctx->buffer_size = sizeof(ctx->parser_buffer); - SVN_ERR(svn_stream_read_full(ctx->stream, ctx->parser_buffer, - &(ctx->buffer_size))); + SVN_ERR(svn_stream_read_full(ctx->stream, ctx->parser_buffer, + &(ctx->buffer_size))); + ctx->hit_stream_eof = (ctx->buffer_size != sizeof(ctx->parser_buffer)); + } if (ctx->buffer_pos < ctx->buffer_size) { @@ -224,8 +231,10 @@ skip_bom(parse_context_t *ctx) * 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) + SVN_ERR_ASSERT(ctx->buffer_size > ctx->buffer_pos + 1 || + ctx->hit_stream_eof); + if (ctx->buffer_size > ctx->buffer_pos + 1 && + buf[ctx->buffer_pos] == 0xBB && buf[ctx->buffer_pos + 1] == 0xBF) ctx->buffer_pos += 2; else SVN_ERR(parser_ungetc(ctx, ch)); @@ -579,6 +588,7 @@ svn_config__parse_stream(svn_config_t *cfg, svn_stream_t *stream, ctx->value = svn_stringbuf_create_empty(scratch_pool); ctx->buffer_pos = 0; ctx->buffer_size = 0; + ctx->hit_stream_eof = FALSE; SVN_ERR(skip_bom(ctx)); diff --git a/subversion/libsvn_subr/deprecated.c b/subversion/libsvn_subr/deprecated.c index a0bf813eada78..68e3bd2cb3f98 100644 --- a/subversion/libsvn_subr/deprecated.c +++ b/subversion/libsvn_subr/deprecated.c @@ -1484,7 +1484,11 @@ void svn_auth_get_keychain_simple_provider(svn_auth_provider_object_t **provider, apr_pool_t *pool) { +#ifdef SVN_HAVE_KEYCHAIN_SERVICES svn_auth__get_keychain_simple_provider(provider, pool); +#else + svn_auth__get_dummmy_simple_provider(provider, pool); +#endif } void @@ -1492,7 +1496,13 @@ svn_auth_get_keychain_ssl_client_cert_pw_provider (svn_auth_provider_object_t **provider, apr_pool_t *pool) { +#ifdef SVN_HAVE_KEYCHAIN_SERVICES svn_auth__get_keychain_ssl_client_cert_pw_provider(provider, pool); +#else + /* Not really the right type of dummy provider, but doesn't throw NULL + errors as just returning NULL would */ + svn_auth__get_dummmy_simple_provider(provider, pool); +#endif } #endif /* DARWIN */ diff --git a/subversion/libsvn_subr/gpg_agent.c b/subversion/libsvn_subr/gpg_agent.c index d53eec44c28f2..36fe30ddb8fe5 100644 --- a/subversion/libsvn_subr/gpg_agent.c +++ b/subversion/libsvn_subr/gpg_agent.c @@ -233,6 +233,7 @@ find_running_gpg_agent(int *new_sd, apr_pool_t *pool) { char *buffer; char *gpg_agent_info = NULL; + char *gnupghome = NULL; const char *socket_name = NULL; const char *request = NULL; const char *p = NULL; @@ -243,10 +244,9 @@ find_running_gpg_agent(int *new_sd, apr_pool_t *pool) /* This implements the method of finding the socket as described in * the gpg-agent man page under the --use-standard-socket option. - * The manage page misleadingly says the standard socket is - * "named 'S.gpg-agent' located in the home directory." The standard - * socket path is actually in the .gnupg directory in the home directory, - * i.e. ~/.gnupg/S.gpg-agent */ + * The manage page says the standard socket is "named 'S.gpg-agent' located + * in the home directory." GPG's home directory is either the directory + * specified by $GNUPGHOME or ~/.gnupg. */ gpg_agent_info = getenv("GPG_AGENT_INFO"); if (gpg_agent_info != NULL) { @@ -259,6 +259,11 @@ find_running_gpg_agent(int *new_sd, apr_pool_t *pool) pool); socket_name = APR_ARRAY_IDX(socket_details, 0, const char *); } + else if ((gnupghome = getenv("GNUPGHOME")) != NULL) + { + const char *homedir = svn_dirent_canonicalize(gnupghome, pool); + socket_name = svn_dirent_join(homedir, "S.gpg-agent", pool); + } else { const char *homedir = svn_user_get_homedir(pool); @@ -611,11 +616,10 @@ simple_gpg_agent_next_creds(void **credentials, return SVN_NO_ERROR; } + bye_gpg_agent(sd); + if (strncmp(buffer, "OK\n", 3) != 0) - { - bye_gpg_agent(sd); - return SVN_NO_ERROR; - } + return SVN_NO_ERROR; /* TODO: This attempt limit hard codes it at 3 attempts (or 2 retries) * which matches svn command line client's retry_limit as set in diff --git a/subversion/libsvn_subr/internal_statements.h b/subversion/libsvn_subr/internal_statements.h index 93251a47e997d..39b671964787c 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.9.4/subversion/libsvn_subr/token-map.h. +/* This file is automatically generated from internal_statements.sql and .dist_sandbox/subversion-1.9.5/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/sqlite.c b/subversion/libsvn_subr/sqlite.c index 18d1c49285581..18124a3508e60 100644 --- a/subversion/libsvn_subr/sqlite.c +++ b/subversion/libsvn_subr/sqlite.c @@ -1261,6 +1261,55 @@ reset_all_statements(svn_sqlite__db_t *db, return err; } +static svn_error_t * +rollback_transaction(svn_sqlite__db_t *db, + svn_error_t *error_to_wrap) +{ + svn_sqlite__stmt_t *stmt; + svn_error_t *err; + + err = get_internal_statement(&stmt, db, STMT_INTERNAL_ROLLBACK_TRANSACTION); + if (!err) + { + err = svn_error_trace(svn_sqlite__step_done(stmt)); + + if (err && err->apr_err == SVN_ERR_SQLITE_BUSY) + { + /* ### Houston, we have a problem! + + We are trying to rollback but we can't because some + statements are still busy. This leaves the database + unusable for future transactions as the current transaction + is still open. + + As we are returning the actual error as the most relevant + error in the chain, our caller might assume that it can + retry/compensate on this error (e.g. SVN_WC_LOCKED), while + in fact the SQLite database is unusable until the statements + started within this transaction are reset and the transaction + aborted. + + We try to compensate by resetting all prepared but unreset + statements; but we leave the busy error in the chain anyway to + help diagnosing the original error and help in finding where + a reset statement is missing. */ + err = svn_error_trace(reset_all_statements(db, err)); + err = svn_error_compose_create( + svn_error_trace(svn_sqlite__step_done(stmt)), + err); + } + } + + if (err) + { + /* Rollback failed, use a specific error code. */ + err = svn_error_create(SVN_SQLITE__ERR_ROLLBACK_FAILED, err, + _("SQLite transaction rollback failed")); + } + + return svn_error_compose_create(error_to_wrap, err); +} + svn_error_t * svn_sqlite__begin_transaction(svn_sqlite__db_t *db) { @@ -1303,46 +1352,37 @@ svn_sqlite__finish_transaction(svn_sqlite__db_t *db, /* Commit or rollback the sqlite transaction. */ if (err) { - svn_error_t *err2; - - err2 = get_internal_statement(&stmt, db, - STMT_INTERNAL_ROLLBACK_TRANSACTION); - if (!err2) - err2 = svn_sqlite__step_done(stmt); - - if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY) - { - /* ### Houston, we have a problem! - - We are trying to rollback but we can't because some - statements are still busy. This leaves the database - unusable for future transactions as the current transaction - is still open. - - As we are returning the actual error as the most relevant - error in the chain, our caller might assume that it can - retry/compensate on this error (e.g. SVN_WC_LOCKED), while - in fact the SQLite database is unusable until the statements - started within this transaction are reset and the transaction - aborted. - - We try to compensate by resetting all prepared but unreset - statements; but we leave the busy error in the chain anyway to - help diagnosing the original error and help in finding where - a reset statement is missing. */ - - err2 = reset_all_statements(db, err2); - err2 = svn_error_compose_create( - svn_sqlite__step_done(stmt), - err2); - } - - return svn_error_compose_create(err, - err2); + return svn_error_trace(rollback_transaction(db, err)); + } + else + { + err = get_internal_statement(&stmt, db, + STMT_INTERNAL_COMMIT_TRANSACTION); + if (!err) + err = svn_error_trace(svn_sqlite__step_done(stmt)); + + /* Need to rollback if the commit fails as well, because otherwise the + db connection will be left in an unusable state. + + One important case to keep in mind is trying to COMMIT with concurrent + readers. In case the commit fails, because someone else is holding a + shared lock, sqlite keeps the transaction, and *also* keeps the file + locks on the database. While the first part only prevents from using + this connection, the second part prevents everyone else from accessing + the database while the connection is open. + + See https://www.sqlite.org/lang_transaction.html + + COMMIT might also result in an SQLITE_BUSY return code if an another + thread or process has a shared lock on the database that prevented + the database from being updated. When COMMIT fails in this way, the + transaction remains active and the COMMIT can be retried later after + the reader has had a chance to clear. */ + if (err) + return svn_error_trace(rollback_transaction(db, err)); } - SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_COMMIT_TRANSACTION)); - return svn_error_trace(svn_sqlite__step_done(stmt)); + return SVN_NO_ERROR; } svn_error_t * @@ -1359,18 +1399,22 @@ svn_sqlite__finish_savepoint(svn_sqlite__db_t *db, STMT_INTERNAL_ROLLBACK_TO_SAVEPOINT_SVN); if (!err2) - err2 = svn_sqlite__step_done(stmt); - - if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY) { - /* Ok, we have a major problem. Some statement is still open, which - makes it impossible to release this savepoint. + err2 = svn_error_trace(svn_sqlite__step_done(stmt)); + + if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY) + { + /* Ok, we have a major problem. Some statement is still open, + which makes it impossible to release this savepoint. - ### See huge comment in svn_sqlite__finish_transaction for - further details */ + ### See huge comment in svn_sqlite__finish_transaction for + further details */ - err2 = reset_all_statements(db, err2); - err2 = svn_error_compose_create(svn_sqlite__step_done(stmt), err2); + err2 = svn_error_trace(reset_all_statements(db, err2)); + err2 = svn_error_compose_create( + svn_error_trace(svn_sqlite__step_done(stmt)), + err2); + } } err = svn_error_compose_create(err, err2); @@ -1378,9 +1422,9 @@ svn_sqlite__finish_savepoint(svn_sqlite__db_t *db, STMT_INTERNAL_RELEASE_SAVEPOINT_SVN); if (!err2) - err2 = svn_sqlite__step_done(stmt); + err2 = svn_error_trace(svn_sqlite__step_done(stmt)); - return svn_error_trace(svn_error_compose_create(err, err2)); + return svn_error_compose_create(err, err2); } SVN_ERR(get_internal_statement(&stmt, db, diff --git a/subversion/libsvn_subr/sysinfo.c b/subversion/libsvn_subr/sysinfo.c index 0678672241539..4ac923c0551b1 100644 --- a/subversion/libsvn_subr/sysinfo.c +++ b/subversion/libsvn_subr/sysinfo.c @@ -1143,6 +1143,8 @@ release_name_from_version(const char *osver) case 8: return "Mountain Lion"; case 9: return "Mavericks"; case 10: return "Yosemite"; + case 11: return "El Capitan"; + case 12: return "Sierra"; } return NULL; diff --git a/subversion/libsvn_subr/win32_crashrpt.c b/subversion/libsvn_subr/win32_crashrpt.c index 680b944b90221..1349d84c9fe21 100644 --- a/subversion/libsvn_subr/win32_crashrpt.c +++ b/subversion/libsvn_subr/win32_crashrpt.c @@ -53,9 +53,9 @@ HANDLE dbghelp_dll = INVALID_HANDLE_VALUE; #define LOGFILE_PREFIX "svn-crash-log" #if defined(_M_IX86) -#define FORMAT_PTR "0x%08x" +#define FORMAT_PTR "0x%08Ix" #elif defined(_M_X64) -#define FORMAT_PTR "0x%016I64x" +#define FORMAT_PTR "0x%016Ix" #endif /*** Code. ***/ @@ -171,7 +171,7 @@ write_module_info_callback(void *data, MINIDUMP_MODULE_CALLBACK module = callback_input->Module; char *buf = convert_wbcs_to_ansi(module.FullPath); - fprintf(log_file, FORMAT_PTR, module.BaseOfImage); + fprintf(log_file, FORMAT_PTR, (UINT_PTR)module.BaseOfImage); fprintf(log_file, " %s", buf); free(buf); @@ -260,18 +260,19 @@ write_process_info(EXCEPTION_RECORD *exception, CONTEXT *context, #endif } -/* Formats the value at address based on the specified basic type - * (char, int, long ...). */ +/* Writes the value at address based on the specified basic type + * (char, int, long ...) to LOG_FILE. */ static void -format_basic_type(char *buf, DWORD basic_type, DWORD64 length, void *address) +write_basic_type(FILE *log_file, DWORD basic_type, DWORD64 length, + void *address) { switch(length) { case 1: - sprintf(buf, "0x%02x", (int)*(unsigned char *)address); + fprintf(log_file, "0x%02x", (int)*(unsigned char *)address); break; case 2: - sprintf(buf, "0x%04x", (int)*(unsigned short *)address); + fprintf(log_file, "0x%04x", (int)*(unsigned short *)address); break; case 4: switch(basic_type) @@ -279,38 +280,38 @@ format_basic_type(char *buf, DWORD basic_type, DWORD64 length, void *address) case 2: /* btChar */ { if (!IsBadStringPtr(*(PSTR*)address, 32)) - sprintf(buf, "\"%.31s\"", *(const char **)address); + fprintf(log_file, "\"%.31s\"", *(const char **)address); else - sprintf(buf, FORMAT_PTR, *(DWORD_PTR *)address); + fprintf(log_file, FORMAT_PTR, *(DWORD_PTR *)address); } case 6: /* btInt */ - sprintf(buf, "%d", *(int *)address); + fprintf(log_file, "%d", *(int *)address); break; case 8: /* btFloat */ - sprintf(buf, "%f", *(float *)address); + fprintf(log_file, "%f", *(float *)address); break; default: - sprintf(buf, FORMAT_PTR, *(DWORD_PTR *)address); + fprintf(log_file, FORMAT_PTR, *(DWORD_PTR *)address); break; } break; case 8: if (basic_type == 8) /* btFloat */ - sprintf(buf, "%lf", *(double *)address); + fprintf(log_file, "%lf", *(double *)address); else - sprintf(buf, "0x%016I64X", *(unsigned __int64 *)address); + fprintf(log_file, "0x%016I64X", *(unsigned __int64 *)address); break; default: - sprintf(buf, "[unhandled type 0x%08x of length " FORMAT_PTR "]", - basic_type, length); + fprintf(log_file, "[unhandled type 0x%08x of length " FORMAT_PTR "]", + basic_type, (UINT_PTR)length); break; } } -/* Formats the value at address based on the type (pointer, user defined, - * basic type). */ +/* Writes the value at address based on the type (pointer, user defined, + * basic type) to LOG_FILE. */ static void -format_value(char *value_str, DWORD64 mod_base, DWORD type, void *value_addr) +write_value(FILE *log_file, DWORD64 mod_base, DWORD type, void *value_addr) { DWORD tag = 0; int ptr = 0; @@ -340,19 +341,19 @@ format_value(char *value_str, DWORD64 mod_base, DWORD type, void *value_addr) LocalFree(type_name_wbcs); if (ptr == 0) - sprintf(value_str, "(%s) " FORMAT_PTR, - type_name, (DWORD_PTR *)value_addr); + fprintf(log_file, "(%s) " FORMAT_PTR, + type_name, (UINT_PTR)(DWORD_PTR *)value_addr); else if (ptr == 1) - sprintf(value_str, "(%s *) " FORMAT_PTR, + fprintf(log_file, "(%s *) " FORMAT_PTR, type_name, *(DWORD_PTR *)value_addr); else - sprintf(value_str, "(%s **) " FORMAT_PTR, + fprintf(log_file, "(%s **) " FORMAT_PTR, type_name, *(DWORD_PTR *)value_addr); free(type_name); } else - sprintf(value_str, "[no symbol tag]"); + fprintf(log_file, "[no symbol tag]"); } break; case 16: /* SymTagBaseType */ @@ -364,27 +365,27 @@ format_value(char *value_str, DWORD64 mod_base, DWORD type, void *value_addr) /* print a char * as a string */ if (ptr == 1 && length == 1) { - sprintf(value_str, FORMAT_PTR " \"%s\"", + fprintf(log_file, FORMAT_PTR " \"%s\"", *(DWORD_PTR *)value_addr, *(const char **)value_addr); } else if (ptr >= 1) { - sprintf(value_str, FORMAT_PTR, *(DWORD_PTR *)value_addr); + fprintf(log_file, FORMAT_PTR, *(DWORD_PTR *)value_addr); } else if (SymGetTypeInfo_(proc, mod_base, type, TI_GET_BASETYPE, &bt)) { - format_basic_type(value_str, bt, length, value_addr); + write_basic_type(log_file, bt, length, value_addr); } } break; case 12: /* SymTagEnum */ - sprintf(value_str, "%d", *(DWORD_PTR *)value_addr); + fprintf(log_file, "%d", *(DWORD_PTR *)value_addr); break; case 13: /* SymTagFunctionType */ - sprintf(value_str, FORMAT_PTR, *(DWORD_PTR *)value_addr); + fprintf(log_file, FORMAT_PTR, *(DWORD_PTR *)value_addr); break; default: - sprintf(value_str, "[unhandled tag: %d]", tag); + fprintf(log_file, "[unhandled tag: %d]", tag); break; } } @@ -408,7 +409,6 @@ write_var_values(PSYMBOL_INFO sym_info, ULONG sym_size, void *baton) FILE *log_file = ((symbols_baton_t*)baton)->log_file; int nr_of_frame = ((symbols_baton_t*)baton)->nr_of_frame; BOOL log_params = ((symbols_baton_t*)baton)->log_params; - char value_str[256] = ""; /* get the variable's data */ if (sym_info->Flags & SYMFLAG_REGREL) @@ -422,21 +422,21 @@ write_var_values(PSYMBOL_INFO sym_info, ULONG sym_size, void *baton) if (log_params && sym_info->Flags & SYMFLAG_PARAMETER) { if (last_nr_of_frame == nr_of_frame) - fprintf(log_file, ", ", 2); + fprintf(log_file, ", "); else last_nr_of_frame = nr_of_frame; - format_value(value_str, sym_info->ModBase, sym_info->TypeIndex, - (void *)var_data); - fprintf(log_file, "%.*s=%s", (int)sym_info->NameLen, sym_info->Name, - value_str); + fprintf(log_file, "%.*s=", (int)sym_info->NameLen, sym_info->Name); + write_value(log_file, sym_info->ModBase, sym_info->TypeIndex, + (void *)var_data); } if (!log_params && sym_info->Flags & SYMFLAG_LOCAL) { - format_value(value_str, sym_info->ModBase, sym_info->TypeIndex, - (void *)var_data); - fprintf(log_file, " %.*s = %s\n", (int)sym_info->NameLen, - sym_info->Name, value_str); + fprintf(log_file, " %.*s = ", (int)sym_info->NameLen, + sym_info->Name); + write_value(log_file, sym_info->ModBase, sym_info->TypeIndex, + (void *)var_data); + fprintf(log_file, "\n"); } return TRUE; diff --git a/subversion/libsvn_subr/xml.c b/subversion/libsvn_subr/xml.c index 7f66b4531a541..edf21aae6d309 100644 --- a/subversion/libsvn_subr/xml.c +++ b/subversion/libsvn_subr/xml.c @@ -46,6 +46,14 @@ #error Expat is unusable -- it has been compiled for wide characters #endif +#ifndef XML_VERSION_AT_LEAST +#define XML_VERSION_AT_LEAST(major,minor,patch) \ +(((major) < XML_MAJOR_VERSION) \ + || ((major) == XML_MAJOR_VERSION && (minor) < XML_MINOR_VERSION) \ + || ((major) == XML_MAJOR_VERSION && (minor) == XML_MINOR_VERSION && \ + (patch) <= XML_MICRO_VERSION)) +#endif /* XML_VERSION_AT_LEAST */ + const char * svn_xml__compiled_version(void) { @@ -361,6 +369,28 @@ static void expat_data_handler(void *userData, const XML_Char *s, int len) (*svn_parser->data_handler)(svn_parser->baton, s, (apr_size_t)len); } +#if XML_VERSION_AT_LEAST(1, 95, 8) +static void expat_entity_declaration(void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName) +{ + svn_xml_parser_t *svn_parser = userData; + + /* Stop the parser if an entity declaration is hit. */ + XML_StopParser(svn_parser->parser, 0 /* resumable */); +} +#else +/* A noop default_handler. */ +static void expat_default_handler(void *userData, const XML_Char *s, int len) +{ +} +#endif /*** Making a parser. ***/ @@ -382,6 +412,12 @@ svn_xml_make_parser(void *baton, XML_SetCharacterDataHandler(parser, data_handler ? expat_data_handler : NULL); +#if XML_VERSION_AT_LEAST(1, 95, 8) + XML_SetEntityDeclHandler(parser, expat_entity_declaration); +#else + XML_SetDefaultHandler(parser, expat_default_handler); +#endif + /* ### we probably don't want this pool; or at least we should pass it ### to the callbacks and clear it periodically. */ subpool = svn_pool_create(pool); @@ -463,6 +499,9 @@ void svn_xml_signal_bailout(svn_error_t *error, /* This will cause the current XML_Parse() call to finish quickly! */ XML_SetElementHandler(svn_parser->parser, NULL, NULL); XML_SetCharacterDataHandler(svn_parser->parser, NULL); +#if XML_VERSION_AT_LEAST(1, 95, 8) + XML_SetEntityDeclHandler(svn_parser->parser, NULL); +#endif /* Once outside of XML_Parse(), the existence of this field will cause svn_delta_parse()'s main read-loop to return error. */ |