On Fri, Feb 15, 2002 at 02:04:12AM +0000, Philip Martin wrote:
>
> Breaks on Linux/gcc, it segfaults on svn up, make check, etc. It
> appears to be whenever ap is NULL on entry to this function.
>
> Is it valid to use va_arg without va_start? Is it valid to use va_arg
> at all in a function without a ... prototype?
Yes to both, if and only if the va_list argument used by the function
calling va_arg, was initialized by a function with a ... prototype
that called va_start and has not yet called va_end or returned.
However, if a va_list is passed as a direct parameter instead of
through a pointer, the caller and callee must not both use va_arg on
it, or the behavior is undefined.
va_arg (NULL, type) is perfectly entitled to crash, or fail to
compile; passing NULL as a va_list parameter is allowed to fail to
compile.
Looking at the code in entries.c, I would suggest that fold_entry be
changed to take a pointer to a va_list type, instead of a direct
va_list, like the appended patch. Also, va_end needs to be called in
svn_wc__entry_modify. (Yes, I know it doesn't do anything on sane
architectures; that's not an excuse to break the rules.)
Patch is completely untested, btw.
zw
* libsvn_wc/entries.c (fold_entry): Take a pointer to a va_list,
not a bare va_list, so that we can check whether it's NULL.
(svn_wc__entry_modify): Change to match. Call va_end.
===================================================================
Index: subversion/libsvn_wc/entries.c
--- subversion/libsvn_wc/entries.c
+++ subversion/libsvn_wc/entries.c Thu Feb 14 18:23:59 2002
@@ -1005,7 +1005,7 @@
const svn_stringbuf_t *url,
apr_hash_t *atts,
apr_pool_t *pool,
- va_list ap)
+ va_list *pap)
{
apr_hash_index_t *hi;
svn_wc_entry_t *entry = apr_hash_get (entries, name->data, name->len);
@@ -1088,8 +1088,11 @@
normalize_entry (entry, pool);
/* Remove any attributes named for removal. */
- while ((remove_me = va_arg (ap, const char *)) != NULL)
- apr_hash_set (entry->attributes, remove_me, APR_HASH_KEY_STRING, NULL);
+ if (pap)
+ {
+ while ((remove_me = va_arg (*pap, const char *)) != NULL)
+ apr_hash_set (entry->attributes, remove_me, APR_HASH_KEY_STRING, NULL);
+ }
/* Make sure the entry exists in the entries hash. Possibly it
already did, in which case this could have been skipped, but what
@@ -1372,10 +1375,11 @@
if (! entry_was_deleted_p)
fold_entry (entries, name, modify_flags, revision, kind,
schedule, conflicted, copied, text_time,
- prop_time, url, attributes, pool, ap);
+ prop_time, url, attributes, pool, &ap);
SVN_ERR (svn_wc__entries_write (entries, path, pool));
+ va_end (ap);
return SVN_NO_ERROR;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:37:08 2006