diff options
Diffstat (limited to 'config.c')
-rw-r--r-- | config.c | 106 |
1 files changed, 77 insertions, 29 deletions
@@ -464,7 +464,15 @@ static int store_aux(const char* key, const char* value) return 0; } -static void store_write_section(int fd, const char* key) +static int write_error() +{ + fprintf(stderr, "Failed to write new configuration file\n"); + + /* Same error code as "failed to rename". */ + return 4; +} + +static int store_write_section(int fd, const char* key) { const char *dot = strchr(key, '.'); int len1 = store.baselen, len2 = -1; @@ -478,37 +486,60 @@ static void store_write_section(int fd, const char* key) } } - write(fd, "[", 1); - write(fd, key, len1); + if (write_in_full(fd, "[", 1) != 1 || + write_in_full(fd, key, len1) != len1) + return 0; if (len2 >= 0) { - write(fd, " \"", 2); + if (write_in_full(fd, " \"", 2) != 2) + return 0; while (--len2 >= 0) { unsigned char c = *++dot; if (c == '"') - write(fd, "\\", 1); - write(fd, &c, 1); + if (write_in_full(fd, "\\", 1) != 1) + return 0; + if (write_in_full(fd, &c, 1) != 1) + return 0; } - write(fd, "\"", 1); + if (write_in_full(fd, "\"", 1) != 1) + return 0; } - write(fd, "]\n", 2); + if (write_in_full(fd, "]\n", 2) != 2) + return 0; + + return 1; } -static void store_write_pair(int fd, const char* key, const char* value) +static int store_write_pair(int fd, const char* key, const char* value) { int i; + int length = strlen(key+store.baselen+1); - write(fd, "\t", 1); - write(fd, key+store.baselen+1, - strlen(key+store.baselen+1)); - write(fd, " = ", 3); + if (write_in_full(fd, "\t", 1) != 1 || + write_in_full(fd, key+store.baselen+1, length) != length || + write_in_full(fd, " = ", 3) != 3) + return 0; for (i = 0; value[i]; i++) switch (value[i]) { - case '\n': write(fd, "\\n", 2); break; - case '\t': write(fd, "\\t", 2); break; - case '"': case '\\': write(fd, "\\", 1); - default: write(fd, value+i, 1); - } - write(fd, "\n", 1); + case '\n': + if (write_in_full(fd, "\\n", 2) != 2) + return 0; + break; + case '\t': + if (write_in_full(fd, "\\t", 2) != 2) + return 0; + break; + case '"': + case '\\': + if (write_in_full(fd, "\\", 1) != 1) + return 0; + default: + if (write_in_full(fd, value+i, 1) != 1) + return 0; + break; + } + if (write_in_full(fd, "\n", 1) != 1) + return 0; + return 1; } static int find_beginning_of_line(const char* contents, int size, @@ -648,8 +679,11 @@ int git_config_set_multivar(const char* key, const char* value, } store.key = (char*)key; - store_write_section(fd, key); - store_write_pair(fd, key, value); + if (!store_write_section(fd, key) || + !store_write_pair(fd, key, value)) { + ret = write_error(); + goto out_free; + } } else{ struct stat st; char* contents; @@ -729,10 +763,10 @@ int git_config_set_multivar(const char* key, const char* value, /* write the first part of the config */ if (copy_end > copy_begin) { - write(fd, contents + copy_begin, + write_in_full(fd, contents + copy_begin, copy_end - copy_begin); if (new_line) - write(fd, "\n", 1); + write_in_full(fd, "\n", 1); } copy_begin = store.offset[i]; } @@ -740,13 +774,19 @@ int git_config_set_multivar(const char* key, const char* value, /* write the pair (value == NULL means unset) */ if (value != NULL) { if (store.state == START) - store_write_section(fd, key); - store_write_pair(fd, key, value); + if (!store_write_section(fd, key)) { + ret = write_error(); + goto out_free; + } + if (!store_write_pair(fd, key, value)) { + ret = write_error(); + goto out_free; + } } /* write the rest of the config */ if (copy_begin < st.st_size) - write(fd, contents + copy_begin, + write_in_full(fd, contents + copy_begin, st.st_size - copy_begin); munmap(contents, st.st_size); @@ -800,6 +840,7 @@ int git_config_rename_section(const char *old_name, const char *new_name) while (fgets(buf, sizeof(buf), config_file)) { int i; + int length; for (i = 0; buf[i] && isspace(buf[i]); i++) ; /* do nothing */ if (buf[i] == '[') { @@ -830,15 +871,22 @@ int git_config_rename_section(const char *old_name, const char *new_name) /* old_name matches */ ret++; store.baselen = strlen(new_name); - store_write_section(out_fd, new_name); + if (!store_write_section(out_fd, new_name)) { + ret = write_error(); + goto out; + } continue; } } - write(out_fd, buf, strlen(buf)); + length = strlen(buf); + if (write_in_full(out_fd, buf, length) != length) { + ret = write_error(); + goto out; + } } fclose(config_file); if (close(out_fd) || commit_lock_file(lock) < 0) - ret = error("Cannot commit config file!"); + ret = error("Cannot commit config file!"); out: free(config_filename); return ret; |