[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: critique of gnulib - string allocation

From: Bruno Haible
Subject: Re: critique of gnulib - string allocation
Date: Sun, 08 Sep 2019 19:08:21 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-159-generic; KDE/5.18.0; x86_64; ; )

Jonas Termansen wrote:
> > Buffer allocation and string production
> > should not be decoupled as it leads to bugs. (Modern languages, such as
> > the one I develop at work, does simply not have these problems.) In C,
> > strdup should be used instead of strlen+malloc+strcpy/memcpy because
> > it's much less error prone. Generally asprintf should be used instead of
> > sprintf/snprintf because it does the buffer allocation for you and
> > significantly reduces the risk.
> > ...
> > The
> > correct resolution is to not even have this class of problems in the
> > first place by not decoupling buffer allocation from the string
> > creation.

This is something I can support. The problem is that asprintf is often
considered overkill, because it has to parse a format string first.
Application programmers don't care about this, by system programmers do.

What can we do about it? If gnulib offers some convenience functions

   char * concatenated_string2 (const char *string1, const char *string2);
   char * concatenated_string3 (const char *string1, const char *string2,
                                const char *string3);
   char * concatenated_string4 (const char *string1, const char *string2,
                                const char *string3, const char *string4);

it only solves half of the problem, because often a concatenation involves
a substring, and system programmers don't want to do an intermediate
memory allocation for the substring.

So, what we would need is are functions

   char * substring (const char *string, size_t length);
   char * concatenated_string2 (const char *string1, size_t length1,
                                const char *string2, size_t length2);
   char * concatenated_string3 (const char *string1, size_t length1,
                                const char *string2, size_t length2,
                                const char *string3, size_t length3);

where the length arguments are set to SIZE_MAX to designate the entire

How does that sound? Should we add something like that to gnulib?

Paul Eggert wrote:
> asprintf is often a good way to go, and Gnulib uses it. However, like sprintf 
> and snprintf, asprintf mishandles large buffers and so careful code cannot 
> use 
> it to both allocate and format large results - which means that careful code 
> must do the "risky" stuff anyway since asprintf is not up to the task.

What do you mean by "asprintf mishandles large buffers"? The fact that an error
occurs if the result is longer than INT_MAX characters? Really, we have data
larger than 2 GB in many places, but *strings* larger than 2 GB? You can't send
a mail of that size, nor open a file with a line that is that long in any text
editor except Emacs.

In GNU gettext, I make plenty of use of xasprintf. What are the risks?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]