diff options
author | Rob Austein <sra@hactrn.net> | 2012-03-09 21:07:35 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2012-03-09 21:07:35 +0000 |
commit | f3af4e1bf6566664759cad4bf9d59c3ea0442169 (patch) | |
tree | 2d86c79c2a5b08003970811e5a8a3a148d51e7eb | |
parent | 0eecc7942adf27d15c3fc86ec51affed180abc7e (diff) |
Fix fencepost error in walk_ctx_loop_next(). This closes #219.
svn path=/trunk/; revision=4391
-rw-r--r-- | rcynic/rcynic.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/rcynic/rcynic.c b/rcynic/rcynic.c index 46d3cb82..17b1493b 100644 --- a/rcynic/rcynic.c +++ b/rcynic/rcynic.c @@ -1620,22 +1620,35 @@ static int walk_ctx_loop_done(STACK_OF(walk_ctx_t) *wsk) * context which collectively define the current pass, product URI, * etc, and we want to be able to iterate through this sequence via * the event system. So this function steps to the next state. + * + * Conceptually, w->manifest->fileList and w->filenames form a single + * array with index w->manifest_iteration + w->filename_iteration. + * Beware of fencepost errors, I've gotten this wrong once already. + * Slightly odd coding here is to make it easier to check this. */ static void walk_ctx_loop_next(const rcynic_ctx_t *rc, STACK_OF(walk_ctx_t) *wsk) { walk_ctx_t *w = walk_ctx_stack_head(wsk); + int n_manifest, n_filenames; assert(rc && wsk && w); - if (w->manifest && w->manifest_iteration + 1 < sk_FileAndHash_num(w->manifest->fileList)) { - w->manifest_iteration++; - return; + assert(w->manifest_iteration >= 0 && w->filename_iteration >= 0); + + n_manifest = w->manifest ? sk_FileAndHash_num(w->manifest->fileList) : 0; + n_filenames = w->filenames ? sk_OPENSSL_STRING_num(w->filenames) : 0; + + if (w->manifest_iteration + w->filename_iteration < n_manifest + n_filenames) { + if (w->manifest_iteration < n_manifest) + w->manifest_iteration++; + else + w->filename_iteration++; } - if (w->filenames && w->filename_iteration + 1 < sk_OPENSSL_STRING_num(w->filenames)) { - w->filename_iteration++; + assert(w->manifest_iteration <= n_manifest && w->filename_iteration <= n_filenames); + + if (w->manifest_iteration + w->filename_iteration < n_manifest + n_filenames) return; - } while (!walk_ctx_loop_done(wsk)) { w->state++; |