Commit Graph

14 Commits

Author SHA1 Message Date
Willy Tarreau
b686afd568 MINOR: chunks: implement a simple dynamic allocator for trash buffers
The trash buffers are becoming increasingly complex to deal with due to
the code's modularity allowing some functions to be chained and causing
the same chunk buffers to be used multiple times along the chain, possibly
corrupting each other. In fact the trash were designed from scratch for
explicitly not surviving a function call but string manipulation makes
this impossible most of the time while not fullfilling the need for
reliable temporary chunks.

Here we introduce the ability to allocate a temporary trash chunk which
is reserved, so that it will not conflict with the trash chunks other
functions use, and will even support reentrant calls (eg: build_logline).

For this, we create a new pool which is exactly the size of a usual chunk
buffer plus the size of the chunk struct so that these chunks when allocated
are exactly the same size as the ones returned by get_trash_buffer(). These
chunks may fail so the caller must check them, and the caller is also
responsible for freeing them.

The code focuses on minimal changes and ease of reliable backporting
because it will be needed in stable versions in order to support next
patch.
2017-02-08 11:16:29 +01:00
Baptiste Assmann
7819c125c2 MINOR: chunk: new strncat function
Purpose of this function is to append data to the end of a chunk when
we know only the pointer to the beginning of the string and the string
length.
2016-09-12 19:51:59 +02:00
David Carlier
8ab1043c6b CLEANUP: chunk: adding NULL check to chunk_dup allocation.
Avoiding harmful memcpy call if the allocation failed.
Resetting the size which avoids further harmful freeing
invalid pointer. Closer to the comment behavior description.
2016-03-24 10:18:44 +01:00
Willy Tarreau
320ec2a745 BUG/MEDIUM: chunks: always reject negative-length chunks
The recent addition of "show env" on the CLI has revealed an interesting
design bug. Chunks are supposed to support a negative length to indicate
that they carry no data. chunk_printf() sets this size to -1 if the string
is too large for the buffer. At a few places in the http engine we may end
up with trash.len = -1. But bi_putchk(), chunk_appendf() and a few other
chunks consumers don't consider this case as possible and will use such a
chunk, possibly restoring an invalid string or trying to copy -1 bytes.

This fix takes care of clarifying the situation in a backportable way
where such sizes are used, so that a negative length indicating an error
remains present until the chunk is reinitialized or overwritten. But a
cleaner design adjustment needs to be done so that there's a clear contract
on how to use these chunks. At first glance it doesn't seem *that* useful
to support negative sizes, so probably this is what should change.

This fix must be backported to 1.6 and 1.5.
2016-02-25 16:24:14 +01:00
Willy Tarreau
70af633ebe MINOR: chunk: make chunk_initstr() take a const string
chunk_initstr() prepares a read-only chunk from a string of
fixed length. Thus it must be prepared to accept a read-only
string on the input, otherwise the caller has to force-cast
some const char* and that's not a good idea.
2016-01-06 20:58:55 +01:00
Willy Tarreau
601360b41d MINOR: chunks: add chunk_strcat() and chunk_newstr()
These two new functions will make it easier to manipulate small strings
from within functions, because at many places, multiple short strings
are needed which do not deserve a malloc() nor a free(), and alloca()
is often discouraged. Since we already have trash chunks, it's convenient
to be able to allocate substrings from a chunk and use them later since
our functions already perform all the length checks. chunk_newstr() adds
a trailing zero at the end of a chunk and returns the pointer to the next
character, which can be used as an independant string. chunk_strcat()
does what it says.
2016-01-06 13:53:37 +01:00
Willy Tarreau
0b6044fa24 MINOR: chunks: ensure that chunk_strcpy() adds a trailing zero
Since thus function bears the name of a well-known string function, it
must at least promise compatible semantics. Here it means always adding
the trailing zero so that anyone willing to use chunk->str as a regular
string can do it. Of course the zero is not counted in the chunk's length.
2016-01-06 13:53:37 +01:00
Willy Tarreau
f9476a5a30 BUG/MINOR: chunk: make chunk_dup() always check and set dst->size
chunk_dup() was affected by two bugs at once related to dst->size :
  - first, it didn't check dst->size to know if it could free(dst->str),
    so using it on a statically allocated chunk would cause a free(constant)
    and crash the process ;

  - second, it didn't properly set dst->size, possibly causing smaller
    strings not to be properly reported in a chunk that was previously
    used for something else.

Fortunately, neither of these situations ever happened since the function
is rarely used.

In the process of doing this, we even allocate one more byte for a
trailing zero if the input chunk was not full, so that the copied
string can safely be reused by standard string functions.

The bug was introduced in 1.3.4 nine years ago with this commit :

  0f77253 ("[MINOR] store HTTP error messages into a chunk array")

It's better to backport this fix in case a future fix relies on it.
2016-01-04 20:47:27 +01:00
David Carlier
60deeba090 MINOR: chunk: New function free_trash_buffers()
This new function is meant to be called in the general deinit phase,
to free those two internal chunks.
2015-09-28 14:00:00 +02:00
Willy Tarreau
47ca54505c MINOR: chunks: centralize the trash chunk allocation
At the moment, we need trash chunks almost everywhere and the only
correctly implemented one is in the sample code. Let's move this to
the chunks so that all other places can use this allocator.

Additionally, the get_trash_chunk() function now really returns two
different chunks. Previously it used to always overwrite the same
chunk and point it to a different buffer, which was a bit tricky
because it's not obvious that two consecutive results do alias each
other.
2012-12-23 21:46:07 +01:00
Willy Tarreau
7780473c3b CLEANUP: replace chunk_printf() with chunk_appendf()
This function's naming was misleading as it is used to append data
at the end of a string, causing some surprizes when used for the
first time!

Add a chunk_printf() function which does what its name suggests.
2012-10-29 16:14:26 +01:00
Willy Tarreau
c26ac9deea MINOR: chunk: add a function to reset a chunk
This is a first step in avoiding to constantly reinitialize chunks.
It replaces the old chunk_reset() which was not properly named as it
used to drop everything and was only used by chunk_destroy(). It has
been renamed chunk_drop().
2012-10-29 13:33:42 +01:00
Willy Tarreau
ad8f8e8ffb MINOR: chunk: provide string compare functions
It's sometimes needed to be able to compare a zero-terminated string with a
chunk, so we now have two functions to do that, one strcmp() equivalent and
one strcasecmp() equivalent.
2012-10-19 15:18:06 +02:00
Willy Tarreau
c7e4238df0 REORG: buffers: split buffers into chunk,buffer,channel
Many parts of the channel definition still make use of the "buffer" word.
2012-09-03 20:47:32 +02:00