[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn commit: rev 1287 - trunk/subversion/libsvn_wc

From: Zack Weinberg <zack_at_codesourcery.com>
Date: 2002-02-15 03:28:56 CET

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

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.