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;
|
friend class torrent_info;
|
||||||
#endif
|
#endif
|
||||||
internal_file_entry()
|
internal_file_entry()
|
||||||
: name(0)
|
: name(NULL)
|
||||||
, offset(0)
|
, offset(0)
|
||||||
, symlink_index(-1)
|
, symlink_index(not_a_symlink)
|
||||||
, size(0)
|
, size(0)
|
||||||
, name_len(0)
|
, name_len(name_is_owned)
|
||||||
, pad_file(false)
|
, pad_file(false)
|
||||||
, hidden_attribute(false)
|
, hidden_attribute(false)
|
||||||
, executable_attribute(false)
|
, executable_attribute(false)
|
||||||
|
@ -132,11 +132,11 @@ namespace libtorrent
|
||||||
{}
|
{}
|
||||||
|
|
||||||
internal_file_entry(file_entry const& e)
|
internal_file_entry(file_entry const& e)
|
||||||
: name(0)
|
: name(NULL)
|
||||||
, offset(e.offset)
|
, offset(e.offset)
|
||||||
, symlink_index(-1)
|
, symlink_index(not_a_symlink)
|
||||||
, size(e.size)
|
, size(e.size)
|
||||||
, name_len(0)
|
, name_len(name_is_owned)
|
||||||
, pad_file(e.pad_file)
|
, pad_file(e.pad_file)
|
||||||
, hidden_attribute(e.hidden_attribute)
|
, hidden_attribute(e.hidden_attribute)
|
||||||
, executable_attribute(e.executable_attribute)
|
, executable_attribute(e.executable_attribute)
|
||||||
|
@ -151,7 +151,7 @@ namespace libtorrent
|
||||||
|
|
||||||
~internal_file_entry();
|
~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;
|
std::string filename() const;
|
||||||
|
|
||||||
// make it available for logging
|
// make it available for logging
|
||||||
|
@ -165,26 +165,30 @@ namespace libtorrent
|
||||||
char const* name;
|
char const* name;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum {
|
||||||
|
name_is_owned = (1<<12)-1,
|
||||||
|
not_a_symlink = (1<<16)-1
|
||||||
|
};
|
||||||
// the offset of this file inside the torrent
|
// 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
|
// if this is not a symlink
|
||||||
size_type symlink_index:16;
|
boost::uint64_t symlink_index:16;
|
||||||
|
|
||||||
// the size of this file
|
// the size of this file
|
||||||
size_type size:48;
|
boost::uint64_t size:48;
|
||||||
|
|
||||||
// the number of characters in the name. If this is
|
// 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
|
// (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
|
// to this object, and it's not null terminated
|
||||||
size_type name_len:10;
|
boost::uint64_t name_len:12;
|
||||||
bool pad_file:1;
|
boost::uint64_t pad_file:1;
|
||||||
bool hidden_attribute:1;
|
boost::uint64_t hidden_attribute:1;
|
||||||
bool executable_attribute:1;
|
boost::uint64_t executable_attribute:1;
|
||||||
bool symlink_attribute:1;
|
boost::uint64_t symlink_attribute:1;
|
||||||
// the index into file_storage::m_paths. To get
|
// the index into file_storage::m_paths. To get
|
||||||
// the full path to this file, concatenate the path
|
// the full path to this file, concatenate the path
|
||||||
// from that array with the 'name' field in
|
// from that array with the 'name' field in
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace libtorrent
|
||||||
|
|
||||||
file_entry::~file_entry() {}
|
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)
|
internal_file_entry::internal_file_entry(internal_file_entry const& fe)
|
||||||
: name(0)
|
: name(0)
|
||||||
|
@ -142,26 +142,40 @@ namespace libtorrent
|
||||||
return *this;
|
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);
|
TORRENT_ASSERT(string_len >= 0);
|
||||||
if (borrow_chars > 1023) borrow_chars = 1023;
|
|
||||||
if (name_len == 0) free((void*)name);
|
// we have limited space in the length field. truncate string
|
||||||
if (n == 0 || *n == 0)
|
// 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);
|
TORRENT_ASSERT(borrow_string == false);
|
||||||
name = 0;
|
name = NULL;
|
||||||
|
}
|
||||||
|
else if (borrow_string)
|
||||||
|
{
|
||||||
|
name = n;
|
||||||
|
name_len = string_len;
|
||||||
}
|
}
|
||||||
else
|
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
|
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 : "";
|
return name ? name : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +217,7 @@ namespace libtorrent
|
||||||
void file_storage::rename_file_borrow(int index, char const* new_filename, int len)
|
void file_storage::rename_file_borrow(int index, char const* new_filename, int len)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
|
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
|
namespace
|
||||||
|
@ -253,6 +267,8 @@ namespace libtorrent
|
||||||
|
|
||||||
int file_storage::file_name_len(int index) const
|
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;
|
return m_files[index].name_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +301,7 @@ namespace libtorrent
|
||||||
file_slice f;
|
file_slice f;
|
||||||
f.file_index = file_iter - m_files.begin();
|
f.file_index = file_iter - m_files.begin();
|
||||||
f.offset = file_offset + file_base(f.file_index);
|
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);
|
TORRENT_ASSERT(f.size <= size);
|
||||||
size -= int(f.size);
|
size -= int(f.size);
|
||||||
file_offset += f.size;
|
file_offset += f.size;
|
||||||
|
@ -311,7 +327,7 @@ namespace libtorrent
|
||||||
ret.hidden_attribute = ife.hidden_attribute;
|
ret.hidden_attribute = ife.hidden_attribute;
|
||||||
ret.executable_attribute = ife.executable_attribute;
|
ret.executable_attribute = ife.executable_attribute;
|
||||||
ret.symlink_attribute = ife.symlink_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);
|
ret.filehash = hash(index);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -415,7 +431,6 @@ namespace libtorrent
|
||||||
int file_index = m_files.size();
|
int file_index = m_files.size();
|
||||||
m_files.push_back(ife);
|
m_files.push_back(ife);
|
||||||
internal_file_entry& e = m_files.back();
|
internal_file_entry& e = m_files.back();
|
||||||
if (e.size < 0) e.size = 0;
|
|
||||||
e.offset = m_total_size;
|
e.offset = m_total_size;
|
||||||
m_total_size += e.size;
|
m_total_size += e.size;
|
||||||
if (filehash)
|
if (filehash)
|
||||||
|
|
|
@ -1399,7 +1399,7 @@ namespace libtorrent
|
||||||
for (int i = 0; i < m_files.num_files(); ++i)
|
for (int i = 0; i < m_files.num_files(); ++i)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_files.file_name_ptr(i) != 0);
|
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
|
// name needs to point into the allocated info section buffer
|
||||||
TORRENT_ASSERT(m_files.file_name_ptr(i) >= m_info_section.get());
|
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;
|
||||||
using namespace libtorrent::dht;
|
using namespace libtorrent::dht;
|
||||||
error_code ec;
|
error_code ec;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
// make sure the retry interval keeps growing
|
// make sure the retry interval keeps growing
|
||||||
// on failing announces
|
// on failing announces
|
||||||
|
|
Loading…
Reference in New Issue