* [PATCH 2/3] diff.c: remove unnecessary typecast
[not found] <1456145545-5374-1-git-send-email-pclouds@gmail.com>
@ 2016-02-22 12:52 ` Nguyễn Thái Ngọc Duy
2016-02-22 12:52 ` [PATCH 3/3] Correct conditions to free textconv result data Nguyễn Thái Ngọc Duy
1 sibling, 0 replies; 10+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2016-02-22 12:52 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
diff.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/diff.c b/diff.c
index 8b3a3db..5bdc3c0 100644
--- a/diff.c
+++ b/diff.c
@@ -717,8 +717,8 @@ static void emit_rewrite_diff(const char *name_a,
ecbdata.opt = o;
if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
mmfile_t mf1, mf2;
- mf1.ptr = (char *)data_one;
- mf2.ptr = (char *)data_two;
+ mf1.ptr = data_one;
+ mf2.ptr = data_two;
mf1.size = size_one;
mf2.size = size_two;
check_blank_at_eof(&mf1, &mf2, &ecbdata);
--
2.7.1.532.gd9e3aaa
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] Correct conditions to free textconv result data
[not found] <1456145545-5374-1-git-send-email-pclouds@gmail.com>
2016-02-22 12:52 ` [PATCH 2/3] diff.c: remove unnecessary typecast Nguyễn Thái Ngọc Duy
@ 2016-02-22 12:52 ` Nguyễn Thái Ngọc Duy
2016-02-22 13:00 ` Duy Nguyen
2016-02-22 18:06 ` Jeff King
1 sibling, 2 replies; 10+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2016-02-22 12:52 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
fill_textconv() have four code paths to return a new buffer. Two of
them, run_textconv() and notes_cache_get(), return a newly allocated
buffer. The other two return either a constant string or an existing
buffer (mmfile_t). We can only free the result buffer if it's allocated
by fill_textconv(). Correct all call sites.
Changes in combine-diff.c are not clear from diff output. We need to
force not running fill_textconv() unless the function returns a new
buffer so that it falls to the "else" case and allocates a new buffer
with no conversion.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Frankly I don't like the way fill_textconv() returns buffer at all.
But I don't know much about textconv, or want to spend more time on
it. This patch can be dropped if people come up with a better one.
builtin/blame.c | 2 +-
combine-diff.c | 4 ++--
diff.c | 8 ++++----
diffcore-pickaxe.c | 5 +++--
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/builtin/blame.c b/builtin/blame.c
index cb6f2fb..b5477ad 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -166,7 +166,7 @@ int textconv_object(const char *path,
df = alloc_filespec(path);
fill_filespec(df, sha1, sha1_valid, mode);
textconv = get_textconv(df);
- if (!textconv) {
+ if (!textconv || !textconv->textconv) {
free_filespec(df);
return 0;
}
diff --git a/combine-diff.c b/combine-diff.c
index 5571304..c57cefd 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -299,7 +299,7 @@ static char *grab_blob(const struct object_id *oid, unsigned int mode,
/* deleted blob */
*size = 0;
return xcalloc(1, 1);
- } else if (textconv) {
+ } else if (textconv && textconv->textconv) {
struct diff_filespec *df = alloc_filespec(path);
fill_filespec(df, oid->hash, 1, mode);
*size = fill_textconv(textconv, df, &blob);
@@ -1022,7 +1022,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
else
result = grab_blob(&oid, elem->mode,
&result_size, NULL, NULL);
- } else if (textconv) {
+ } else if (textconv && textconv->textconv) {
struct diff_filespec *df = alloc_filespec(elem->path);
fill_filespec(df, null_sha1, 0, st.st_mode);
result_size = fill_textconv(textconv, df, &result);
diff --git a/diff.c b/diff.c
index 5bdc3c0..173ec5b 100644
--- a/diff.c
+++ b/diff.c
@@ -744,9 +744,9 @@ static void emit_rewrite_diff(const char *name_a,
emit_rewrite_lines(&ecbdata, '-', data_one, size_one);
if (lc_b)
emit_rewrite_lines(&ecbdata, '+', data_two, size_two);
- if (textconv_one)
+ if (textconv_one && textconv_one->textconv)
free((char *)data_one);
- if (textconv_two)
+ if (textconv_two && textconv_two->textconv)
free((char *)data_two);
}
@@ -2454,9 +2454,9 @@ static void builtin_diff(const char *name_a,
die("unable to generate diff for %s", one->path);
if (o->word_diff)
free_diff_words_data(&ecbdata);
- if (textconv_one)
+ if (textconv_one && textconv_one->textconv)
free(mf1.ptr);
- if (textconv_two)
+ if (textconv_two && textconv_two->textconv)
free(mf2.ptr);
xdiff_clear_find_func(&xecfg);
}
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index 7715c13..f89e106 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -7,6 +7,7 @@
#include "diffcore.h"
#include "xdiff-interface.h"
#include "kwset.h"
+#include "userdiff.h"
typedef int (*pickaxe_fn)(mmfile_t *one, mmfile_t *two,
struct diff_options *o,
@@ -150,9 +151,9 @@ static int pickaxe_match(struct diff_filepair *p, struct diff_options *o,
DIFF_FILE_VALID(p->two) ? &mf2 : NULL,
o, regexp, kws);
- if (textconv_one)
+ if (textconv_one && textconv_one->textconv)
free(mf1.ptr);
- if (textconv_two)
+ if (textconv_two && textconv_two->textconv)
free(mf2.ptr);
diff_free_filespec_data(p->one);
diff_free_filespec_data(p->two);
--
2.7.1.532.gd9e3aaa
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] Correct conditions to free textconv result data
2016-02-22 12:52 ` [PATCH 3/3] Correct conditions to free textconv result data Nguyễn Thái Ngọc Duy
@ 2016-02-22 13:00 ` Duy Nguyen
2016-02-22 18:06 ` Jeff King
1 sibling, 0 replies; 10+ messages in thread
From: Duy Nguyen @ 2016-02-22 13:00 UTC (permalink / raw)
To: Git Mailing List; +Cc: Nguyễn Thái Ngọc Duy
On Mon, Feb 22, 2016 at 7:52 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
> fill_textconv() have four code paths to return a new buffer.
I forgot to add. Thanks to -Wwrite-strings pointing to '*outbuf = ""'
line in this function. I wouldn't notice otherwise.
--
Duy
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] Correct conditions to free textconv result data
2016-02-22 12:52 ` [PATCH 3/3] Correct conditions to free textconv result data Nguyễn Thái Ngọc Duy
2016-02-22 13:00 ` Duy Nguyen
@ 2016-02-22 18:06 ` Jeff King
2016-02-22 18:12 ` Jeff King
2016-02-22 18:28 ` [PATCH] diff: clarify textconv interface Jeff King
1 sibling, 2 replies; 10+ messages in thread
From: Jeff King @ 2016-02-22 18:06 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
On Mon, Feb 22, 2016 at 07:52:25PM +0700, Nguyễn Thái Ngọc Duy wrote:
> fill_textconv() have four code paths to return a new buffer. Two of
> them, run_textconv() and notes_cache_get(), return a newly allocated
> buffer. The other two return either a constant string or an existing
> buffer (mmfile_t). We can only free the result buffer if it's allocated
> by fill_textconv(). Correct all call sites.
Right, and those two cases (allocated or not) should follow based on
whether you passed in a textconv-enabled driver.
> diff --git a/builtin/blame.c b/builtin/blame.c
> index cb6f2fb..b5477ad 100644
> --- a/builtin/blame.c
> +++ b/builtin/blame.c
> @@ -166,7 +166,7 @@ int textconv_object(const char *path,
> df = alloc_filespec(path);
> fill_filespec(df, sha1, sha1_valid, mode);
> textconv = get_textconv(df);
> - if (!textconv) {
> + if (!textconv || !textconv->textconv) {
> free_filespec(df);
> return 0;
> }
This change (and the other similar ones) doesn't make any sense to me.
The point of get_textconv() is to return the userdiff driver if and only
if it has textconv enabled.
I have a feeling you were confused by the fact that fill_textconv()
does:
if (!driver || !driver->textconv)
to decide whether to allocate the textconv buffer. The latter half of
that is really just defensive programming, and I think this would
probably be better as:
if (driver)
....
assert(driver->textconv);
to make it more clear that we assume the parameter came from
get_textconv().
And if there's a case that triggers that assert(), then I think the bug
is in the caller, which should be fixed.
Is there a case I'm missing here where we actually leak memory or try to
free non-allocated memory? I didn't see it.
-Peff
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] Correct conditions to free textconv result data
2016-02-22 18:06 ` Jeff King
@ 2016-02-22 18:12 ` Jeff King
2016-02-22 23:03 ` Duy Nguyen
2016-02-22 18:28 ` [PATCH] diff: clarify textconv interface Jeff King
1 sibling, 1 reply; 10+ messages in thread
From: Jeff King @ 2016-02-22 18:12 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
On Mon, Feb 22, 2016 at 01:06:46PM -0500, Jeff King wrote:
> Is there a case I'm missing here where we actually leak memory or try to
> free non-allocated memory? I didn't see it.
By the way, I saw only patches 2/3 and 3/3 on the list. So maybe there
is something interesting going on in 1/3, or in a cover letter that
didn't make it. :)
-Peff
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] diff: clarify textconv interface
2016-02-22 18:06 ` Jeff King
2016-02-22 18:12 ` Jeff King
@ 2016-02-22 18:28 ` Jeff King
2016-02-22 23:01 ` Duy Nguyen
1 sibling, 1 reply; 10+ messages in thread
From: Jeff King @ 2016-02-22 18:28 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
On Mon, Feb 22, 2016 at 01:06:45PM -0500, Jeff King wrote:
> I have a feeling you were confused by the fact that fill_textconv()
> does:
Looking over it, I agree this is a pretty confusing interface that grew
out of control over time. But refactoring it is kind of tricky, because
we really do want to avoid extra allocations, or cross-module
assumptions (e.g., userdiff doesn't know about diff_filespec, but rather
the other way around, and we probably do not want to muck with the
internals of a diff_filespec when doing a textconv).
So I think the patch below is an improvement, but if somebody really
wants to dig into refactoring it, be my guest.
-- >8 --
Subject: [PATCH] diff: clarify textconv interface
The memory allocation scheme for the textconv interface is a
bit tricky, and not well documented. It was originally
designed as an internal part of diff.c (matching
fill_mmfile), but gradually was made public.
Refactoring it is difficult, but we can at least improve the
situation by documenting the intended flow and enforcing it
with an in-code assertion.
Signed-off-by: Jeff King <peff@peff.net>
---
diff.c | 5 ++++-
diff.h | 16 ++++++++++++++++
userdiff.h | 4 ++++
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/diff.c b/diff.c
index 2136b69..a088e26 100644
--- a/diff.c
+++ b/diff.c
@@ -5085,7 +5085,7 @@ size_t fill_textconv(struct userdiff_driver *driver,
{
size_t size;
- if (!driver || !driver->textconv) {
+ if (!driver) {
if (!DIFF_FILE_VALID(df)) {
*outbuf = "";
return 0;
@@ -5096,6 +5096,9 @@ size_t fill_textconv(struct userdiff_driver *driver,
return df->size;
}
+ if (!driver->textconv)
+ die("BUG: fill_textconv called with non-textconv driver");
+
if (driver->textconv_cache && df->sha1_valid) {
*outbuf = notes_cache_get(driver->textconv_cache, df->sha1,
&size);
diff --git a/diff.h b/diff.h
index 70b2d70..4505b4d 100644
--- a/diff.h
+++ b/diff.h
@@ -349,10 +349,26 @@ extern void diff_no_index(struct rev_info *, int, const char **);
extern int index_differs_from(const char *def, int diff_flags);
+/*
+ * Fill the contents of the filespec "df", respecting any textconv defined by
+ * its userdiff driver. The "driver" parameter must come from a
+ * previous call to get_textconv(), and therefore should either be NULL or have
+ * textconv enabled.
+ *
+ * Note that the memory ownership of the resulting buffer depends on whether
+ * the driver field is NULL. If it is, then the memory belongs to the filespec
+ * struct. If it is non-NULL, then "outbuf" points to a newly allocated buffer
+ * that should be freed by the caller.
+ */
extern size_t fill_textconv(struct userdiff_driver *driver,
struct diff_filespec *df,
char **outbuf);
+/*
+ * Look up the userdiff driver for the given filespec, and return it if
+ * and only if it has textconv enabled (otherwise return NULL). The result
+ * can be passed to fill_textconv().
+ */
extern struct userdiff_driver *get_textconv(struct diff_filespec *one);
extern int parse_rename_score(const char **cp_p);
diff --git a/userdiff.h b/userdiff.h
index 4a7e78f..2ef0ce5 100644
--- a/userdiff.h
+++ b/userdiff.h
@@ -23,6 +23,10 @@ int userdiff_config(const char *k, const char *v);
struct userdiff_driver *userdiff_find_by_name(const char *name);
struct userdiff_driver *userdiff_find_by_path(const char *path);
+/*
+ * Initialize any textconv-related fields in the driver and return it, or NULL
+ * if it does not have textconv enabled at all.
+ */
struct userdiff_driver *userdiff_get_textconv(struct userdiff_driver *driver);
#endif /* USERDIFF */
--
2.7.1.652.g2fdcad6
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] diff: clarify textconv interface
2016-02-22 18:28 ` [PATCH] diff: clarify textconv interface Jeff King
@ 2016-02-22 23:01 ` Duy Nguyen
0 siblings, 0 replies; 10+ messages in thread
From: Duy Nguyen @ 2016-02-22 23:01 UTC (permalink / raw)
To: Jeff King; +Cc: Git Mailing List
On Tue, Feb 23, 2016 at 1:28 AM, Jeff King <peff@peff.net> wrote:
> On Mon, Feb 22, 2016 at 01:06:45PM -0500, Jeff King wrote:
>
>> I have a feeling you were confused by the fact that fill_textconv()
>> does:
>
> Looking over it, I agree this is a pretty confusing interface that grew
> out of control over time. But refactoring it is kind of tricky, because
> we really do want to avoid extra allocations, or cross-module
> assumptions (e.g., userdiff doesn't know about diff_filespec, but rather
> the other way around, and we probably do not want to muck with the
> internals of a diff_filespec when doing a textconv).
>
> So I think the patch below is an improvement, but if somebody really
> wants to dig into refactoring it, be my guest.
I almost went this way but I wasn't sure if driver->textconv can be
NULL on purpose. Definitely an improvement.
--
Duy
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] Correct conditions to free textconv result data
2016-02-22 18:12 ` Jeff King
@ 2016-02-22 23:03 ` Duy Nguyen
2016-02-22 23:08 ` Junio C Hamano
0 siblings, 1 reply; 10+ messages in thread
From: Duy Nguyen @ 2016-02-22 23:03 UTC (permalink / raw)
To: Jeff King; +Cc: Git Mailing List
On Tue, Feb 23, 2016 at 1:12 AM, Jeff King <peff@peff.net> wrote:
> On Mon, Feb 22, 2016 at 01:06:46PM -0500, Jeff King wrote:
>
>> Is there a case I'm missing here where we actually leak memory or try to
>> free non-allocated memory? I didn't see it.
>
> By the way, I saw only patches 2/3 and 3/3 on the list. So maybe there
> is something interesting going on in 1/3, or in a cover letter that
> didn't make it. :)
The only thing common in this series is it's the result of
-Wwrite-strings. 1/3 changes some "char *" to "const char *", you
don't miss anything.
--
Duy
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] Correct conditions to free textconv result data
2016-02-22 23:03 ` Duy Nguyen
@ 2016-02-22 23:08 ` Junio C Hamano
2016-02-22 23:25 ` Jeff King
0 siblings, 1 reply; 10+ messages in thread
From: Junio C Hamano @ 2016-02-22 23:08 UTC (permalink / raw)
To: Duy Nguyen; +Cc: Jeff King, Git Mailing List
Duy Nguyen <pclouds@gmail.com> writes:
> On Tue, Feb 23, 2016 at 1:12 AM, Jeff King <peff@peff.net> wrote:
>> On Mon, Feb 22, 2016 at 01:06:46PM -0500, Jeff King wrote:
>>
>>> Is there a case I'm missing here where we actually leak memory or try to
>>> free non-allocated memory? I didn't see it.
>>
>> By the way, I saw only patches 2/3 and 3/3 on the list. So maybe there
>> is something interesting going on in 1/3, or in a cover letter that
>> didn't make it. :)
>
> The only thing common in this series is it's the result of
> -Wwrite-strings. 1/3 changes some "char *" to "const char *", you
> don't miss anything.
While reading Peff's clarification patch, I did find the assignment
of "" to the *out pointer disturbing. That part of your patch (I
presume that is what you mean by the above) may want to be revived.
Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] Correct conditions to free textconv result data
2016-02-22 23:08 ` Junio C Hamano
@ 2016-02-22 23:25 ` Jeff King
0 siblings, 0 replies; 10+ messages in thread
From: Jeff King @ 2016-02-22 23:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List
On Mon, Feb 22, 2016 at 03:08:01PM -0800, Junio C Hamano wrote:
> > The only thing common in this series is it's the result of
> > -Wwrite-strings. 1/3 changes some "char *" to "const char *", you
> > don't miss anything.
>
> While reading Peff's clarification patch, I did find the assignment
> of "" to the *out pointer disturbing. That part of your patch (I
> presume that is what you mean by the above) may want to be revived.
That part was inherited from diff_populate_filespec, though it casts
explicitly to "char *" since d2543b8 (Clean up diff.c, 2006-06-24).
I guess we could do the same here (not that it makes things any safer,
but at least tells everyone "yes, I _know_ this is weird".
-Peff
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2016-02-22 23:25 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1456145545-5374-1-git-send-email-pclouds@gmail.com>
2016-02-22 12:52 ` [PATCH 2/3] diff.c: remove unnecessary typecast Nguyễn Thái Ngọc Duy
2016-02-22 12:52 ` [PATCH 3/3] Correct conditions to free textconv result data Nguyễn Thái Ngọc Duy
2016-02-22 13:00 ` Duy Nguyen
2016-02-22 18:06 ` Jeff King
2016-02-22 18:12 ` Jeff King
2016-02-22 23:03 ` Duy Nguyen
2016-02-22 23:08 ` Junio C Hamano
2016-02-22 23:25 ` Jeff King
2016-02-22 18:28 ` [PATCH] diff: clarify textconv interface Jeff King
2016-02-22 23:01 ` Duy Nguyen
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).