aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2012-03-09 21:07:35 +0000
committerRob Austein <sra@hactrn.net>2012-03-09 21:07:35 +0000
commitf3af4e1bf6566664759cad4bf9d59c3ea0442169 (patch)
tree2d86c79c2a5b08003970811e5a8a3a148d51e7eb
parent0eecc7942adf27d15c3fc86ec51affed180abc7e (diff)
Fix fencepost error in walk_ctx_loop_next(). This closes #219.
svn path=/trunk/; revision=4391
-rw-r--r--rcynic/rcynic.c25
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++;