FIX: use utf8_strnwidth for line_prefix in diff.c
cover FIX: use utf8_strnwidth for line_prefix in diff.c
This patch adresses diff.c:2721 and proposes the fix using a new function.
Md Isfarul Haque (2):
FIX: use utf8_strnwidth for line_prefix in diff.c FIX memory leak in one branch
diff.c | 19 +++++++++++++++++-- diff.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-)
base-commit: e02ecfcc534e2021aae29077a958dd11c3897e4c
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1653%2FInnocentZero%2Fdiff_needswork-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1653/InnocentZero/diff_needswork-v1
Pull-Request: https://github.com/git/git/pull/1653
Signature · 1 line
gitgitgadget
PATCH 1/2 FIX: use utf8_strnwidth for line_prefix in diff.c
From: Md Isfarul Haque <[email protected]>
This patch adresses diff.c:2721 and proposes the fix using a new function.
--- diff.c | 18 ++++++++++++++++-- diff.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-)
diff.c +16 -2
@@ -2300,6 +2300,20 @@ const char *diff_line_prefix(struct diff_options *opt)return msgbuf->buf; } +const struct strbuf *diff_line_prefix_buf (struct diff_options *opt) +{ +struct strbuf *msgbuf = (struct strbuf *)malloc (sizeof (*msgbuf)); +if (!opt->output_prefix){ + msgbuf->buf ="" ; + msgbuf->len =0 ; + msgbuf->alloc =1 ; + } +else { + msgbuf = opt->output_prefix (opt, opt->output_prefix_data); + } +return msgbuf; +} +static unsigned long sane_truncate_line (char *line,unsigned long len) {const char *cp;
@@ -2635,7 +2649,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)int width, name_width, graph_width, number_width =0 , bin_width =0 ;const char *reset, *add_c, *del_c;int extra_shown =0 ; -const char *line_prefix =diff_line_prefix (options); +const struct strbuf *line_prefix =diff_line_prefix_buf (options);struct strbuf out =STRBUF_INIT ;if (data->nr ==0 )
@@ -2718,7 +2732,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)* used to correctly count the display width instead of strlen(). */ if (options->stat_width ==-1 ) - width =term_columns () -strlen (line_prefix); + width =term_columns () -utf8_strnwidth (line_prefix->buf, line_prefix->len,1 );else width = options->stat_width ? options->stat_width :80 ; number_width = decimal_width(max_change) > number_width ?
diff.h +1 -0
@@ -460,6 +460,7 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix);const char *diff_line_prefix (struct diff_options *); +const struct strbuf *diff_line_prefix_buf (struct diff_options *);extern const char mime_boundary_leader[];
Signature · 1 line
gitgitgadget
PATCH 2/2 FIX memory leak in one branch
In reply to Md Isfarul Haque via GitGitGadgetFrom: Md Isfarul Haque <[email protected]>
--- diff.c | 1 + 1 file changed, 1 insertion(+)
diff.c +1 -0
@@ -2309,6 +2309,7 @@ const struct strbuf *diff_line_prefix_buf(struct diff_options *opt) msgbuf->alloc =1 ; }else { +free (msgbuf); msgbuf = opt->output_prefix (opt, opt->output_prefix_data); }return msgbuf;
Signature · 1 line
gitgitgadget
Quoted 1 line · Md Isfarul Haque via GitGitGadget
This patch adresses diff.c:2721 and proposes the fix using a new function.
Yay. My favorite long-time pet-peeve topic.
Quoted 4 lines
Md Isfarul Haque (2):
FIX: useutf8_strnwidthforline_prefixindiff.cFIX memory leak in one branch
Our convention does not use "FIX" and other prefix on the subject. Please check Documentation/SubmittingPatches.
Thanks.
Quoted 4 lines · Md Isfarul Haque via GitGitGadget
From: Md Isfarul Haque <[email protected]>
This patch adresses diff.c:2721 and proposes the fix using a new function.
Please give more details here about what is currently at diff.c:2721 and what the patch is fixing, as lines at diff.c:2721 could move to a different location if some changes are made to diff.c before your patches get merged or after they get merged.
Also if the patch is addressing an issue in a code comment I would expect the corresponding code comment to be removed by the patch.
About the subject, maybe "diff: use utf8_strnwidth() for line_prefix" is already better.
Quoted 11 lines
Signed-off-by Md Isfarul Haque <[email protected]>--- diff.c | 18 ++++++++++++++++-- diff.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-)diff.c +0
-0
diff.c const char *diff_line_prefix(struct diff_options *opt) · line 2303
Quoted 4 lines
diff.c +1
-0@@ -2300,6 +2300,20 @@ const char *diff_line_prefix(struct diff_options *opt)return msgbuf->buf; } +const struct strbuf *diff_line_prefix_buf (struct diff_options *opt)
This function seems to be used only in diff.c, so it could be static.
Quoted 3 lines · Md Isfarul Haque via GitGitGadget
From: Md Isfarul Haque <[email protected]>
This patch adresses diff.c:2721 and proposes the fix using a new function.
Once the issue has fully been addressed, it is expected that the NEEDSWORK comment there would be removed, making this proposed log message useless. Make it a habit to write a log message that is self-contained enough to help readers (including yourself in the future when you have forgotten the details of what you did in this commit).
diff.c const char *diff_line_prefix(struct diff_options *opt) · line 2304
Quoted 2 lines
diff.c +2
-0+const struct strbuf *diff_line_prefix_buf (struct diff_options *opt) +{
Given that there is only one caller of this function in the same file, I do not see a reason why this needs to be extern and exported in diff.h (actually I do not see a need for this helper at all).
When dealing with a string buffer, it is much more common in this codebase for the caller to prepare a strbuf (often on its stack) and pass a pointer to it to helper functions. I.e.
static void prepare_diff_line_prefix_buf(struct strbuf *buf,
struct diff_options *opt)
{
... stuff whatever you need into the string buffer ...
strbuf_add(buf, ...);
}
/* in show_stats() */
struct strbuf line_prefix = STRBUF_INIT;
...
prepare_diff_line_prefix_buf(&line_prefix, options);
... use line_prefix and ...
... release the resource before returning ...
strbuf_release(&line_prefix);is more common and less prone to resource leak over time.
Quoted 10 lines
diff.c +1
-1@@ -2635,7 +2649,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)int width, name_width, graph_width, number_width =0 , bin_width =0 ;const char *reset, *add_c, *del_c;int extra_shown =0 ; -const char *line_prefix =diff_line_prefix (options); +const struct strbuf *line_prefix =diff_line_prefix_buf (options);struct strbuf out =STRBUF_INIT ;if (data->nr ==0 )
diff.c static void show_stats(struct diffstat_t *data, struct diff_options *options) · line 2735
Quoted 5 lines
diff.c +1
-1@@ -2718,7 +2732,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)* used to correctly count the display width instead of strlen(). */ if (options->stat_width ==-1 ) - width =term_columns () -strlen (line_prefix); + width =term_columns () -utf8_strnwidth (line_prefix->buf, line_prefix->len,1 );
I do not see the need for any of the diff_line_prefix_buf() related changes, only to do this change. You have a const char *line_prefix at this point, and utf8_strnwidth() wants to know its length, so what you need is to massage the parameter to match what it wants. Perhaps even something simple and dumb like
utf8_strnwidth(line_prefix, strlen(line_prefix), 1);
might be sufficient to replace strlen(line_prefix) in the original?
This patch hopefully will change the behaviour of the command. A patch needs to also protect the change from future breakages by adding a test or two to demonstrate the desired behaviour. Such a test should pass with the code change in the patch, and should fail when the code change in the patch gets reverted.
Thanks.
Re: [PATCH 2/2] FIX memory leak in one branch
In reply to Md Isfarul Haque via GitGitGadgetQuoted 6 lines · Md Isfarul Haque via GitGitGadget
From: Md Isfarul Haque <[email protected]>
Signed-off-by Md Isfarul Haque <[email protected]>--- diff.c | 1 + 1 file changed, 1 insertion(+)
We do not need to see that you are just as human as other developers and are prone to make mistakes that you need to fix it in a follow-up. In other words, please do not introduce a bug in [1/2] only to be fixed in [2/2]. By squashing these two patches into one, you can pretend as if you are a perfect developer and never leaked memory ;-).
diff.c const struct strbuf *diff_line_prefix_buf(struct diff_options *opt) · line 2315
Quoted 12 lines
diff.c +1
-0@@ -2309,6 +2309,7 @@ const struct strbuf *diff_line_prefix_buf(struct diff_options *opt) msgbuf->alloc =1 ; }else { +free (msgbuf); msgbuf = opt->output_prefix (opt, opt->output_prefix_data); }return msgbuf;
But as I said, I do not see a need for this helper function in the first place, so...
Quoted 7 lines · Christian Couder
Quoted 4 lines · Md Isfarul Haque via GitGitGadget
From: Md Isfarul Haque <[email protected]>
This patch adresses diff.c:2721 and proposes the fix using a new function.
Quoted 7 lines
Please give more details here about what is currently at diff.c:2721 and what the patch is fixing, as lines at diff.c:2721 could move to a different location if some changes are made to
diff.cbefore your patches get merged or after they get merged.Also if the patch is addressing an issue in a code comment I would expect the corresponding code comment to be removed by the patch.
I understand and apologize for the mess-up. I will keep it in mind next time.
Quoted 17 lines
About the subject, maybe "diff: use
utf8_strnwidth()forline_prefix" is already better.Quoted 14 lines
Signed-off-by Md Isfarul Haque <[email protected]>--- diff.c | 18 ++++++++++++++++-- diff.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-)diff.c +0
-0@@ -2300,6 +2300,20 @@ const char *diff_line_prefix(struct diff_options *opt)return msgbuf->buf; }
Quoted 3 lines
diff.c const char *diff_line_prefix(struct diff_options *opt) · line 2303
Quoted 1 line
diff.c +1
-0+const struct strbuf *diff_line_prefix_buf (struct diff_options *opt)This function seems to be used only in
diff.c, so it could be static.
As Junio pointed out, I will probably use the existing function with slight modifications and use it. Besides, having unnecessary allocations and frees will probably only add overhead.
Signature · 2 lines
Thanks and regards Md. Isfarul Haque
Quoted 4 lines · Junio C Hamano
Quoted 2 lines · Md Isfarul Haque via GitGitGadget
From: Md Isfarul Haque <[email protected]>
Quoted 9 lines
Quoted 1 line
This patch adresses diff.c:2721 and proposes the fix using a new function.
Once the issue has fully been addressed, it is expected that the NEEDSWORK comment there would be removed, making this proposed log message useless. Make it a habit to write a log message that is self-contained enough to help readers (including yourself in the future when you have forgotten the details of what you did in this commit).
I understand. Sorry for the mess-up. I will keep it in mind the next time.
Quoted 26 lines
diff.c const char *diff_line_prefix(struct diff_options *opt) · line 2304
Quoted 2 lines
diff.c +2
-0+const struct strbuf *diff_line_prefix_buf (struct diff_options *opt) +{Given that there is only one caller of this function in the same file, I do not see a reason why this needs to be extern and exported in
diff.h(actually I do not see a need for this helper at all).When dealing with a string buffer, it is much more common in this codebase for the caller to prepare a strbuf (often on its stack) and pass a pointer to it to helper functions. I.e.
static void prepare_diff_line_prefix_buf(struct strbuf *buf, struct diff_options *opt) { ... stuff whatever you need into the string buffer ... strbuf_add(buf, ...); } /* in show_stats() */ struct strbuf line_prefix = STRBUF_INIT; ... prepare_diff_line_prefix_buf(&line_prefix, options); ... use line_prefix and ... ... release the resource before returning ... strbuf_release(&line_prefix);
Quoted 2 lines
is more common and less prone to resource leak over time.
Ah, this is indeed very neat. Didn't strike me. I'm not extremely familiar with the codebase and was unaware of this practice. I will follow this pattern in the future.
Quoted 22 lines
Quoted 10 lines
diff.c +1
-1@@ -2635,7 +2649,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)int width, name_width, graph_width, number_width =0 , bin_width =0 ;const char *reset, *add_c, *del_c;int extra_shown =0 ; -const char *line_prefix =diff_line_prefix (options); +const struct strbuf *line_prefix =diff_line_prefix_buf (options);struct strbuf out =STRBUF_INIT ;if (data->nr ==0 )diff.c static void show_stats(struct diffstat_t *data, struct diff_options *options) · line 2735
Quoted 5 lines
diff.c +1
-1@@ -2718,7 +2732,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)* used to correctly count the display width instead of strlen(). */ if (options->stat_width ==-1 ) - width =term_columns () -strlen (line_prefix); + width =term_columns () -utf8_strnwidth (line_prefix->buf, line_prefix->len,1 );I do not see the need for any of the
diff_line_prefix_buf()related changes, only to do this change. You have a const char*line_prefixat this point, andutf8_strnwidth()wants to know its length, so what you need is to massage the parameter to match what it wants. Perhaps even something simple and dumb like
Quoted 3 lines
utf8_strnwidth(line_prefix, strlen(line_prefix), 1);might be sufficient to replace
strlen(line_prefix)in the original?
It was more of a force of habit on my end, since I usually do not use functions that do not have a limit on the length they are reading. However, considering that the string is generated by another function and is most likely safe as it was used earlier, I will implement this suggestion.
Quoted 7 lines
This patch hopefully will change the behaviour of the command. A patch needs to also protect the change from future breakages by adding a test or two to demonstrate the desired behaviour. Such a test should pass with the code change in the patch, and should fail when the code change in the patch gets reverted.
Alright. Where should I add the test? A new/existing test in t/t4013 or t4124-log-graph-octopus.sh?
Signature · 2 lines
Thanks and regards, Md Isfarul Haque