mirror of
https://github.com/zeromq/libzmq.git
synced 2025-03-10 16:06:09 +00:00
Problem: radix tree's apply function uses incorrect resizing logic (#3548)
* Problem: radix tree's apply function uses incorrect resizing logic Solution: rewrite the function using a vector The buffer is extended once by 256 bytes, which will not be enough if the node holds data larger than this number.
This commit is contained in:
parent
b17e854f15
commit
15dafb1c1c
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
node::node (unsigned char *data) : data_ (data)
|
node::node (unsigned char *data) : data_ (data)
|
||||||
{
|
{
|
||||||
@ -517,35 +518,33 @@ bool zmq::radix_tree::check (const unsigned char *key, size_t size)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
visit_keys (node n,
|
visit_keys (node n,
|
||||||
unsigned char **buffer,
|
std::vector<unsigned char> &buffer,
|
||||||
size_t buffer_size,
|
|
||||||
size_t maxbuffer_size,
|
|
||||||
void (*func) (unsigned char *data, size_t size, void *arg),
|
void (*func) (unsigned char *data, size_t size, void *arg),
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
if (buffer_size >= maxbuffer_size) {
|
for (size_t i = 0; i < n.prefix_length (); ++i)
|
||||||
maxbuffer_size += 256;
|
buffer.push_back (n.prefix ()[i]);
|
||||||
*buffer =
|
|
||||||
static_cast<unsigned char *> (realloc (*buffer, maxbuffer_size));
|
if (n.refcount () > 0) {
|
||||||
zmq_assert (*buffer);
|
zmq_assert (!buffer.empty ());
|
||||||
|
func (&buffer[0], buffer.size (), arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < n.prefix_length (); ++i)
|
|
||||||
(*buffer)[buffer_size++] = n.prefix ()[i];
|
|
||||||
if (n.refcount () > 0)
|
|
||||||
func (*buffer, buffer_size, arg);
|
|
||||||
for (size_t i = 0; i < n.edgecount (); ++i)
|
for (size_t i = 0; i < n.edgecount (); ++i)
|
||||||
visit_keys (n.node_at (i), buffer, buffer_size, maxbuffer_size, func,
|
visit_keys (n.node_at (i), buffer, func, arg);
|
||||||
arg);
|
for (size_t i = 0; i < n.prefix_length (); ++i)
|
||||||
buffer_size -= n.prefix_length ();
|
buffer.pop_back ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmq::radix_tree::apply (
|
void zmq::radix_tree::apply (
|
||||||
void (*func) (unsigned char *data, size_t size, void *arg), void *arg)
|
void (*func) (unsigned char *data, size_t size, void *arg), void *arg)
|
||||||
{
|
{
|
||||||
unsigned char *buffer = NULL;
|
if (root_.refcount () > 0)
|
||||||
visit_keys (root_, &buffer, 0, 0, func, arg);
|
func (NULL, 0, arg); // Root node is always empty.
|
||||||
free (buffer);
|
|
||||||
|
std::vector<unsigned char> buffer;
|
||||||
|
for (size_t i = 0; i < root_.edgecount (); ++i)
|
||||||
|
visit_keys (root_.node_at (i), buffer, func, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t zmq::radix_tree::size () const
|
size_t zmq::radix_tree::size () const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user