forked from premiere/premiere-libtorrent
fix issue in internal_file_entry when assigning an empty string that's borrowed
This commit is contained in:
parent
590c0d876c
commit
1dd5e5128b
|
@ -119,11 +119,11 @@ namespace libtorrent
|
|||
friend class torrent_info;
|
||||
#endif
|
||||
internal_file_entry()
|
||||
: name(0)
|
||||
: name(NULL)
|
||||
, offset(0)
|
||||
, symlink_index(-1)
|
||||
, symlink_index(not_a_symlink)
|
||||
, size(0)
|
||||
, name_len(0)
|
||||
, name_len(name_is_owned)
|
||||
, pad_file(false)
|
||||
, hidden_attribute(false)
|
||||
, executable_attribute(false)
|
||||
|
@ -132,11 +132,11 @@ namespace libtorrent
|
|||
{}
|
||||
|
||||
internal_file_entry(file_entry const& e)
|
||||
: name(0)
|
||||
: name(NULL)
|
||||
, offset(e.offset)
|
||||
, symlink_index(-1)
|
||||
, symlink_index(not_a_symlink)
|
||||
, size(e.size)
|
||||
, name_len(0)
|
||||
, name_len(name_is_owned)
|
||||
, pad_file(e.pad_file)
|
||||
, hidden_attribute(e.hidden_attribute)
|
||||
, executable_attribute(e.executable_attribute)
|
||||
|
@ -151,7 +151,7 @@ namespace libtorrent
|
|||
|
||||
~internal_file_entry();
|
||||
|
||||
void set_name(char const* n, int borrow_chars = 0);
|
||||
void set_name(char const* n, bool borrow_string = false, int string_len = 0);
|
||||
std::string filename() const;
|
||||
|
||||
// make it available for logging
|
||||
|
@ -165,26 +165,30 @@ namespace libtorrent
|
|||
char const* name;
|
||||
public:
|
||||
|
||||
enum {
|
||||
name_is_owned = (1<<12)-1,
|
||||
not_a_symlink = (1<<16)-1
|
||||
};
|
||||
// the offset of this file inside the torrent
|
||||
size_type offset:48;
|
||||
boost::uint64_t offset:48;
|
||||
|
||||
// index into file_storage::m_symlinks or -1
|
||||
// index into file_storage::m_symlinks or not_a_symlink
|
||||
// if this is not a symlink
|
||||
size_type symlink_index:16;
|
||||
boost::uint64_t symlink_index:16;
|
||||
|
||||
// the size of this file
|
||||
size_type size:48;
|
||||
boost::uint64_t size:48;
|
||||
|
||||
// the number of characters in the name. If this is
|
||||
// 0, name is null terminated and owned by this object
|
||||
// name_is_owned, name is null terminated and owned by this object
|
||||
// (i.e. it should be freed in the destructor). If
|
||||
// the len is > 0, the name pointer doesn not belong
|
||||
// the len is not name_is_owned, the name pointer doesn not belong
|
||||
// to this object, and it's not null terminated
|
||||
size_type name_len:10;
|
||||
bool pad_file:1;
|
||||
bool hidden_attribute:1;
|
||||
bool executable_attribute:1;
|
||||
bool symlink_attribute:1;
|
||||
boost::uint64_t name_len:12;
|
||||
boost::uint64_t pad_file:1;
|
||||
boost::uint64_t hidden_attribute:1;
|
||||
boost::uint64_t executable_attribute:1;
|
||||
boost::uint64_t symlink_attribute:1;
|
||||
// the index into file_storage::m_paths. To get
|
||||
// the full path to this file, concatenate the path
|
||||
// from that array with the 'name' field in
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace libtorrent
|
|||
|
||||
file_entry::~file_entry() {}
|
||||
|
||||
internal_file_entry::~internal_file_entry() { if (name_len == 0) free((void*)name); }
|
||||
internal_file_entry::~internal_file_entry() { if (name_len == name_is_owned) free((void*)name); }
|
||||
|
||||
internal_file_entry::internal_file_entry(internal_file_entry const& fe)
|
||||
: name(0)
|
||||
|
@ -142,26 +142,40 @@ namespace libtorrent
|
|||
return *this;
|
||||
}
|
||||
|
||||
void internal_file_entry::set_name(char const* n, int borrow_chars)
|
||||
// if borrow_chars >= 0, don't take ownership over n, just
|
||||
// point to it. It points to borrow_chars number of characters.
|
||||
// if borrow_chars == -1, n is a null terminated string that
|
||||
// should be copied
|
||||
void internal_file_entry::set_name(char const* n, bool borrow_string, int string_len)
|
||||
{
|
||||
TORRENT_ASSERT(borrow_chars >= 0);
|
||||
if (borrow_chars > 1023) borrow_chars = 1023;
|
||||
if (name_len == 0) free((void*)name);
|
||||
if (n == 0 || *n == 0)
|
||||
TORRENT_ASSERT(string_len >= 0);
|
||||
|
||||
// we have limited space in the length field. truncate string
|
||||
// if it's too long
|
||||
if (string_len >= name_is_owned) string_len = name_is_owned - 1;
|
||||
|
||||
// free the current string, before assigning the new one
|
||||
if (name_len == name_is_owned) free((void*)name);
|
||||
if (n == NULL)
|
||||
{
|
||||
TORRENT_ASSERT(borrow_chars == 0);
|
||||
name = 0;
|
||||
TORRENT_ASSERT(borrow_string == false);
|
||||
name = NULL;
|
||||
}
|
||||
else if (borrow_string)
|
||||
{
|
||||
name = n;
|
||||
name_len = string_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = borrow_chars ? n : allocate_string_copy(n);
|
||||
name = allocate_string_copy(n);
|
||||
name_len = name_is_owned;
|
||||
}
|
||||
name_len = borrow_chars;
|
||||
}
|
||||
|
||||
std::string internal_file_entry::filename() const
|
||||
{
|
||||
if (name_len) return std::string(name, name_len);
|
||||
if (name_len != name_is_owned) return std::string(name, name_len);
|
||||
return name ? name : "";
|
||||
}
|
||||
|
||||
|
@ -203,7 +217,7 @@ namespace libtorrent
|
|||
void file_storage::rename_file_borrow(int index, char const* new_filename, int len)
|
||||
{
|
||||
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
|
||||
m_files[index].set_name(new_filename, len);
|
||||
m_files[index].set_name(new_filename, true, len);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -253,6 +267,8 @@ namespace libtorrent
|
|||
|
||||
int file_storage::file_name_len(int index) const
|
||||
{
|
||||
if (m_files[index].name_len == internal_file_entry::name_is_owned)
|
||||
return -1;
|
||||
return m_files[index].name_len;
|
||||
}
|
||||
|
||||
|
@ -285,7 +301,7 @@ namespace libtorrent
|
|||
file_slice f;
|
||||
f.file_index = file_iter - m_files.begin();
|
||||
f.offset = file_offset + file_base(f.file_index);
|
||||
f.size = (std::min)(file_iter->size - file_offset, (size_type)size);
|
||||
f.size = (std::min)(size_type(file_iter->size) - file_offset, (size_type)size);
|
||||
TORRENT_ASSERT(f.size <= size);
|
||||
size -= int(f.size);
|
||||
file_offset += f.size;
|
||||
|
@ -311,7 +327,7 @@ namespace libtorrent
|
|||
ret.hidden_attribute = ife.hidden_attribute;
|
||||
ret.executable_attribute = ife.executable_attribute;
|
||||
ret.symlink_attribute = ife.symlink_attribute;
|
||||
if (ife.symlink_index >= 0) ret.symlink_path = symlink(index);
|
||||
if (ife.symlink_index != internal_file_entry::not_a_symlink) ret.symlink_path = symlink(index);
|
||||
ret.filehash = hash(index);
|
||||
return ret;
|
||||
}
|
||||
|
@ -415,7 +431,6 @@ namespace libtorrent
|
|||
int file_index = m_files.size();
|
||||
m_files.push_back(ife);
|
||||
internal_file_entry& e = m_files.back();
|
||||
if (e.size < 0) e.size = 0;
|
||||
e.offset = m_total_size;
|
||||
m_total_size += e.size;
|
||||
if (filehash)
|
||||
|
|
|
@ -1399,7 +1399,7 @@ namespace libtorrent
|
|||
for (int i = 0; i < m_files.num_files(); ++i)
|
||||
{
|
||||
TORRENT_ASSERT(m_files.file_name_ptr(i) != 0);
|
||||
if (m_files.file_name_len(i) > 0)
|
||||
if (m_files.file_name_len(i) != -1)
|
||||
{
|
||||
// name needs to point into the allocated info section buffer
|
||||
TORRENT_ASSERT(m_files.file_name_ptr(i) >= m_info_section.get());
|
||||
|
|
|
@ -83,7 +83,6 @@ int test_main()
|
|||
using namespace libtorrent;
|
||||
using namespace libtorrent::dht;
|
||||
error_code ec;
|
||||
int ret = 0;
|
||||
|
||||
// make sure the retry interval keeps growing
|
||||
// on failing announces
|
||||
|
|
Loading…
Reference in New Issue