* [PATCH] refs.c: add a function to append a reflog entry to a fd
@ 2014-11-20 0:42 Stefan Beller
2014-11-20 1:22 ` Junio C Hamano
2014-11-20 1:42 ` [PATCH] " Jonathan Nieder
0 siblings, 2 replies; 18+ messages in thread
From: Stefan Beller @ 2014-11-20 0:42 UTC (permalink / raw)
To: sahlberg, jrnieder, gitster, git; +Cc: Stefan Beller
From: Ronnie Sahlberg <sahlberg@google.com>
Break out the code to create the string and writing it to the file
descriptor from log_ref_write and add it into a dedicated function
log_ref_write_fd. For now this is only used from log_ref_write,
but later on we will call this function from reflog transactions too,
which means that we will end up with only a single place,
where we write a reflog entry to a file instead of the current two
places (log_ref_write and builtin/reflog.c).
[sb: replaced sprintf by snprintf for security reasons,
which was there in the beginning (6de08ae688b9f2, 2006-06-17,
Log ref updates to logs/refs/<ref>), but got lost in (8ac65937d032ad,
2007-01-26, Make sure we do not write bogus reflog entries.)
]
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
refs.c | 48 ++++++++++++++++++++++++++++++------------------
1 file changed, 30 insertions(+), 18 deletions(-)
This is also part of the ref-transaction-reflog series, but is
sufficiently independant, that I'd argue it's a general code hygiene thing,
we can use in any case.
Applies on master.
Compared to the last send of this patch[1], there was one change in the print
function. Replaced sprintf by snprintf for security reasons.
[1] part of the ref-transaction-reflog series
http://permalink.gmane.org/gmane.comp.version-control.git/259714
diff --git a/refs.c b/refs.c
index 5ff457e..f9b42e5 100644
--- a/refs.c
+++ b/refs.c
@@ -2990,15 +2990,37 @@ int log_ref_setup(const char *refname, char *logfile, int bufsize)
return 0;
}
+static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
+ const unsigned char *new_sha1,
+ const char *committer, const char *msg)
+{
+ int msglen, written;
+ unsigned maxlen, len;
+ char *logrec;
+
+ msglen = msg ? strlen(msg) : 0;
+ maxlen = strlen(committer) + msglen + 100;
+ logrec = xmalloc(maxlen);
+ len = snprintf(logrec, maxlen, "%s %s %s\n",
+ sha1_to_hex(old_sha1),
+ sha1_to_hex(new_sha1),
+ committer);
+ if (msglen)
+ len += copy_msg(logrec + len - 1, msg) - 1;
+
+ written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
+ free(logrec);
+ if (written != len)
+ return -1;
+
+ return 0;
+}
+
static int log_ref_write(const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg)
{
- int logfd, result, written, oflags = O_APPEND | O_WRONLY;
- unsigned maxlen, len;
- int msglen;
+ int logfd, result, oflags = O_APPEND | O_WRONLY;
char log_file[PATH_MAX];
- char *logrec;
- const char *committer;
if (log_all_ref_updates < 0)
log_all_ref_updates = !is_bare_repository();
@@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
logfd = open(log_file, oflags);
if (logfd < 0)
return 0;
- msglen = msg ? strlen(msg) : 0;
- committer = git_committer_info(0);
- maxlen = strlen(committer) + msglen + 100;
- logrec = xmalloc(maxlen);
- len = sprintf(logrec, "%s %s %s\n",
- sha1_to_hex(old_sha1),
- sha1_to_hex(new_sha1),
- committer);
- if (msglen)
- len += copy_msg(logrec + len - 1, msg) - 1;
- written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
- free(logrec);
- if (written != len) {
+ result = log_ref_write_fd(logfd, old_sha1, new_sha1,
+ git_committer_info(0), msg);
+ if (result) {
int save_errno = errno;
close(logfd);
error("Unable to append to %s", log_file);
--
2.2.0.rc2.13.g0786cdb
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH] refs.c: add a function to append a reflog entry to a fd
2014-11-20 0:42 [PATCH] refs.c: add a function to append a reflog entry to a fd Stefan Beller
@ 2014-11-20 1:22 ` Junio C Hamano
2014-11-20 1:34 ` Junio C Hamano
2014-11-20 1:42 ` [PATCH] " Jonathan Nieder
1 sibling, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2014-11-20 1:22 UTC (permalink / raw)
To: Stefan Beller; +Cc: sahlberg, jrnieder, git
Stefan Beller <sbeller@google.com> writes:
> Compared to the last send of this patch[1], there was one change in the print
> function. Replaced sprintf by snprintf for security reasons.
Careful. I despise people who blindly think strlcpy() and
snprintf() are good solutions for for security. They are by
themselves not.
Surely, the use of them lets you avoid stomping on pieces of memory
that you did not intend to write to. I'd call that "protecting
other people's data".
But what about your own data? If you are thinking that you are
trying to write "this and that", but by mistake (either by your or
by a careless future change) if you did not allocate enough, you
would stop at "this and th". You may have protected other people's
data, but your result is still broken. If you gave that to others
without checking that you produced an incomplete piece of data, what
guarantee are you getting that you are not creating a security hole
there (imagine you intended to copy "rm -fr ./tmpdir" and by mistake
you stopped at "rm -fr ./" @~@).
> + msglen = msg ? strlen(msg) : 0;
> + maxlen = strlen(committer) + msglen + 100;
> + logrec = xmalloc(maxlen);
> + len = snprintf(logrec, maxlen, "%s %s %s\n",
> + sha1_to_hex(old_sha1),
> + sha1_to_hex(new_sha1),
> + committer);
> + if (msglen)
> + len += copy_msg(logrec + len - 1, msg) - 1;
In this codepath, you are allocating enough buffer to hold the whole
message; there is no difference between sprintf() and snprintf().
If the difference mattered, you would have chopped the reflog entry
too short, and produced a wrong result, but you then discard the
whole record (the code that follows the above), losing data.
So use of snprintf() is not really buying you much here, not in the
current code certainly, but not as a future-proofing measure,
either.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] refs.c: add a function to append a reflog entry to a fd
2014-11-20 1:22 ` Junio C Hamano
@ 2014-11-20 1:34 ` Junio C Hamano
2014-11-20 2:05 ` Stefan Beller
0 siblings, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2014-11-20 1:34 UTC (permalink / raw)
To: Stefan Beller; +Cc: sahlberg, jrnieder, git
Junio C Hamano <gitster@pobox.com> writes:
> Stefan Beller <sbeller@google.com> writes:
>
>> Compared to the last send of this patch[1], there was one change in the print
>> function. Replaced sprintf by snprintf for security reasons.
>
> Careful. I despise people who blindly think strlcpy() and
> snprintf() are good solutions for for security. They are by
> themselves not.
> ...
> So use of snprintf() is not really buying you much here, not in the
> current code certainly, but not as a future-proofing measure,
> either.
Don't get me wrong. I am not saying that using snprintf() here is
bad per-se. There should be no difference.
But I do not want to see people getting in the habit of thinking "I
now use snprintf/strlcpy instead of sprintf/strcpy, and made my code
more secure." Often they are not doing that.
The only case snprintf/strlcpy is useful is when your data does not
matter in its detail. E.g. when you are preparing human-readble
data whose first part is sufficient to convey the information you
want to convey, you would be perfectly happy if the result is
truncated. In such a case, counting to allocate enough to hold
everything and running sprintf() only to chop the result later is
not necessary --- it still is not wrong, though --- and allocating
enough to satisify the eventual chop length and using snprintf()
is easier way to achieve the same result.
But I do not think this codepath falls into such an "I am willing to
lose data" case.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] refs.c: add a function to append a reflog entry to a fd
2014-11-20 0:42 [PATCH] refs.c: add a function to append a reflog entry to a fd Stefan Beller
2014-11-20 1:22 ` Junio C Hamano
@ 2014-11-20 1:42 ` Jonathan Nieder
1 sibling, 0 replies; 18+ messages in thread
From: Jonathan Nieder @ 2014-11-20 1:42 UTC (permalink / raw)
To: Stefan Beller; +Cc: sahlberg, gitster, git
Stefan Beller wrote:
> Compared to the last send of this patch[1], there was one change in the print
> function. Replaced sprintf by snprintf for security reasons.
I prefer the version that didn't change the code while we are
extracting it into a new function. A separate patch on top can switch
it to use strbuf_addf or xstrfmt if we want that.
My two cents,
Jonathan
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH] refs.c: add a function to append a reflog entry to a fd
2014-11-20 1:34 ` Junio C Hamano
@ 2014-11-20 2:05 ` Stefan Beller
2014-11-20 2:36 ` Jonathan Nieder
0 siblings, 1 reply; 18+ messages in thread
From: Stefan Beller @ 2014-11-20 2:05 UTC (permalink / raw)
To: git, gitster, jrnieder, sahlberg; +Cc: Stefan Beller
Break out the code to create the string and writing it to the file
descriptor from log_ref_write and add it into a dedicated function
log_ref_write_fd. For now this is only used from log_ref_write,
but later on we will call this function from reflog transactions too,
which means that we will end up with only a single place,
where we write a reflog entry to a file instead of the current two
places (log_ref_write and builtin/reflog.c).
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
refs.c | 48 ++++++++++++++++++++++++++++++------------------
1 file changed, 30 insertions(+), 18 deletions(-)
Sorry for the small change w.r.t. sprintf/snprintf
Here comes a resend without changing code, but just making it a new function,
so we come forwards with the patch.
Let's discuss the change and decide if I shouldsend a follow up patch to change
it into snprintf.
On Wed, Nov 19, 2014 at 5:22 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> + logrec = xmalloc(maxlen);
>> + len = snprintf(logrec, maxlen, "%s %s %s\n",
>> + sha1_to_hex(old_sha1),
>> + sha1_to_hex(new_sha1),
>> + committer);
>> + if (msglen)
>> + len += copy_msg(logrec + len - 1, msg) - 1;
>
> In this codepath, you are allocating enough buffer to hold the whole
> message; there is no difference between sprintf() and snprintf().
> If the difference mattered, you would have chopped the reflog entry
> too short, and produced a wrong result, but you then discard the
> whole record (the code that follows the above), losing data.
Hypothetically speaking:
There should be no difference between sprintf() and snprintf(). As soon as you
would have a difference, you'd risk stomping on other peoples data, which could lead
to code insertion, iff the format of the inserted data is long enough overwriting
parts of your stack? Or you could change data to alter the program flow to direct
the program to another easier abusable bug.
Does this make sense? This is about protecting a user from a malicious attacker.
> imagine you intended to copy "rm -fr ./tmpdir" and by mistake
> you stopped at "rm -fr ./" @~@).
Yes, that's when you should check the return code of snprintf and compare to
strlen("rm -fr ./tmpdir"). That kind of bug also has severe consequences, but
it's not yet involving a malicious attacker, so I'd file this as a safety instead
of a security flaw.
Safety related bugs are easier to find usually as you don't need to have to
think about what weird things an attacker might do. This kind of bug can be found
directly from reading the code and its surroundings
("there it should print 'rm -fr ./tmpdir'... Gah! I did not check the return value")
diff --git a/refs.c b/refs.c
index 5ff457e..f9b42e5 100644
--- a/refs.c
+++ b/refs.c
@@ -2990,15 +2990,37 @@ int log_ref_setup(const char *refname, char *logfile, int bufsize)
return 0;
}
+static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
+ const unsigned char *new_sha1,
+ const char *committer, const char *msg)
+{
+ int msglen, written;
+ unsigned maxlen, len;
+ char *logrec;
+
+ msglen = msg ? strlen(msg) : 0;
+ maxlen = strlen(committer) + msglen + 100;
+ logrec = xmalloc(maxlen);
+ len = sprintf(logrec, maxlen, "%s %s %s\n",
+ sha1_to_hex(old_sha1),
+ sha1_to_hex(new_sha1),
+ committer);
+ if (msglen)
+ len += copy_msg(logrec + len - 1, msg) - 1;
+
+ written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
+ free(logrec);
+ if (written != len)
+ return -1;
+
+ return 0;
+}
+
static int log_ref_write(const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg)
{
- int logfd, result, written, oflags = O_APPEND | O_WRONLY;
- unsigned maxlen, len;
- int msglen;
+ int logfd, result, oflags = O_APPEND | O_WRONLY;
char log_file[PATH_MAX];
- char *logrec;
- const char *committer;
if (log_all_ref_updates < 0)
log_all_ref_updates = !is_bare_repository();
@@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
logfd = open(log_file, oflags);
if (logfd < 0)
return 0;
- msglen = msg ? strlen(msg) : 0;
- committer = git_committer_info(0);
- maxlen = strlen(committer) + msglen + 100;
- logrec = xmalloc(maxlen);
- len = sprintf(logrec, "%s %s %s\n",
- sha1_to_hex(old_sha1),
- sha1_to_hex(new_sha1),
- committer);
- if (msglen)
- len += copy_msg(logrec + len - 1, msg) - 1;
- written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
- free(logrec);
- if (written != len) {
+ result = log_ref_write_fd(logfd, old_sha1, new_sha1,
+ git_committer_info(0), msg);
+ if (result) {
int save_errno = errno;
close(logfd);
error("Unable to append to %s", log_file);
--
2.2.0.rc2.13.g0786cdb
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH] refs.c: add a function to append a reflog entry to a fd
2014-11-20 2:05 ` Stefan Beller
@ 2014-11-20 2:36 ` Jonathan Nieder
2014-11-20 16:57 ` Junio C Hamano
2014-11-20 18:37 ` [PATCH v3] " Stefan Beller
0 siblings, 2 replies; 18+ messages in thread
From: Jonathan Nieder @ 2014-11-20 2:36 UTC (permalink / raw)
To: Stefan Beller; +Cc: git, gitster, sahlberg
Stefan Beller wrote:
> [Subject: [PATCH] refs.c: add a function to append a reflog entry to a fd]
Does this supersede the other patch with the same subject?
Please keep adding v<num> in the subject --- when it's there, it makes
reading much easier.
>
Missing 'From:' line naming the original patch author.
> Break out the code to create the string and writing it to the file
> descriptor from log_ref_write and add it into a dedicated function
> log_ref_write_fd.
(grammar) I'm having trouble parsing the above.
Is the idea something like "Split out a function that [explanation
of when a caller would use this function goes here]?"
> For now this is only used from log_ref_write,
> but later on we will call this function from reflog transactions too,
Useful to know. I'd end the sentence here, since it seems to run
on with a different thought.
> which means that we will end up with only a single place,
> where we write a reflog entry to a file instead of the current two
> places (log_ref_write and builtin/reflog.c).
Ah, so builtin/reflog.c is doing something similar and will later
be changed to use this code, too?
Overall it sounds like a very good change.
[...]
> Here comes a resend without changing code, but just making it a new function,
> so we come forwards with the patch.
\o/
> Let's discuss the change and decide if I shouldsend a follow up patch to change
> it into snprintf.
Both sprintf and snprintf are error-prone functions. It would be
lovely in a followup to use strbuf_addf or xstrfmt in this code path.
strbufs are how git deals with bookkeeping for string sizes --- they
are very pleasant.
[...]
> +++ b/refs.c
[...]
> @@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
[...]
> + result = log_ref_write_fd(logfd, old_sha1, new_sha1,
> + git_committer_info(0), msg);
> + if (result) {
> int save_errno = errno;
> close(logfd);
> error("Unable to append to %s", log_file);
Since 'result' isn't used here, this could be simplified to
if (log_ref_write_fd(...)) {
...
}
Thanks and hope that helps,
Jonathan
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] refs.c: add a function to append a reflog entry to a fd
2014-11-20 2:36 ` Jonathan Nieder
@ 2014-11-20 16:57 ` Junio C Hamano
2014-11-20 18:37 ` [PATCH v3] " Stefan Beller
1 sibling, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2014-11-20 16:57 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Stefan Beller, git, sahlberg
Jonathan Nieder <jrnieder@gmail.com> writes:
>> Break out the code to create the string and writing it to the file
>> descriptor from log_ref_write and add it into a dedicated function
>> log_ref_write_fd.
>
> (grammar) I'm having trouble parsing the above.
Yeah, I can see what it wants to say, but still...
>> Let's discuss the change and decide if I shouldsend a follow up patch to change
>> it into snprintf.
>
> Both sprintf and snprintf are error-prone functions. It would be
> lovely in a followup to use strbuf_addf or xstrfmt in this code path.
> strbufs are how git deals with bookkeeping for string sizes --- they
> are very pleasant.
Yeah, that solves both sides of not stomping on other peoples' data
(which may lead to replaced return address and such) and not giving
broken result (which may cause trouble to the callers) equally well
without raising a stink about "security!!!", which is good ;-).
>> @@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname,
>> const unsigned char *old_sha1,
> [...]
>> + result = log_ref_write_fd(logfd, old_sha1, new_sha1,
>> + git_committer_info(0), msg);
>> + if (result) {
>> int save_errno = errno;
>> close(logfd);
>> error("Unable to append to %s", log_file);
>
> Since 'result' isn't used here, this could be simplified to
>
> if (log_ref_write_fd(...)) {
> ...
> }
Yeah that is a good simplification.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3] refs.c: add a function to append a reflog entry to a fd
2014-11-20 2:36 ` Jonathan Nieder
2014-11-20 16:57 ` Junio C Hamano
@ 2014-11-20 18:37 ` Stefan Beller
2014-11-20 21:20 ` Jonathan Nieder
2014-11-20 21:42 ` Junio C Hamano
1 sibling, 2 replies; 18+ messages in thread
From: Stefan Beller @ 2014-11-20 18:37 UTC (permalink / raw)
To: git, jrnieder, gitster; +Cc: Ronnie Sahlberg, Stefan Beller
From: Ronnie Sahlberg <sahlberg@google.com>
Move code to create the string for a ref and write it to a file descriptor
from log_ref_write and add it into a new dedicated function
log_ref_write_fd.
For now the new function is only used from log_ref_write, but later
on we will call this function from reflog transactions too. That means
that we will end up with only a single place, where we write a
reflog entry to a file instead of the current two places
(log_ref_write and builtin/reflog.c).
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
Changes in version 3:
* reword the commit message to make it more understandable.
* no changes in code
* wait for the follow up to address any changes in the code.
refs.c | 48 ++++++++++++++++++++++++++++++------------------
1 file changed, 30 insertions(+), 18 deletions(-)
diff --git a/refs.c b/refs.c
index 5ff457e..9948841 100644
--- a/refs.c
+++ b/refs.c
@@ -2990,15 +2990,37 @@ int log_ref_setup(const char *refname, char *logfile, int bufsize)
return 0;
}
+static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
+ const unsigned char *new_sha1,
+ const char *committer, const char *msg)
+{
+ int msglen, written;
+ unsigned maxlen, len;
+ char *logrec;
+
+ msglen = msg ? strlen(msg) : 0;
+ maxlen = strlen(committer) + msglen + 100;
+ logrec = xmalloc(maxlen);
+ len = sprintf(logrec, maxlen, "%s %s %s\n",
+ sha1_to_hex(old_sha1),
+ sha1_to_hex(new_sha1),
+ committer);
+ if (msglen)
+ len += copy_msg(logrec + len - 1, msg) - 1;
+
+ written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
+ free(logrec);
+ if (written != len)
+ return -1;
+
+ return 0;
+}
+
static int log_ref_write(const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg)
{
- int logfd, result, written, oflags = O_APPEND | O_WRONLY;
- unsigned maxlen, len;
- int msglen;
+ int logfd, result, oflags = O_APPEND | O_WRONLY;
char log_file[PATH_MAX];
- char *logrec;
- const char *committer;
if (log_all_ref_updates < 0)
log_all_ref_updates = !is_bare_repository();
@@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
logfd = open(log_file, oflags);
if (logfd < 0)
return 0;
- msglen = msg ? strlen(msg) : 0;
- committer = git_committer_info(0);
- maxlen = strlen(committer) + msglen + 100;
- logrec = xmalloc(maxlen);
- len = sprintf(logrec, "%s %s %s\n",
- sha1_to_hex(old_sha1),
- sha1_to_hex(new_sha1),
- committer);
- if (msglen)
- len += copy_msg(logrec + len - 1, msg) - 1;
- written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
- free(logrec);
- if (written != len) {
+ result = log_ref_write_fd(logfd, old_sha1, new_sha1,
+ git_committer_info(0), msg);
+ if (result) {
int save_errno = errno;
close(logfd);
error("Unable to append to %s", log_file);
--
2.2.0.rc2.23.gca0107e
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v3] refs.c: add a function to append a reflog entry to a fd
2014-11-20 18:37 ` [PATCH v3] " Stefan Beller
@ 2014-11-20 21:20 ` Jonathan Nieder
2014-11-20 21:24 ` Stefan Beller
2014-11-20 21:42 ` Junio C Hamano
1 sibling, 1 reply; 18+ messages in thread
From: Jonathan Nieder @ 2014-11-20 21:20 UTC (permalink / raw)
To: Stefan Beller; +Cc: git, gitster, Ronnie Sahlberg
Stefan Beller wrote:
> From: Ronnie Sahlberg <sahlberg@google.com>
>
> Move code to create the string for a ref and write it to a file descriptor
> from log_ref_write and add it into a new dedicated function
> log_ref_write_fd.
>
> For now the new function is only used from log_ref_write, but later
> on we will call this function from reflog transactions too. That means
> that we will end up with only a single place, where we write a
> reflog entry to a file instead of the current two places
> (log_ref_write and builtin/reflog.c).
Line-wrapping width is still inconsistent. I don't think it's worth
resending just for that, but something to look out for in the future.
> Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
[...]
> +++ b/refs.c
[...]
> @@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
[...]
> + result = log_ref_write_fd(logfd, old_sha1, new_sha1,
> + git_committer_info(0), msg);
> + if (result) {
> int save_errno = errno;
I don't understand why the above writes to a temporary variable and
checks it, never to read that temporary again.
I don't think that alone is a reason to block the patch, but it
worries me in that the review comment seems to have been just lost.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3] refs.c: add a function to append a reflog entry to a fd
2014-11-20 21:20 ` Jonathan Nieder
@ 2014-11-20 21:24 ` Stefan Beller
2014-11-20 21:31 ` Jonathan Nieder
0 siblings, 1 reply; 18+ messages in thread
From: Stefan Beller @ 2014-11-20 21:24 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: git@vger.kernel.org, Junio C Hamano, Ronnie Sahlberg
On Thu, Nov 20, 2014 at 1:20 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
>>
>> For now the new function is only used from log_ref_write, but later
>> on we will call this function from reflog transactions too. That means
>> that we will end up with only a single place, where we write a
>> reflog entry to a file instead of the current two places
>> (log_ref_write and builtin/reflog.c).
>
> Line-wrapping width is still inconsistent. I don't think it's worth
> resending just for that, but something to look out for in the future.
>
ok, I'll care about that more in the future.
> I don't understand why the above writes to a temporary variable and
> checks it, never to read that temporary again.
>
> I don't think that alone is a reason to block the patch, but it
> worries me in that the review comment seems to have been just lost.
It wasn't lost as I think it should go in a follow up patch. Sorry for
not stating that clearly.
(This patch is about moving code around, not changing code)
I got interrupted preparing the follow up patch, which gets rid of the temporary
variable.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3] refs.c: add a function to append a reflog entry to a fd
2014-11-20 21:24 ` Stefan Beller
@ 2014-11-20 21:31 ` Jonathan Nieder
0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Nieder @ 2014-11-20 21:31 UTC (permalink / raw)
To: Stefan Beller; +Cc: git@vger.kernel.org, Junio C Hamano, Ronnie Sahlberg
Stefan Beller wrote:
> On Thu, Nov 20, 2014 at 1:20 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
>> I don't understand why the above writes to a temporary variable and
>> checks it, never to read that temporary again.
>>
>> I don't think that alone is a reason to block the patch, but it
>> worries me in that the review comment seems to have been just lost.
>
> It wasn't lost as I think it should go in a follow up patch. Sorry for
> not stating that clearly.
> (This patch is about moving code around, not changing code)
Ah, sorry for the lack of clarity.
I agree completely with the above principle. But the code that writes
to result and checks result is new code, not part of the code that
moved.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3] refs.c: add a function to append a reflog entry to a fd
2014-11-20 18:37 ` [PATCH v3] " Stefan Beller
2014-11-20 21:20 ` Jonathan Nieder
@ 2014-11-20 21:42 ` Junio C Hamano
2014-11-20 21:58 ` Stefan Beller
2014-11-20 21:59 ` [PATCH v4] " Stefan Beller
1 sibling, 2 replies; 18+ messages in thread
From: Junio C Hamano @ 2014-11-20 21:42 UTC (permalink / raw)
To: Stefan Beller; +Cc: git, jrnieder, Ronnie Sahlberg
Stefan Beller <sbeller@google.com> writes:
> From: Ronnie Sahlberg <sahlberg@google.com>
>
> Move code to create the string for a ref and write it to a file descriptor
> from log_ref_write and add it into a new dedicated function
> log_ref_write_fd.
>
> For now the new function is only used from log_ref_write, but later
> on we will call this function from reflog transactions too. That means
> that we will end up with only a single place, where we write a
> reflog entry to a file instead of the current two places
> (log_ref_write and builtin/reflog.c).
>
> Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>
> Changes in version 3:
> * reword the commit message to make it more understandable.
> * no changes in code
> * wait for the follow up to address any changes in the code.
>
> refs.c | 48 ++++++++++++++++++++++++++++++------------------
> 1 file changed, 30 insertions(+), 18 deletions(-)
>
> diff --git a/refs.c b/refs.c
> index 5ff457e..9948841 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -2990,15 +2990,37 @@ int log_ref_setup(const char *refname, char *logfile, int bufsize)
> return 0;
> }
>
> +static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
> + const unsigned char *new_sha1,
> + const char *committer, const char *msg)
> +{
> + int msglen, written;
> + unsigned maxlen, len;
> + char *logrec;
> +
> + msglen = msg ? strlen(msg) : 0;
> + maxlen = strlen(committer) + msglen + 100;
> + logrec = xmalloc(maxlen);
> + len = sprintf(logrec, maxlen, "%s %s %s\n",
You cannot have maxlen here ;-)
> + sha1_to_hex(old_sha1),
> + sha1_to_hex(new_sha1),
> + committer);
> + if (msglen)
> + len += copy_msg(logrec + len - 1, msg) - 1;
> +
> + written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
> + free(logrec);
> + if (written != len)
> + return -1;
> +
> + return 0;
> +}
> +
> static int log_ref_write(const char *refname, const unsigned char *old_sha1,
> const unsigned char *new_sha1, const char *msg)
> {
> - int logfd, result, written, oflags = O_APPEND | O_WRONLY;
> - unsigned maxlen, len;
> - int msglen;
> + int logfd, result, oflags = O_APPEND | O_WRONLY;
> char log_file[PATH_MAX];
> - char *logrec;
> - const char *committer;
>
> if (log_all_ref_updates < 0)
> log_all_ref_updates = !is_bare_repository();
> @@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
> logfd = open(log_file, oflags);
> if (logfd < 0)
> return 0;
> - msglen = msg ? strlen(msg) : 0;
> - committer = git_committer_info(0);
> - maxlen = strlen(committer) + msglen + 100;
> - logrec = xmalloc(maxlen);
> - len = sprintf(logrec, "%s %s %s\n",
> - sha1_to_hex(old_sha1),
> - sha1_to_hex(new_sha1),
> - committer);
> - if (msglen)
> - len += copy_msg(logrec + len - 1, msg) - 1;
> - written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
> - free(logrec);
> - if (written != len) {
> + result = log_ref_write_fd(logfd, old_sha1, new_sha1,
> + git_committer_info(0), msg);
> + if (result) {
> int save_errno = errno;
> close(logfd);
> error("Unable to append to %s", log_file);
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3] refs.c: add a function to append a reflog entry to a fd
2014-11-20 21:42 ` Junio C Hamano
@ 2014-11-20 21:58 ` Stefan Beller
2014-11-20 22:05 ` Jonathan Nieder
2014-11-20 21:59 ` [PATCH v4] " Stefan Beller
1 sibling, 1 reply; 18+ messages in thread
From: Stefan Beller @ 2014-11-20 21:58 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, jrnieder, Ronnie Sahlberg
>From 4bec12b878ca02a1e80af3c265e7e7ab52ba17ce Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <sahlberg@google.com>
Date: Thu, 20 Nov 2014 13:48:14 -0800
Subject: [PATCH v4] refs.c: add a function to append a reflog entry to a fd
Move code to create the string for a ref and write it to a file descriptor
from log_ref_write and add it into a new dedicated function
log_ref_write_fd.
For now the new function is only used from log_ref_write, but later
on we will call this function from reflog transactions too. That means
that we will end up with only a single place, where we write a reflog
entry to a file instead of the current two places (log_ref_write and
builtin/reflog.c).
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
Changes in version 3:
* reword the commit message to make it more understandable.
* no changes in code
* wait for the follow up to address any changes in the code.
Changes in version 4:
* fix arguments of sprintf, (note to self: compile testing helps)
* break lines of commit message again to appease the taste of Jonathan ;)
* take the simplification for
result = log_ref_write_fd(...);
if (result) {
...
and omit the result variable in there to just become
if (log_ref_write_fd(...)) {
...
refs.c | 48 ++++++++++++++++++++++++++++++------------------
1 file changed, 30 insertions(+), 18 deletions(-)
diff --git a/refs.c b/refs.c
index 5ff457e..a6088e3 100644
--- a/refs.c
+++ b/refs.c
@@ -2990,15 +2990,37 @@ int log_ref_setup(const char *refname, char *logfile, int bufsize)
return 0;
}
+static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
+ const unsigned char *new_sha1,
+ const char *committer, const char *msg)
+{
+ int msglen, written;
+ unsigned maxlen, len;
+ char *logrec;
+
+ msglen = msg ? strlen(msg) : 0;
+ maxlen = strlen(committer) + msglen + 100;
+ logrec = xmalloc(maxlen);
+ len = sprintf(logrec, "%s %s %s\n",
+ sha1_to_hex(old_sha1),
+ sha1_to_hex(new_sha1),
+ committer);
+ if (msglen)
+ len += copy_msg(logrec + len - 1, msg) - 1;
+
+ written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
+ free(logrec);
+ if (written != len)
+ return -1;
+
+ return 0;
+}
+
static int log_ref_write(const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg)
{
- int logfd, result, written, oflags = O_APPEND | O_WRONLY;
- unsigned maxlen, len;
- int msglen;
+ int logfd, result, oflags = O_APPEND | O_WRONLY;
char log_file[PATH_MAX];
- char *logrec;
- const char *committer;
if (log_all_ref_updates < 0)
log_all_ref_updates = !is_bare_repository();
@@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
logfd = open(log_file, oflags);
if (logfd < 0)
return 0;
- msglen = msg ? strlen(msg) : 0;
- committer = git_committer_info(0);
- maxlen = strlen(committer) + msglen + 100;
- logrec = xmalloc(maxlen);
- len = sprintf(logrec, "%s %s %s\n",
- sha1_to_hex(old_sha1),
- sha1_to_hex(new_sha1),
- committer);
- if (msglen)
- len += copy_msg(logrec + len - 1, msg) - 1;
- written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
- free(logrec);
- if (written != len) {
+
+ if (log_ref_write_fd(logfd, old_sha1, new_sha1,
+ git_committer_info(0), msg)) {
int save_errno = errno;
close(logfd);
error("Unable to append to %s", log_file);
--
2.2.0.rc2.23.gca0107e
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v4] refs.c: add a function to append a reflog entry to a fd
2014-11-20 21:42 ` Junio C Hamano
2014-11-20 21:58 ` Stefan Beller
@ 2014-11-20 21:59 ` Stefan Beller
2014-11-20 22:11 ` Jonathan Nieder
1 sibling, 1 reply; 18+ messages in thread
From: Stefan Beller @ 2014-11-20 21:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, jrnieder, Ronnie Sahlberg
From: Ronnie Sahlberg <sahlberg@google.com>
Move code to create the string for a ref and write it to a file descriptor
from log_ref_write and add it into a new dedicated function
log_ref_write_fd.
For now the new function is only used from log_ref_write, but later
on we will call this function from reflog transactions too. That means
that we will end up with only a single place, where we write a reflog
entry to a file instead of the current two places (log_ref_write and
builtin/reflog.c).
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
Changes in version 3:
* reword the commit message to make it more understandable.
* no changes in code
* wait for the follow up to address any changes in the code.
Changes in version 4:
* fix arguments of sprintf
* break lines of commit message again to appease the taste of Jonathan ;)
* take the simplification for
result = log_ref_write_fd(...);
if (result) {
...
and omit the result variable in there to just become
if (log_ref_write_fd(...)) {
...
refs.c | 48 ++++++++++++++++++++++++++++++------------------
1 file changed, 30 insertions(+), 18 deletions(-)
diff --git a/refs.c b/refs.c
index 5ff457e..a6088e3 100644
--- a/refs.c
+++ b/refs.c
@@ -2990,15 +2990,37 @@ int log_ref_setup(const char *refname, char *logfile, int bufsize)
return 0;
}
+static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
+ const unsigned char *new_sha1,
+ const char *committer, const char *msg)
+{
+ int msglen, written;
+ unsigned maxlen, len;
+ char *logrec;
+
+ msglen = msg ? strlen(msg) : 0;
+ maxlen = strlen(committer) + msglen + 100;
+ logrec = xmalloc(maxlen);
+ len = sprintf(logrec, "%s %s %s\n",
+ sha1_to_hex(old_sha1),
+ sha1_to_hex(new_sha1),
+ committer);
+ if (msglen)
+ len += copy_msg(logrec + len - 1, msg) - 1;
+
+ written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
+ free(logrec);
+ if (written != len)
+ return -1;
+
+ return 0;
+}
+
static int log_ref_write(const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg)
{
- int logfd, result, written, oflags = O_APPEND | O_WRONLY;
- unsigned maxlen, len;
- int msglen;
+ int logfd, result, oflags = O_APPEND | O_WRONLY;
char log_file[PATH_MAX];
- char *logrec;
- const char *committer;
if (log_all_ref_updates < 0)
log_all_ref_updates = !is_bare_repository();
@@ -3010,19 +3032,9 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
logfd = open(log_file, oflags);
if (logfd < 0)
return 0;
- msglen = msg ? strlen(msg) : 0;
- committer = git_committer_info(0);
- maxlen = strlen(committer) + msglen + 100;
- logrec = xmalloc(maxlen);
- len = sprintf(logrec, "%s %s %s\n",
- sha1_to_hex(old_sha1),
- sha1_to_hex(new_sha1),
- committer);
- if (msglen)
- len += copy_msg(logrec + len - 1, msg) - 1;
- written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
- free(logrec);
- if (written != len) {
+
+ if (log_ref_write_fd(logfd, old_sha1, new_sha1,
+ git_committer_info(0), msg)) {
int save_errno = errno;
close(logfd);
error("Unable to append to %s", log_file);
--
2.2.0.rc2.23.gca0107e
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v3] refs.c: add a function to append a reflog entry to a fd
2014-11-20 21:58 ` Stefan Beller
@ 2014-11-20 22:05 ` Jonathan Nieder
2014-11-20 22:11 ` Junio C Hamano
0 siblings, 1 reply; 18+ messages in thread
From: Jonathan Nieder @ 2014-11-20 22:05 UTC (permalink / raw)
To: Stefan Beller; +Cc: Junio C Hamano, git, Ronnie Sahlberg
Stefan Beller wrote:
> From 4bec12b878ca02a1e80af3c265e7e7ab52ba17ce Mon Sep 17 00:00:00 2001
The above line causes "git am" to be unable to parse the message
downloaded as an mbox, if I remember correctly.
[...]
> * break lines of commit message again to appease the taste of Jonathan ;)
I hope it's not just to appease me. If the rationale behind a comment I
make isn't clear, always feel free to ask.
In this case, it is about readability. It's perhaps irrational, but I
find text much more readable and the intent to be clearer when
paragraphs are wrapped to a consistent width instead of lines breaking
at arbitrary points.
Perhaps a nice way to make this a non-issue in the future would be an
option to "git am" to rewrap.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v4] refs.c: add a function to append a reflog entry to a fd
2014-11-20 21:59 ` [PATCH v4] " Stefan Beller
@ 2014-11-20 22:11 ` Jonathan Nieder
2014-11-20 22:29 ` Junio C Hamano
0 siblings, 1 reply; 18+ messages in thread
From: Jonathan Nieder @ 2014-11-20 22:11 UTC (permalink / raw)
To: Stefan Beller; +Cc: Junio C Hamano, git, Ronnie Sahlberg
Stefan Beller wrote:
> Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
[...]
> refs.c | 48 ++++++++++++++++++++++++++++++------------------
> 1 file changed, 30 insertions(+), 18 deletions(-)
The --patience diff makes review of this version very simple.
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Thanks.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3] refs.c: add a function to append a reflog entry to a fd
2014-11-20 22:05 ` Jonathan Nieder
@ 2014-11-20 22:11 ` Junio C Hamano
0 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2014-11-20 22:11 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Stefan Beller, git, Ronnie Sahlberg
Jonathan Nieder <jrnieder@gmail.com> writes:
> In this case, it is about readability. It's perhaps irrational, but I
> find text much more readable and the intent to be clearer when
> paragraphs are wrapped to a consistent width instead of lines breaking
> at arbitrary points.
Yeah I agree with that.
Also a blank line between paragraphs, but that goes without saying
once you accept that we do not do a single line per paragraph.
> Perhaps a nice way to make this a non-issue in the future would be an
> option to "git am" to rewrap.
No. There are cases where you do need to have a single oddball long
line that you cannot flow. In a project that employs "am", the
users of "am" are much more likely to become bottleneck than the
senders of patches, and it does not make sense to have them spend
cycles to decide if they want to let "am" do such wrapping.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v4] refs.c: add a function to append a reflog entry to a fd
2014-11-20 22:11 ` Jonathan Nieder
@ 2014-11-20 22:29 ` Junio C Hamano
0 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2014-11-20 22:29 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Stefan Beller, git, Ronnie Sahlberg
Jonathan Nieder <jrnieder@gmail.com> writes:
> Stefan Beller wrote:
>
>> Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
>> Signed-off-by: Stefan Beller <sbeller@google.com>
>> ---
> [...]
>> refs.c | 48 ++++++++++++++++++++++++++++++------------------
>> 1 file changed, 30 insertions(+), 18 deletions(-)
>
> The --patience diff makes review of this version very simple.
I guess it depends on what the reader is focusing on, but at least
to me I found the default or histogram much easier to see what is
going on. It could be due to my use of large -U<context> value,
too.
> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Thanks.
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2014-11-20 22:29 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-20 0:42 [PATCH] refs.c: add a function to append a reflog entry to a fd Stefan Beller
2014-11-20 1:22 ` Junio C Hamano
2014-11-20 1:34 ` Junio C Hamano
2014-11-20 2:05 ` Stefan Beller
2014-11-20 2:36 ` Jonathan Nieder
2014-11-20 16:57 ` Junio C Hamano
2014-11-20 18:37 ` [PATCH v3] " Stefan Beller
2014-11-20 21:20 ` Jonathan Nieder
2014-11-20 21:24 ` Stefan Beller
2014-11-20 21:31 ` Jonathan Nieder
2014-11-20 21:42 ` Junio C Hamano
2014-11-20 21:58 ` Stefan Beller
2014-11-20 22:05 ` Jonathan Nieder
2014-11-20 22:11 ` Junio C Hamano
2014-11-20 21:59 ` [PATCH v4] " Stefan Beller
2014-11-20 22:11 ` Jonathan Nieder
2014-11-20 22:29 ` Junio C Hamano
2014-11-20 1:42 ` [PATCH] " Jonathan Nieder
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).