Skip to content

Commit 378ce61

Browse files
committed
config: catch exceptions during iteration
Not doing so means an exception or even a break will jump over us and not give us the opportunity to free the resources we've allocated.
1 parent 2e2e1ea commit 378ce61

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

ext/rugged/rugged_config.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -169,20 +169,22 @@ static VALUE rb_git_config_delete(VALUE self, VALUE rb_key)
169169
return Qtrue;
170170
}
171171

172-
static int cb_config__each_key(const git_config_entry *entry, void *opaque)
172+
static int cb_config__each_key(const git_config_entry *entry, void *payload)
173173
{
174-
rb_funcall((VALUE)opaque, rb_intern("call"), 1, rb_str_new_utf8(entry->name));
175-
return GIT_OK;
174+
int *exception = (int *) payload;
175+
176+
rb_protect(rb_yield, rb_ary_new3(1, rb_str_new_utf8(entry->name)), exception);
177+
178+
return (*exception != 0) ? GIT_EUSER : GIT_OK;
176179
}
177180

178-
static int cb_config__each_pair(const git_config_entry *entry, void *opaque)
181+
static int cb_config__each_pair(const git_config_entry *entry, void *payload)
179182
{
180-
rb_funcall((VALUE)opaque, rb_intern("call"), 2,
181-
rb_str_new_utf8(entry->name),
182-
rb_str_new_utf8(entry->value)
183-
);
183+
int *exception = (int *) payload;
184184

185-
return GIT_OK;
185+
rb_protect(rb_yield, rb_ary_new3(2, rb_str_new_utf8(entry->name), rb_str_new_utf8(entry->value)), exception);
186+
187+
return (*exception != 0) ? GIT_EUSER : GIT_OK;
186188
}
187189

188190
static int cb_config__to_hash(const git_config_entry *entry, void *opaque)
@@ -210,12 +212,15 @@ static int cb_config__to_hash(const git_config_entry *entry, void *opaque)
210212
static VALUE rb_git_config_each_key(VALUE self)
211213
{
212214
git_config *config;
213-
int error;
215+
int error, exception;
214216

215217
RETURN_ENUMERATOR(self, 0, 0);
216218
Data_Get_Struct(self, git_config, config);
217219

218-
error = git_config_foreach(config, &cb_config__each_key, (void *)rb_block_proc());
220+
error = git_config_foreach(config, &cb_config__each_key, &exception);
221+
if (error == GIT_EUSER)
222+
rb_jump_tag(exception);
223+
219224
rugged_exception_check(error);
220225
return Qnil;
221226
}
@@ -237,12 +242,15 @@ static VALUE rb_git_config_each_key(VALUE self)
237242
static VALUE rb_git_config_each_pair(VALUE self)
238243
{
239244
git_config *config;
240-
int error;
241-
245+
int error, exception;
246+
242247
RETURN_ENUMERATOR(self, 0, 0);
243248
Data_Get_Struct(self, git_config, config);
244249

245-
error = git_config_foreach(config, &cb_config__each_pair, (void *)rb_block_proc());
250+
error = git_config_foreach(config, &cb_config__each_pair, &exception);
251+
if (error == GIT_EUSER)
252+
rb_jump_tag(exception);
253+
246254
rugged_exception_check(error);
247255
return Qnil;
248256
}

0 commit comments

Comments
 (0)