mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-31 22:50:54 +00:00
gems/vfs.h: make 'File_content' more robust
This patch addresses two problems: By guarding the buffer allocation in a nested class, an exception in the body of the 'File_content' constructor reverts the allocation. Second, if the file has no content no allocation should be performed. The previous version wrongly passed a size of zero to the allocator in this case.
This commit is contained in:
parent
89d0d648ed
commit
3976a43c84
@ -426,16 +426,26 @@ class Genode::File_content
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Allocator &_alloc;
|
class Buffer
|
||||||
size_t const _size;
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
char *_buffer = (char *)_alloc.alloc(_size);
|
/*
|
||||||
|
* Noncopyable
|
||||||
|
*/
|
||||||
|
Buffer(Buffer const &);
|
||||||
|
Buffer &operator = (Buffer const &);
|
||||||
|
|
||||||
/*
|
public:
|
||||||
* Noncopyable
|
|
||||||
*/
|
Allocator &alloc;
|
||||||
File_content(File_content const &);
|
size_t const size;
|
||||||
File_content &operator = (File_content const &);
|
char * const ptr = size ? (char *)alloc.alloc(size) : nullptr;
|
||||||
|
|
||||||
|
Buffer(Allocator &alloc, size_t size) : alloc(alloc), size(size) { }
|
||||||
|
~Buffer() { if (ptr) alloc.free(ptr, size); }
|
||||||
|
|
||||||
|
} _buffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -456,15 +466,12 @@ class Genode::File_content
|
|||||||
File_content(Allocator &alloc, Directory const &dir, Path const &rel_path,
|
File_content(Allocator &alloc, Directory const &dir, Path const &rel_path,
|
||||||
Limit limit)
|
Limit limit)
|
||||||
:
|
:
|
||||||
_alloc(alloc),
|
_buffer(alloc, min(dir.file_size(rel_path), (Vfs::file_size)limit.value))
|
||||||
_size(min(dir.file_size(rel_path), (Vfs::file_size)limit.value))
|
|
||||||
{
|
{
|
||||||
if (Readonly_file(dir, rel_path).read(_buffer, _size) != _size)
|
if (Readonly_file(dir, rel_path).read(_buffer.ptr, _buffer.size) != _buffer.size)
|
||||||
throw Truncated_during_read();
|
throw Truncated_during_read();
|
||||||
}
|
}
|
||||||
|
|
||||||
~File_content() { _alloc.free(_buffer, _size); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call functor 'fn' with content as 'Xml_node' argument
|
* Call functor 'fn' with content as 'Xml_node' argument
|
||||||
*
|
*
|
||||||
@ -474,7 +481,7 @@ class Genode::File_content
|
|||||||
template <typename FN>
|
template <typename FN>
|
||||||
void xml(FN const &fn) const
|
void xml(FN const &fn) const
|
||||||
{
|
{
|
||||||
try { fn(Xml_node(_buffer, _size)); }
|
try { fn(Xml_node(_buffer.ptr, _buffer.size)); }
|
||||||
catch (Xml_node::Invalid_syntax) { fn(Xml_node("<empty/>")); }
|
catch (Xml_node::Invalid_syntax) { fn(Xml_node("<empty/>")); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,14 +493,14 @@ class Genode::File_content
|
|||||||
template <typename STRING, typename FN>
|
template <typename STRING, typename FN>
|
||||||
void for_each_line(FN const &fn) const
|
void for_each_line(FN const &fn) const
|
||||||
{
|
{
|
||||||
char const *src = _buffer;
|
char const *src = _buffer.ptr;
|
||||||
char const *curr_line = src;
|
char const *curr_line = src;
|
||||||
size_t curr_line_len = 0;
|
size_t curr_line_len = 0;
|
||||||
|
|
||||||
for (size_t n = 0; ; n++) {
|
for (size_t n = 0; ; n++) {
|
||||||
|
|
||||||
char const c = *src++;
|
char const c = *src++;
|
||||||
bool const end_of_data = (c == 0 || n == _size);
|
bool const end_of_data = (c == 0 || n == _buffer.size);
|
||||||
bool const end_of_line = (c == '\n');
|
bool const end_of_line = (c == '\n');
|
||||||
|
|
||||||
if (!end_of_data && !end_of_line) {
|
if (!end_of_data && !end_of_line) {
|
||||||
@ -516,7 +523,7 @@ class Genode::File_content
|
|||||||
* Call functor 'fn' with the data pointer and size in bytes
|
* Call functor 'fn' with the data pointer and size in bytes
|
||||||
*/
|
*/
|
||||||
template <typename FN>
|
template <typename FN>
|
||||||
void bytes(FN const &fn) const { fn((char const *)_buffer, _size); }
|
void bytes(FN const &fn) const { fn((char const *)_buffer.ptr, _buffer.size); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user