Improve byte_data const correctness

This commit is contained in:
topjohnwu
2023-06-03 03:16:03 -07:00
parent 57afae3425
commit 2a654e5d7f
17 changed files with 186 additions and 161 deletions

View File

@@ -433,14 +433,14 @@ sFILE make_file(FILE *fp) {
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
}
int byte_data::patch(bool log, str_pairs list) {
if (buf == nullptr)
int byte_data::patch(str_pairs list) {
if (_buf == nullptr)
return 0;
int count = 0;
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) {
for (auto [from, to] : list) {
for (uint8_t *p = _buf, *eof = _buf + _sz; p < eof; ++p) {
for (auto &[from, to] : list) {
if (memcmp(p, from.data(), from.length() + 1) == 0) {
if (log) LOGD("Replace [%s] -> [%s]\n", from.data(), to.data());
LOGD("Patch @ %08X [%s] -> [%s]\n", (unsigned)(p - _buf), from.data(), to.data());
memset(p, 0, from.length());
memcpy(p, to.data(), to.length());
++count;
@@ -451,33 +451,55 @@ int byte_data::patch(bool log, str_pairs list) {
return count;
}
bool byte_data::contains(string_view pattern, bool log) const {
if (buf == nullptr)
int byte_data::patch(byte_pairs list) {
if (_buf == nullptr)
return 0;
int count = 0;
for (uint8_t *p = _buf, *eof = _buf + _sz; p < eof; ++p) {
for (auto &[from, to] : list) {
if (memcmp(p, from.buf(), from.sz()) == 0) {
LOGD("Patch @ %08X\n", (unsigned)(p - _buf));
memset(p, 0, from.sz());
memcpy(p, to.buf(), to.sz());
++count;
p += from.sz();
}
}
}
return count;
}
bool byte_view::contains(string_view pattern) const {
if (_buf == nullptr)
return false;
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) {
for (uint8_t *p = _buf, *eof = _buf + _sz; p < eof; ++p) {
if (memcmp(p, pattern.data(), pattern.length() + 1) == 0) {
if (log) LOGD("Found pattern [%s]\n", pattern.data());
LOGD("Found pattern [%s]\n", pattern.data());
return true;
}
}
return false;
}
bool byte_data::equals(const byte_data &o) const {
return sz == o.sz && memcmp(buf, o.buf, sz) == 0;
bool byte_view::equals(const byte_view &o) const {
return _sz == o._sz && memcmp(_buf, o._buf, _sz) == 0;
}
void byte_data::swap(byte_data &o) {
std::swap(buf, o.buf);
std::swap(sz, o.sz);
void byte_view::swap(byte_view &o) {
std::swap(_buf, o._buf);
std::swap(_sz, o._sz);
}
heap_data byte_data::clone() const {
heap_data copy(sz);
memcpy(copy.buf, buf, sz);
heap_data byte_view::clone() const {
heap_data copy(_sz);
memcpy(copy._buf, _buf, _sz);
return copy;
}
void heap_data::realloc(size_t sz) {
_buf = static_cast<uint8_t *>(::realloc(_buf, sz));
}
mmap_data::mmap_data(const char *name, bool rw) {
int fd = xopen(name, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC);
if (fd < 0)
@@ -488,15 +510,15 @@ mmap_data::mmap_data(const char *name, bool rw) {
if (S_ISBLK(st.st_mode)) {
uint64_t size;
ioctl(fd, BLKGETSIZE64, &size);
sz = size;
_sz = size;
} else {
sz = st.st_size;
_sz = st.st_size;
}
void *b = sz > 0
? xmmap(nullptr, sz, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0)
void *b = _sz > 0
? xmmap(nullptr, _sz, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0)
: nullptr;
close(fd);
buf = static_cast<uint8_t *>(b);
_buf = static_cast<uint8_t *>(b);
}
string find_apk_path(const char *pkg) {

View File

@@ -45,23 +45,41 @@ struct mount_info {
struct heap_data;
struct byte_data {
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
struct byte_view {
byte_view() : _buf(nullptr), _sz(0) {}
byte_view(const void *buf, size_t sz) : _buf((uint8_t *) buf), _sz(sz) {}
byte_view(std::string_view str) : byte_view(str.data(), str.length()) {}
byte_view(const std::vector<uint8_t> &v) : byte_view(v.data(), v.size()) {}
uint8_t *buf;
size_t sz;
const uint8_t *buf() const { return _buf; }
const size_t &sz() const { return _sz; }
byte_data() : buf(nullptr), sz(0) {}
byte_data(void *buf, size_t sz) : buf(static_cast<uint8_t *>(buf)), sz(sz) {}
explicit byte_data(std::string_view str) : buf((uint8_t *) str.data()), sz(str.length()) {}
int patch(str_pairs list) { return patch(true, list); }
int patch(bool log, str_pairs list);
bool contains(std::string_view pattern, bool log = true) const;
bool equals(const byte_data &o) const;
bool contains(std::string_view pattern) const;
bool equals(const byte_view &o) const;
heap_data clone() const;
protected:
void swap(byte_data &o);
uint8_t *_buf;
size_t _sz;
byte_view(uint8_t *buf, size_t sz) : _buf(buf), _sz(sz) {}
void swap(byte_view &o);
};
struct byte_data : public byte_view {
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
using byte_pairs = std::initializer_list<std::pair<byte_view, byte_view>>;
byte_data() = default;
byte_data(void *buf, size_t sz) : byte_view(static_cast<uint8_t *>(buf), sz) {}
using byte_view::buf;
using byte_view::sz;
uint8_t *buf() { return _buf; }
size_t &sz() { return _sz; }
int patch(str_pairs list);
int patch(byte_pairs list);
};
#define MOVE_ONLY(clazz) \
@@ -73,16 +91,18 @@ clazz& operator=(clazz &&o) { swap(o); return *this; }
struct heap_data : public byte_data {
MOVE_ONLY(heap_data)
explicit heap_data(size_t sz) : byte_data(new uint8_t[sz], sz) {}
heap_data(const void *buf, size_t sz) : heap_data(sz) { memcpy(this->buf, buf, sz); }
~heap_data() { delete[] buf; }
explicit heap_data(size_t sz) : byte_data(malloc(sz), sz) {}
heap_data(const void *buf, size_t sz) : heap_data(sz) { memcpy(_buf, buf, sz); }
~heap_data() { free(_buf); }
void realloc(size_t sz);
};
struct mmap_data : public byte_data {
MOVE_ONLY(mmap_data)
mmap_data(const char *name, bool rw = false);
~mmap_data() { if (buf) munmap(buf, sz); }
~mmap_data() { if (_buf) munmap(_buf, _sz); }
};
extern "C" {

View File

@@ -95,9 +95,9 @@ bool chunk_out_stream::write(const void *_in, size_t len) {
// Enough input for a chunk
const uint8_t *src;
if (buf_off) {
src = data.buf;
src = data.buf();
auto copy = chunk_sz - buf_off;
memcpy(data.buf + buf_off, in, copy);
memcpy(data.buf() + buf_off, in, copy);
in += copy;
len -= copy;
buf_off = 0;
@@ -110,7 +110,7 @@ bool chunk_out_stream::write(const void *_in, size_t len) {
return false;
} else {
// Buffer internally
memcpy(data.buf + buf_off, in, len);
memcpy(data.buf() + buf_off, in, len);
buf_off += len;
break;
}
@@ -124,7 +124,7 @@ bool chunk_out_stream::write_chunk(const void *buf, size_t len, bool) {
void chunk_out_stream::finalize() {
if (buf_off) {
if (!write_chunk(data.buf, buf_off, true)) {
if (!write_chunk(data.buf(), buf_off, true)) {
LOGE("Error in finalize, file truncated\n");
}
buf_off = 0;
@@ -132,17 +132,17 @@ void chunk_out_stream::finalize() {
}
ssize_t byte_channel::read(void *buf, size_t len) {
len = std::min((size_t) len, _data.sz - _pos);
memcpy(buf, _data.buf + _pos, len);
len = std::min((size_t) len, _data.sz() - _pos);
memcpy(buf, _data.buf() + _pos, len);
_pos += len;
return len;
}
bool byte_channel::write(const void *buf, size_t len) {
resize(_pos + len);
memcpy(_data.buf + _pos, buf, len);
memcpy(_data.buf() + _pos, buf, len);
_pos += len;
_data.sz = std::max(_data.sz, _pos);
_data.sz() = std::max(_data.sz(), _pos);
return true;
}
@@ -153,7 +153,7 @@ off_t byte_channel::seek(off_t off, int whence) {
np = _pos + off;
break;
case SEEK_END:
np = _data.sz + off;
np = _data.sz() + off;
break;
case SEEK_SET:
np = off;
@@ -174,9 +174,9 @@ void byte_channel::resize(size_t new_sz, bool zero) {
resize = true;
}
if (resize) {
_data.buf = (uint8_t *) realloc(_data.buf, _cap);
_data.realloc(_cap);
if (zero)
memset(_data.buf + old_cap, 0, _cap - old_cap);
memset(_data.buf() + old_cap, 0, _cap - old_cap);
}
}