Thread (8 messages) flat view 8 messages, 2 authors, 2016-06-15

Re: [PATCH] http: Add Accept-Language header if possible

From: Yi, EungJun <hidden>
Date: 2016-06-15 23:03:42

Possibly related (same subject, not in this thread)

I agree that a list of char* is enough for language_tags.

Thanks for your review and patch. I'll apply your patch and send v9.

On Wed, Jan 28, 2015 at 3:15 PM, Junio C Hamano [off-list ref] wrote:
On Tue, Jan 27, 2015 at 3:34 PM, Junio C Hamano [off-list ref] wrote:
quoted
Yi EungJun [off-list ref] writes:
quoted
+
+             sprintf(q_format, ";q=0.%%0%dd", decimal_places);
+
+             strbuf_addstr(buf, "Accept-Language: ");
+
+             for(i = 0; i < num_langs; i++) {
+                     if (i > 0)
+                             strbuf_addstr(buf, ", ");
+
+                     strbuf_addstr(buf, strbuf_detach(&language_tags[i], NULL));
This is not wrong per-se, but it looks somewhat convoluted to me.
...
Actually, this is wrong, isn't it?

strbuf_detach() removes the language_tags[i].buf from the strbuf,
and the caller now owns that piece of memory. Then strbuf_addstr()
appends a copy of that string to buf, and the piece of memory
that was originally held by language_tags[i].buf is now lost forever.

This is leaking.
quoted
quoted
+     /* free language tags */
+     for(i = 0; i < num_langs; i++) {
+             strbuf_release(&language_tags[i]);
+     }
... because this loop does not free memory for earlier parts of language_tags[].
quoted
I am wondering if using strbuf for each of the language_tags[] is
even necessary.  How about doing it this way instead?
And I think my counter-proposal does not leak (as it does not us strbuf for
language_tags[] anymore).
quoted
 http.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/http.c b/http.c
index 6111c6a..db591b3 100644
--- a/http.c
+++ b/http.c
@@ -1027,7 +1027,7 @@ static void write_accept_language(struct strbuf *buf)
        const int MAX_DECIMAL_PLACES = 3;
        const int MAX_LANGUAGE_TAGS = 1000;
        const int MAX_ACCEPT_LANGUAGE_HEADER_SIZE = 4000;
-       struct strbuf *language_tags = NULL;
+       char **language_tags = NULL;
        int num_langs = 0;
        const char *s = get_preferred_languages();
        int i;
@@ -1053,9 +1053,7 @@ static void write_accept_language(struct strbuf *buf)
                if (tag.len) {
                        num_langs++;
                        REALLOC_ARRAY(language_tags, num_langs);
-                       strbuf_init(&language_tags[num_langs - 1], 0);
-                       strbuf_swap(&tag, &language_tags[num_langs - 1]);
-
+                       language_tags[num_langs - 1] = strbuf_detach(&tag, NULL);
                        if (num_langs >= MAX_LANGUAGE_TAGS - 1) /* -1 for '*' */
                                break;
                }
@@ -1070,13 +1068,12 @@ static void write_accept_language(struct strbuf *buf)

                /* add '*' */
                REALLOC_ARRAY(language_tags, num_langs + 1);
-               strbuf_init(&language_tags[num_langs], 0);
-               strbuf_addstr(&language_tags[num_langs++], "*");
+               language_tags[num_langs++] = "*"; /* it's OK; this won't be freed */

                /* compute decimal_places */
                for (max_q = 1, decimal_places = 0;
-                               max_q < num_langs && decimal_places <= MAX_DECIMAL_PLACES;
-                               decimal_places++, max_q *= 10)
+                    max_q < num_langs && decimal_places <= MAX_DECIMAL_PLACES;
+                    decimal_places++, max_q *= 10)
                        ;

                sprintf(q_format, ";q=0.%%0%dd", decimal_places);
@@ -1087,7 +1084,7 @@ static void write_accept_language(struct strbuf *buf)
                        if (i > 0)
                                strbuf_addstr(buf, ", ");

-                       strbuf_addstr(buf, strbuf_detach(&language_tags[i], NULL));
+                       strbuf_addstr(buf, language_tags[i]);

                        if (i > 0)
                                strbuf_addf(buf, q_format, max_q - i);
@@ -1101,10 +1098,9 @@ static void write_accept_language(struct strbuf *buf)
                }
        }

-       /* free language tags */
-       for(i = 0; i < num_langs; i++) {
-               strbuf_release(&language_tags[i]);
-       }
+       /* free language tags -- last one is a static '*' */
+       for(i = 0; i < num_langs - 1; i++)
+               free(language_tags[i]);
        free(language_tags);
 }
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help