summaryrefslogtreecommitdiff
path: root/src/errors.c
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2015-08-03 16:50:27 -0500
committerEdward Thomson <ethomson@edwardthomson.com>2015-08-03 19:44:51 -0400
commitef4857c2b3d4a61fd1d840199afc92eaf2e15345 (patch)
tree2e02b7fcc28a00c0eede602b8880b83a9fd35c77 /src/errors.c
parent854b701c8a799a484ef48d8b595601ab29876b57 (diff)
downloadlibgit2-ef4857c2b3d4a61fd1d840199afc92eaf2e15345.tar.gz
errors: tighten up git_error_state OOMs a bit more
When an error state is an OOM, make sure that we treat is specially and do not try to free it.
Diffstat (limited to 'src/errors.c')
-rw-r--r--src/errors.c72
1 files changed, 42 insertions, 30 deletions
diff --git a/src/errors.c b/src/errors.c
index 973326c00..91acc3541 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -131,53 +131,65 @@ void giterr_clear(void)
#endif
}
-static int giterr_detach(git_error *cpy)
+const git_error *giterr_last(void)
+{
+ return GIT_GLOBAL->last_error;
+}
+
+int giterr_state_capture(git_error_state *state, int error_code)
{
git_error *error = GIT_GLOBAL->last_error;
- git_buf *buf = &GIT_GLOBAL->error_buf;
+ git_buf *error_buf = &GIT_GLOBAL->error_buf;
- assert(cpy);
+ memset(state, 0, sizeof(git_error_state));
- if (!error)
- return -1;
+ if (!error_code)
+ return 0;
+
+ state->error_code = error_code;
+ state->oom = (error == &g_git_oom_error);
- cpy->message = git_buf_detach(buf);
- cpy->klass = error->klass;
+ if (error) {
+ state->error_msg.klass = error->klass;
- if (error != &g_git_oom_error) {
- error->message = NULL;
+ if (state->oom)
+ state->error_msg.message = g_git_oom_error.message;
+ else
+ state->error_msg.message = git_buf_detach(error_buf);
}
- giterr_clear();
- return 0;
+ giterr_clear();
+ return error_code;
}
-const git_error *giterr_last(void)
+int giterr_state_restore(git_error_state *state)
{
- return GIT_GLOBAL->last_error;
-}
+ int ret = 0;
-int giterr_capture(git_error_state *state, int error_code)
-{
- state->error_code = error_code;
- if (error_code)
- giterr_detach(&state->error_msg);
- return error_code;
-}
+ giterr_clear();
-int giterr_restore(git_error_state *state)
-{
- if (state && state->error_code && state->error_msg.message) {
- if (state->error_msg.message == g_git_oom_error.message) {
+ if (state && state->error_msg.message) {
+ if (state->oom)
giterr_set_oom();
- } else {
+ else
set_error(state->error_msg.klass, state->error_msg.message);
- }
+
+ ret = state->error_code;
+ memset(state, 0, sizeof(git_error_state));
}
- else
- giterr_clear();
- return state ? state->error_code : 0;
+ return ret;
+}
+
+void giterr_state_free(git_error_state *state)
+{
+ if (!state)
+ return;
+
+ if (!state->oom)
+ git__free(state->error_msg.message);
+
+ memset(state, 0, sizeof(git_error_state));
}
int giterr_system_last(void)