Bugfixes part 3 #209

Open
andrey wants to merge 36 commits from bugfixes3 into master
27 changed files with 236 additions and 134 deletions
+1 -1
View File
@@ -201,7 +201,7 @@ ssize_t PICloudServer::Client::readDevice(void * read_to, ssize_t max_size) {
if (buff.isEmpty()) {
sz = 0;
} else {
sz = piMini(max_size, buff.size());
sz = piMin<ssize_t>(max_size, buff.size_s());
memcpy(read_to, buff.data(), sz);
buff.remove(0, sz);
}
+1 -1
View File
@@ -68,7 +68,7 @@ PIByteArray piDecompress(const PIByteArray & zba) {
ba.resize(sz);
int ret = 0;
ulong s = sz;
ret = uncompress(ba.data(), &s, zba.data(), zba.size());
ret = uncompress(ba.data(), &s, zba.data(), zba.size() - sizeof(ullong));
if (ret != Z_OK) {
piCout << "[PICompress]"
<< "Error: invalid input or not enought memory"_tr("PICompress");
+4 -4
View File
@@ -20,6 +20,7 @@
#include "picrypt.h"
#include "pitranslator.h"
#include <sodium.h>
@@ -53,7 +54,7 @@ bool PICrypt::setKey(const PIByteArray & _key) {
}
bool PICrypt::setKey(const PIString & secret) {;
bool PICrypt::setKey(const PIString & secret) {
key_ = hash(secret);
return key_.isNotEmpty();
}
@@ -262,7 +263,6 @@ PIByteArray PICrypt::signMessage(const PIByteArray & data, const PIByteArray & s
bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, const PIByteArray & public_key) {
if (!init()) return false;
return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0);
return false;
}
@@ -317,10 +317,10 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, const PIByteArray &
return PIByteArray();
}
PIByteArray n;
n.resize(crypto_secretbox_NONCEBYTES);
n.resize(crypto_box_NONCEBYTES);
const ullong data_size = crypt_data.size() - n.size();
PIByteArray ret;
ret.resize(data_size - crypto_secretbox_MACBYTES);
ret.resize(data_size - crypto_box_MACBYTES);
memcpy(n.data(), crypt_data.data(data_size), n.size());
if (crypto_box_open_easy(ret.data(), crypt_data.data(), data_size, n.data(), public_key.data(), secret_key.data()) != 0) {
// Bad key
+5
View File
@@ -92,5 +92,10 @@ void CurlThreadPool::destroy() {
for (auto c: *cr)
delete c;
}
{
auto cr = clients_in_proc.getRef();
for (auto c: *cr)
delete c;
}
// piCout << "~CurlThreadPool ok";
}
+1
View File
@@ -73,6 +73,7 @@ void PIStreamPacker::send(const PIByteArray & data) {
} else
hdr << int(cd.size_s());
cd.insert(0, hdr);
if (max_packet_size <= 0) return;
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0;
for (int i = 0; i < pcnt; ++i) {
if (i == pcnt - 1)
+5
View File
@@ -30,6 +30,11 @@ PILuaProgram::PILuaProgram() {
}
PILuaProgram::~PILuaProgram() {
lua_close(PRIVATE->lua_state);
}
bool PILuaProgram::load(const PIString & script) {
int ret = luaL_dostring(PRIVATE->lua_state, script.dataUTF8());
if (ret != 0) return false;
+2 -2
View File
@@ -270,8 +270,8 @@ PIInit::~PIInit() {
mach_port_deallocate(mach_task_self(), __pi_mac_clock);
# endif
if (PRIVATE->delete_locs) {
if (__syslocname__) delete __syslocname__;
if (__sysoemname__) delete __sysoemname__;
if (__syslocname__) delete[] __syslocname__;
if (__sysoemname__) delete[] __sysoemname__;
}
# ifdef PIP_ICU
u_cleanup();
+3 -2
View File
@@ -73,7 +73,8 @@ bool PICAN::openDevice() {
}
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
ifreq ifr;
strcpy(ifr.ifr_name, path().dataAscii());
piZeroMemory(ifr);
strncpy(ifr.ifr_name, path().dataAscii(), sizeof(ifr.ifr_name));
piCout << "PICAN try to get interface index...";
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
piCoutObj << "Error! while determin the interface ioctl";
@@ -124,7 +125,7 @@ ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) {
#ifdef PIP_CAN
if (sock == -1) return -1;
// piCout << "PICAN read";
can_frame frame;
can_frame frame = {};
ssize_t ret = 0;
if (PRIVATE->event.wait(sock)) ret = ::read(sock, &frame, sizeof(can_frame));
if (ret < 0) { /*piCoutObj << "Error while read CAN frame " << ret;*/
+2 -1
View File
@@ -372,7 +372,7 @@ PIVector<PIFile::FileInfo> PIDir::entries(const PIRegularExpression & regexp) {
closedir(dir);
}
# else
dirent ** list;
dirent ** list = nullptr;
int cnt = scandir(p.data(),
&list,
0,
@@ -381,6 +381,7 @@ PIVector<PIFile::FileInfo> PIDir::entries(const PIRegularExpression & regexp) {
# else
versionsort);
# endif
if (cnt < 0) return ret;
for (int i = 0; i < cnt; ++i) {
ret << PIFile::fileInfo(dp + PIString(list[i]->d_name));
free(list[i]);
+5 -3
View File
@@ -1206,8 +1206,10 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
strcpy(ir.ifr_name, in.dataAscii());
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0) ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
if (ioctl(s, SIOCGIFADDR, &ir) >= 0) ci.address = getSockAddr(&ir.ifr_addr);
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0) ci.netmask = getSockAddr(&ir.ifr_addr);
ioctl(s, SIOCGIFMTU, &ci.mtu);
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0) ci.netmask = getSockAddr(&ir.ifr_netmask);
if (ioctl(s, SIOCGIFMTU, &ir) == 0) {
ci.mtu = ir.ifr_mtu;
}
if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback;
il << ci;
}
@@ -1301,7 +1303,7 @@ PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) {
#else
struct ifreq ifr;
piZeroMemory(ifr);
strcpy(ifr.ifr_name, interface_.dataAscii());
strncpy(ifr.ifr_name, interface_.dataAscii(), sizeof(ifr.ifr_name));
int s = ::socket(AF_INET, SOCK_DGRAM, 0);
if (s != -1) {
ioctl(s, SIOCGIFADDR, &ifr);
+5
View File
@@ -1292,6 +1292,11 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
if (!rok) {
ret.remove(i);
--i;
#ifdef WINDOWS
CloseHandle(hComm);
#else
::close(fd);
#endif
continue;
}
#ifdef WINDOWS
+5
View File
@@ -144,6 +144,9 @@ bool PISharedMemory::openDevice() {
::close(fd);
if (PRIVATE->data == MAP_FAILED) {
piCoutObj << "mmap error," << errorString();
if (PRIVATE->owner) shm_unlink((const char *)PRIVATE->name.data());
PRIVATE->data = nullptr;
PRIVATE->owner = false;
return false;
}
// piCoutObj << "opened" << PRIVATE->data;
@@ -251,6 +254,7 @@ int PISharedMemory::read(void * read_to, int max_size) {
int PISharedMemory::read(void * read_to, int max_size, int offset) {
if (offset < 0 || max_size < 0 || offset > dsize - max_size) return -1;
#ifdef WINDOWS
if (!PRIVATE->data) return -1;
CopyMemory(read_to, &(((char *)(PRIVATE->data))[offset]), max_size);
@@ -271,6 +275,7 @@ int PISharedMemory::write(const void * data, int max_size) {
int PISharedMemory::write(const void * data, int max_size, int offset) {
if (offset < 0 || max_size < 0 || offset > dsize - max_size) return -1;
#ifdef WINDOWS
if (!PRIVATE->data) return -1;
CopyMemory(&(((char *)(PRIVATE->data))[offset]), data, max_size);
+6
View File
@@ -106,18 +106,24 @@ bool PISPI::openDevice() {
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MODE, &spi_mode);
if (ret == -1) {
piCoutObj << "can't set spi write mode";
::close(PRIVATE->fd);
PRIVATE->fd = -1;
return false;
}
// piCoutObj << "set bits" << spi_bits;
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits);
if (ret == -1) {
piCoutObj << "can't set bits per word";
::close(PRIVATE->fd);
PRIVATE->fd = -1;
return false;
}
// piCoutObj << "set speed" << spi_speed;
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
if (ret == -1) {
piCoutObj << "can't set max write speed hz";
::close(PRIVATE->fd);
PRIVATE->fd = -1;
return false;
}
piCoutObj << "SPI open" << path() << "speed:" << spi_speed / 1000 << "KHz"
+63 -64
View File
@@ -133,6 +133,67 @@ void PIBaseTransfer::received(PIByteArray data) {
}
mutex_header.unlock();
break;
case pt_Start:
mutex_header.lock();
if (is_pause && (is_sending || is_receiving)) {
if (header.session_id == h.session_id) {
is_pause = false;
mutex_header.unlock();
resumed();
return;
}
}
if (is_sending && header.session_id != h.session_id) {
sendBreak(h.session_id);
mutex_header.unlock();
return;
}
if (is_receiving) {
if (header.session_id != h.session_id) {
piCoutObj << "restart receive"_tr("PIBaseTransfer");
mutex_header.unlock();
finish_receive(false, true);
} else {
header.id = 0;
sendReply(pt_ReplySuccess);
mutex_header.unlock();
return;
}
}
mutex_header.unlock();
if (data.size() == sizeof(StartRequest)) {
StartRequest sr;
data >> sr;
mutex_header.lock();
mutex_session.lock();
bytes_cur = 0;
state_string = "start request";
bytes_all = sr.size;
header.session_id = h.session_id;
header.id = 0;
packets_count = 10;
session.clear();
replies.clear();
session.resize(sr.packets);
replies.resize(sr.packets + 1);
replies.fill(pt_Unknown);
pm_string.resize(replies.size(), '-');
diag.reset();
is_receiving = true;
break_ = false;
mutex_send.lock();
send_queue = 0;
mutex_send.unlock();
beginReceive();
receiveStarted();
state_string = "receiving";
replies[0] = pt_ReplySuccess;
pm_string[0] = '#';
mutex_session.unlock();
sendReply(pt_ReplySuccess);
mutex_header.unlock();
}
break;
case pt_ReplySuccess:
case pt_ReplyInvalid:
mutex_header.lock();
@@ -199,68 +260,6 @@ void PIBaseTransfer::received(PIByteArray data) {
return;
}
break;
case pt_Start:
mutex_header.lock();
if (is_pause && (is_sending || is_receiving)) {
if (header.session_id == h.session_id) {
is_pause = false;
mutex_header.unlock();
resumed();
return;
}
}
if (is_sending && header.session_id != h.session_id) {
sendBreak(h.session_id);
mutex_header.unlock();
return;
}
if (is_receiving) {
if (header.session_id != h.session_id) {
piCoutObj << "restart receive"_tr("PIBaseTransfer");
mutex_header.unlock();
finish_receive(false, true);
} else {
header.id = 0;
sendReply(pt_ReplySuccess);
mutex_header.unlock();
return;
}
}
mutex_header.unlock();
if (data.size() == sizeof(StartRequest)) {
StartRequest sr;
data >> sr;
mutex_session.lock();
mutex_header.lock();
bytes_cur = 0;
state_string = "start request";
bytes_all = sr.size;
header.session_id = h.session_id;
header.id = 0;
packets_count = 10;
session.clear();
replies.clear();
session.resize(sr.packets);
replies.resize(sr.packets + 1);
replies.fill(pt_Unknown);
pm_string.resize(replies.size(), '-');
diag.reset();
// piCoutObj << "receiveStarted()";
is_receiving = true;
break_ = false;
mutex_send.lock();
send_queue = 0;
mutex_send.unlock();
beginReceive();
receiveStarted();
state_string = "receiving";
replies[0] = pt_ReplySuccess;
pm_string[0] = '#';
mutex_session.unlock();
sendReply(pt_ReplySuccess);
mutex_header.unlock();
}
break;
case pt_Pause:
mutex_header.lock();
if (header.session_id == h.session_id) {
@@ -424,8 +423,8 @@ int PIBaseTransfer::checkSession() {
void PIBaseTransfer::buildSession(PIVector<Part> parts) {
mutex_session.lock();
mutex_header.lock();
mutex_session.lock();
state_string = "calculating parts ... ";
session.clear();
header.session_id = randomi();
@@ -478,8 +477,8 @@ void PIBaseTransfer::buildSession(PIVector<Part> parts) {
}
}
if (cur_size > min_size) session << lfi;
mutex_header.unlock();
mutex_session.unlock();
mutex_header.unlock();
}
+3 -1
View File
@@ -28,6 +28,8 @@
#include "picrc.h"
#include "pidiagnostics.h"
#include <atomic>
//! \~\ingroup IO-Utils
//! \~\brief
@@ -301,7 +303,7 @@ protected:
bool send_process();
uint packet_header_size, part_header_size;
bool break_, is_sending, is_receiving, is_pause;
std::atomic<bool> break_{true}, is_sending{false}, is_receiving{false}, is_pause{false};
PIString state_string;
llong bytes_all, bytes_cur;
+20 -5
View File
@@ -572,6 +572,8 @@ bool PIConnection::removeFilter(const PIString & name_) {
void PIConnection::removeAllFilters() {
PIVector<Extractor *> to_delete;
PIVector<PIDiagnostics *> diags_to_delete;
__device_pool__->lock();
for (auto i = extractors.begin(); i != extractors.end(); i++) {
if (!i.value()) continue;
@@ -581,14 +583,18 @@ void PIConnection::removeAllFilters() {
it.value().removeAll(i.value()->extractor);
}
if (diags_.value(i.value()->extractor)) {
delete diags_.value(i.value()->extractor);
}
diags_to_delete << diags_.value(i.value()->extractor);
diags_.remove(i.value()->extractor);
delete i.value();
}
to_delete << i.value();
}
extractors.clear();
bounded_extractors.clear();
__device_pool__->unlock();
for (auto e: to_delete)
delete e;
for (auto d: diags_to_delete)
delete d;
}
@@ -994,6 +1000,7 @@ PIIODevice * PIConnection::DevicePool::addDevice(PIConnection * parent, const PI
if (pmode == mode || pmode == PIIODevice::ReadWrite) return dd->dev;
if ((mode & PIIODevice::ReadOnly) > 0) {
if (dd->rthread) {
dd->rthread->stopAndWait();
delete dd->rthread;
dd->rthread = nullptr;
dd->started = false;
@@ -1133,10 +1140,13 @@ PIConnection::DevicePool::DeviceData::~DeviceData() {
void PIConnection::DevicePool::run() {
PIVector<PIConnection *> conns(PIConnection::allConnections());
for (PIConnection * c: conns) {
if (!c) continue;
__device_pool__->lock();
for (auto d = c->diags_.begin(); d != c->diags_.end(); d++) {
if (!d.value()) continue;
d.value()->tick(1);
}
__device_pool__->unlock();
}
}
@@ -1228,8 +1238,13 @@ void PIConnection::Sender::tick(int) {
// piCoutObj << "write"<<data.size()<<"bytes to"<<devices.size()<<"devices";
for (PIIODevice * d: devices) {
int ret = d->write(data);
PIDiagnostics * diag = parent->diags_.value(d, nullptr);
if (diag && ret > 0) diag->sended(ret);
if (ret > 0) {
PIDiagnostics * diag = nullptr;
__device_pool__->lock();
diag = parent->diags_.value(d, nullptr);
__device_pool__->unlock();
if (diag) diag->sended(ret);
}
}
}
+4
View File
@@ -41,6 +41,10 @@ public:
//! \~russian Создает объект Lua-программы и открывает стандартные библиотеки Lua.
PILuaProgram();
//! \~english Closes the Lua state and releases all associated resources.
//! \~russian Закрывает Lua state и освобождает все связанные ресурсы.
~PILuaProgram();
//! \~english Loads and executes Lua source code from \a script.
//! \~russian Загружает и выполняет исходный код Lua из \a script.
bool load(const PIString & script);
+10 -1
View File
@@ -242,7 +242,16 @@ PRIVATE_DEFINITION_START(PIProcess)
BOOL ok = WriteFile(pipes[StdIn][PipeWrite], data.data(), data.size(), &sz, NULL);
if (!ok) sz = 0;
# else
sz = ::write(pipes[StdIn][PipeWrite], data.data(), data.size());
size_t offset = 0;
while (offset < data.size()) {
ssize_t wr = ::write(pipes[StdIn][PipeWrite], data.data() + offset, data.size() - offset);
if (wr < 0) {
if (errno == EINTR) continue;
return false;
}
offset += wr;
}
sz = offset;
# endif
return sz == (SizeType)data.size_s();
}
+1 -1
View File
@@ -177,7 +177,7 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
l_df.pop_front();
for (const auto & s: l_df) {
PIStringList ml(s.replacedAll(" ", " ").split(" "));
if (ml.size_s() < 2) continue;
if (ml.size_s() < 3) continue;
if (ml.front() == "none") continue;
m.space_all = ml[1].toULLong();
m.space_used = ml[2].toULLong();
+10 -8
View File
@@ -135,17 +135,19 @@ bool PIConditionVariable::waitFor(PIMutex & lk, PISystemTime timeout, std::funct
if (condition()) break;
bool isTimeout;
#if defined(WINDOWS)
isTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle,
(PCRITICAL_SECTION)lk.handle(),
timeout.toMilliseconds() - (int)measurer.elapsed_m()) == 0;
{
int remain = (int)(timeout.toMilliseconds() - (int)measurer.elapsed_m());
if (remain <= 0) return false;
isTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), remain) == 0;
}
#elif defined(FREERTOS)
{
int remain = (int)(timeout.toMilliseconds() - (int)measurer.elapsed_m());
if (remain <= 0) return false;
EventBits_t uxBits;
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle,
1,
pdTRUE,
pdTRUE,
(timeout.toMilliseconds() - (int)measurer.elapsed_m()) / portTICK_PERIOD_MS);
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, remain / portTICK_PERIOD_MS);
isTimeout = (uxBits & 1) == 0;
}
#else
isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t *)lk.handle(), &expire_ts) != 0;
#endif
-1
View File
@@ -1080,7 +1080,6 @@ bool PIThread::_waitForFinish(PISystemTime max_tm) {
if (!running_) return true;
#ifdef WINDOWS
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
#endif
+4 -1
View File
@@ -173,7 +173,10 @@ public:
//! \~english Remove one bit from the end of array.
//! \~russian Удаляет один бит с конца массива.
PIBitArray & pop_back() { return resize(size_ - 1); }
PIBitArray & pop_back() {
if (size_ == 0) return *this;
return resize(size_ - 1);
}
//! \~english Remove one bit from the beginning of array.
//! \~russian Удаляет один бит с начала массива.
+2 -1
View File
@@ -198,10 +198,11 @@ PIByteArray PIByteArray::fromBase64(const PIByteArray & base64) {
base64HelpStruct hs;
PIByteArray ret;
const int sz = base64.size_s();
if (sz < 4) return PIByteArray();
int ind = -1;
uchar t[4];
ret.resize(sz / 4 * 3);
for (int i = 0; i < sz; i += 4) {
for (int i = 0; i < sz / 4 * 4; i += 4) {
hs.setAscii(base64.data(i));
hs.getBytes(t);
ret[++ind] = (t[0]);
+3 -3
View File
@@ -133,15 +133,15 @@ void PIVariant::setValueFromString(const PIString & v) {
case PIVariant::pivComplexf: {
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
setValue(complexf(sl.size() > 0 ? sl[0].toFloat() : 0.f, sl.size() > 1 ? sl[1].toFloat() : 0.f));
}
} break;
case PIVariant::pivComplexd: {
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
setValue(complexd(sl.size() > 0 ? sl[0].toDouble() : 0., sl.size() > 1 ? sl[1].toDouble() : 0.));
}
} break;
case PIVariant::pivComplexld: {
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
setValue(complexld(sl.size() > 0 ? sl[0].toLDouble() : 0.L, sl.size() > 1 ? sl[1].toLDouble() : 0.L));
}
} break;
case PIVariant::pivTime: {
setValue(PITime::fromString(v));
} break;
+1
View File
@@ -213,6 +213,7 @@ PIOpenCL::Context * PIOpenCL::Context::create(const PIOpenCL::DeviceList & dl) {
if (ret != 0) {
piCout << "[PIOpenCL::Context]"
<< "clCreateCommandQueue error" << ret;
clReleaseContext(con);
return 0;
}
piCout << "create done for" << dl[0].name;
+5 -4
View File
@@ -239,7 +239,7 @@ bool PIUSB::openDevice() {
for (int i = 0; i < dc.bNumInterfaces; ++i) {
conf.interfaces << Interface();
Interface & infc(conf.interfaces.back());
struct usb_interface_descriptor * di(dc.interface[c].altsetting);
struct usb_interface_descriptor * di(dc.interface[i].altsetting);
infc.index = i;
infc.value_to_select = di->bAlternateSetting;
infc.class_code = di->bInterfaceClass;
@@ -320,7 +320,7 @@ bool PIUSB::openDevice() {
bool PIUSB::closeDevice() {
#ifdef PIP_USB
if (hdev == 0) return true;
usb_release_interface(hdev, intefrace_);
if (interface_claimed >= 0) usb_release_interface(hdev, interface_claimed);
usb_close(hdev);
hdev = 0;
interface_claimed = -1;
@@ -340,6 +340,7 @@ ssize_t PIUSB::readDevice(void * read_to, ssize_t max_size) {
case Endpoint::Bulk:
/*piCoutObj << "bulk read" << max_size;*/
ret = usb_bulk_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
break;
case Endpoint::Interrupt: ret = usb_interrupt_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
default: break;
}
@@ -354,11 +355,11 @@ ssize_t PIUSB::readDevice(void * read_to, ssize_t max_size) {
ssize_t PIUSB::writeDevice(const void * data, ssize_t max_size) {
#ifdef PIP_USB
if (isClosed() || ep_write.isNull()) return -1;
switch (ep_read.transfer_type) {
switch (ep_write.transfer_type) {
case Endpoint::Bulk:
/*piCoutObj << "bulk write" << max_size;*/
return usb_bulk_write(hdev, ep_write.address, (char *)const_cast<void *>(data), max_size, timeout_w);
case Endpoint::Interrupt: return usb_interrupt_write(hdev, ep_read.address, (char *)data, max_size, timeout_w);
case Endpoint::Interrupt: return usb_interrupt_write(hdev, ep_write.address, (char *)data, max_size, timeout_w);
default: break;
}
return -1;
+35
View File
@@ -0,0 +1,35 @@
#include "pisharedmemory.h"
#include "gtest/gtest.h"
#ifdef WINDOWS
# include <process.h>
#else
# include <unistd.h>
#endif
TEST(PISharedMemory_Test, ReadWriteBounds) {
PISharedMemory shm("pip_bughunt_shm_bounds_" + PIString::fromNumber(int(getpid())), 64);
ASSERT_TRUE(shm.open());
const char payload[32] = "0123456789abcdef";
ASSERT_EQ(32, shm.write(payload, 32));
ASSERT_EQ(16, shm.write(payload, 16, 10));
// Out-of-bounds writes must be rejected, not silently overflow the mapping.
EXPECT_EQ(-1, shm.write(payload, 100)); // exceeds size
EXPECT_EQ(-1, shm.write(payload, 32, 97)); // offset + size exceeds size
EXPECT_EQ(-1, shm.write(payload, 16, -5)); // negative offset
// Out-of-bounds reads must be rejected.
char dst[128];
EXPECT_EQ(-1, shm.read(dst, 200)); // exceeds size
EXPECT_EQ(-1, shm.read(dst, 32, 97)); // offset + size exceeds size
EXPECT_EQ(-1, shm.read(dst, 32, -1));
// In-bounds reads must still succeed.
EXPECT_EQ(16, shm.read(dst, 16, 10));
ASSERT_EQ(0, memcmp(dst, "0123456789abcdef", 16));
ASSERT_TRUE(shm.close());
}