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()) { if (buff.isEmpty()) {
sz = 0; sz = 0;
} else { } else {
sz = piMini(max_size, buff.size()); sz = piMin<ssize_t>(max_size, buff.size_s());
memcpy(read_to, buff.data(), sz); memcpy(read_to, buff.data(), sz);
buff.remove(0, sz); buff.remove(0, sz);
} }
+1 -1
View File
@@ -68,7 +68,7 @@ PIByteArray piDecompress(const PIByteArray & zba) {
ba.resize(sz); ba.resize(sz);
int ret = 0; int ret = 0;
ulong s = sz; 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) { if (ret != Z_OK) {
piCout << "[PICompress]" piCout << "[PICompress]"
<< "Error: invalid input or not enought memory"_tr("PICompress"); << "Error: invalid input or not enought memory"_tr("PICompress");
+4 -4
View File
@@ -20,6 +20,7 @@
#include "picrypt.h" #include "picrypt.h"
#include "pitranslator.h" #include "pitranslator.h"
#include <sodium.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); key_ = hash(secret);
return key_.isNotEmpty(); 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) { bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, const PIByteArray & public_key) {
if (!init()) return false; if (!init()) return false;
return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0); 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(); return PIByteArray();
} }
PIByteArray n; PIByteArray n;
n.resize(crypto_secretbox_NONCEBYTES); n.resize(crypto_box_NONCEBYTES);
const ullong data_size = crypt_data.size() - n.size(); const ullong data_size = crypt_data.size() - n.size();
PIByteArray ret; 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()); 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) { if (crypto_box_open_easy(ret.data(), crypt_data.data(), data_size, n.data(), public_key.data(), secret_key.data()) != 0) {
// Bad key // Bad key
+5
View File
@@ -92,5 +92,10 @@ void CurlThreadPool::destroy() {
for (auto c: *cr) for (auto c: *cr)
delete c; delete c;
} }
{
auto cr = clients_in_proc.getRef();
for (auto c: *cr)
delete c;
}
// piCout << "~CurlThreadPool ok"; // piCout << "~CurlThreadPool ok";
} }
+1
View File
@@ -73,6 +73,7 @@ void PIStreamPacker::send(const PIByteArray & data) {
} else } else
hdr << int(cd.size_s()); hdr << int(cd.size_s());
cd.insert(0, hdr); cd.insert(0, hdr);
if (max_packet_size <= 0) return;
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0; int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0;
for (int i = 0; i < pcnt; ++i) { for (int i = 0; i < pcnt; ++i) {
if (i == pcnt - 1) 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) { bool PILuaProgram::load(const PIString & script) {
int ret = luaL_dostring(PRIVATE->lua_state, script.dataUTF8()); int ret = luaL_dostring(PRIVATE->lua_state, script.dataUTF8());
if (ret != 0) return false; if (ret != 0) return false;
+2 -2
View File
@@ -270,8 +270,8 @@ PIInit::~PIInit() {
mach_port_deallocate(mach_task_self(), __pi_mac_clock); mach_port_deallocate(mach_task_self(), __pi_mac_clock);
# endif # endif
if (PRIVATE->delete_locs) { if (PRIVATE->delete_locs) {
if (__syslocname__) delete __syslocname__; if (__syslocname__) delete[] __syslocname__;
if (__sysoemname__) delete __sysoemname__; if (__sysoemname__) delete[] __sysoemname__;
} }
# ifdef PIP_ICU # ifdef PIP_ICU
u_cleanup(); u_cleanup();
+3 -2
View File
@@ -73,7 +73,8 @@ bool PICAN::openDevice() {
} }
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK); fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
ifreq ifr; 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..."; piCout << "PICAN try to get interface index...";
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) { if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
piCoutObj << "Error! while determin the interface ioctl"; 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 #ifdef PIP_CAN
if (sock == -1) return -1; if (sock == -1) return -1;
// piCout << "PICAN read"; // piCout << "PICAN read";
can_frame frame; can_frame frame = {};
ssize_t ret = 0; ssize_t ret = 0;
if (PRIVATE->event.wait(sock)) ret = ::read(sock, &frame, sizeof(can_frame)); if (PRIVATE->event.wait(sock)) ret = ::read(sock, &frame, sizeof(can_frame));
if (ret < 0) { /*piCoutObj << "Error while read CAN frame " << ret;*/ 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); closedir(dir);
} }
# else # else
dirent ** list; dirent ** list = nullptr;
int cnt = scandir(p.data(), int cnt = scandir(p.data(),
&list, &list,
0, 0,
@@ -381,6 +381,7 @@ PIVector<PIFile::FileInfo> PIDir::entries(const PIRegularExpression & regexp) {
# else # else
versionsort); versionsort);
# endif # endif
if (cnt < 0) return ret;
for (int i = 0; i < cnt; ++i) { for (int i = 0; i < cnt; ++i) {
ret << PIFile::fileInfo(dp + PIString(list[i]->d_name)); ret << PIFile::fileInfo(dp + PIString(list[i]->d_name));
free(list[i]); free(list[i]);
+5 -3
View File
@@ -1206,8 +1206,10 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
strcpy(ir.ifr_name, in.dataAscii()); 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, 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, SIOCGIFADDR, &ir) >= 0) ci.address = getSockAddr(&ir.ifr_addr);
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0) ci.netmask = getSockAddr(&ir.ifr_addr); if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0) ci.netmask = getSockAddr(&ir.ifr_netmask);
ioctl(s, SIOCGIFMTU, &ci.mtu); if (ioctl(s, SIOCGIFMTU, &ir) == 0) {
ci.mtu = ir.ifr_mtu;
}
if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback; if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback;
il << ci; il << ci;
} }
@@ -1301,7 +1303,7 @@ PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) {
#else #else
struct ifreq ifr; struct ifreq ifr;
piZeroMemory(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); int s = ::socket(AF_INET, SOCK_DGRAM, 0);
if (s != -1) { if (s != -1) {
ioctl(s, SIOCGIFADDR, &ifr); ioctl(s, SIOCGIFADDR, &ifr);
+5
View File
@@ -1292,6 +1292,11 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
if (!rok) { if (!rok) {
ret.remove(i); ret.remove(i);
--i; --i;
#ifdef WINDOWS
CloseHandle(hComm);
#else
::close(fd);
#endif
continue; continue;
} }
#ifdef WINDOWS #ifdef WINDOWS
+5
View File
@@ -144,6 +144,9 @@ bool PISharedMemory::openDevice() {
::close(fd); ::close(fd);
if (PRIVATE->data == MAP_FAILED) { if (PRIVATE->data == MAP_FAILED) {
piCoutObj << "mmap error," << errorString(); piCoutObj << "mmap error," << errorString();
if (PRIVATE->owner) shm_unlink((const char *)PRIVATE->name.data());
PRIVATE->data = nullptr;
PRIVATE->owner = false;
return false; return false;
} }
// piCoutObj << "opened" << PRIVATE->data; // 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) { 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 #ifdef WINDOWS
if (!PRIVATE->data) return -1; if (!PRIVATE->data) return -1;
CopyMemory(read_to, &(((char *)(PRIVATE->data))[offset]), max_size); 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) { 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 #ifdef WINDOWS
if (!PRIVATE->data) return -1; if (!PRIVATE->data) return -1;
CopyMemory(&(((char *)(PRIVATE->data))[offset]), data, max_size); 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); ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MODE, &spi_mode);
if (ret == -1) { if (ret == -1) {
piCoutObj << "can't set spi write mode"; piCoutObj << "can't set spi write mode";
::close(PRIVATE->fd);
PRIVATE->fd = -1;
return false; return false;
} }
// piCoutObj << "set bits" << spi_bits; // piCoutObj << "set bits" << spi_bits;
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits); ret = ioctl(PRIVATE->fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits);
if (ret == -1) { if (ret == -1) {
piCoutObj << "can't set bits per word"; piCoutObj << "can't set bits per word";
::close(PRIVATE->fd);
PRIVATE->fd = -1;
return false; return false;
} }
// piCoutObj << "set speed" << spi_speed; // piCoutObj << "set speed" << spi_speed;
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed); ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
if (ret == -1) { if (ret == -1) {
piCoutObj << "can't set max write speed hz"; piCoutObj << "can't set max write speed hz";
::close(PRIVATE->fd);
PRIVATE->fd = -1;
return false; return false;
} }
piCoutObj << "SPI open" << path() << "speed:" << spi_speed / 1000 << "KHz" 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(); mutex_header.unlock();
break; 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_ReplySuccess:
case pt_ReplyInvalid: case pt_ReplyInvalid:
mutex_header.lock(); mutex_header.lock();
@@ -199,68 +260,6 @@ void PIBaseTransfer::received(PIByteArray data) {
return; return;
} }
break; 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: case pt_Pause:
mutex_header.lock(); mutex_header.lock();
if (header.session_id == h.session_id) { if (header.session_id == h.session_id) {
@@ -424,8 +423,8 @@ int PIBaseTransfer::checkSession() {
void PIBaseTransfer::buildSession(PIVector<Part> parts) { void PIBaseTransfer::buildSession(PIVector<Part> parts) {
mutex_session.lock();
mutex_header.lock(); mutex_header.lock();
mutex_session.lock();
state_string = "calculating parts ... "; state_string = "calculating parts ... ";
session.clear(); session.clear();
header.session_id = randomi(); header.session_id = randomi();
@@ -478,8 +477,8 @@ void PIBaseTransfer::buildSession(PIVector<Part> parts) {
} }
} }
if (cur_size > min_size) session << lfi; if (cur_size > min_size) session << lfi;
mutex_header.unlock();
mutex_session.unlock(); mutex_session.unlock();
mutex_header.unlock();
} }
+3 -1
View File
@@ -28,6 +28,8 @@
#include "picrc.h" #include "picrc.h"
#include "pidiagnostics.h" #include "pidiagnostics.h"
#include <atomic>
//! \~\ingroup IO-Utils //! \~\ingroup IO-Utils
//! \~\brief //! \~\brief
@@ -301,7 +303,7 @@ protected:
bool send_process(); bool send_process();
uint packet_header_size, part_header_size; 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; PIString state_string;
llong bytes_all, bytes_cur; llong bytes_all, bytes_cur;
+20 -5
View File
@@ -572,6 +572,8 @@ bool PIConnection::removeFilter(const PIString & name_) {
void PIConnection::removeAllFilters() { void PIConnection::removeAllFilters() {
PIVector<Extractor *> to_delete;
PIVector<PIDiagnostics *> diags_to_delete;
__device_pool__->lock(); __device_pool__->lock();
for (auto i = extractors.begin(); i != extractors.end(); i++) { for (auto i = extractors.begin(); i != extractors.end(); i++) {
if (!i.value()) continue; if (!i.value()) continue;
@@ -581,14 +583,18 @@ void PIConnection::removeAllFilters() {
it.value().removeAll(i.value()->extractor); it.value().removeAll(i.value()->extractor);
} }
if (diags_.value(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); diags_.remove(i.value()->extractor);
delete i.value(); }
to_delete << i.value();
} }
extractors.clear(); extractors.clear();
bounded_extractors.clear(); bounded_extractors.clear();
__device_pool__->unlock(); __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 (pmode == mode || pmode == PIIODevice::ReadWrite) return dd->dev;
if ((mode & PIIODevice::ReadOnly) > 0) { if ((mode & PIIODevice::ReadOnly) > 0) {
if (dd->rthread) { if (dd->rthread) {
dd->rthread->stopAndWait();
delete dd->rthread; delete dd->rthread;
dd->rthread = nullptr; dd->rthread = nullptr;
dd->started = false; dd->started = false;
@@ -1133,10 +1140,13 @@ PIConnection::DevicePool::DeviceData::~DeviceData() {
void PIConnection::DevicePool::run() { void PIConnection::DevicePool::run() {
PIVector<PIConnection *> conns(PIConnection::allConnections()); PIVector<PIConnection *> conns(PIConnection::allConnections());
for (PIConnection * c: conns) { for (PIConnection * c: conns) {
if (!c) continue;
__device_pool__->lock();
for (auto d = c->diags_.begin(); d != c->diags_.end(); d++) { for (auto d = c->diags_.begin(); d != c->diags_.end(); d++) {
if (!d.value()) continue; if (!d.value()) continue;
d.value()->tick(1); 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"; // piCoutObj << "write"<<data.size()<<"bytes to"<<devices.size()<<"devices";
for (PIIODevice * d: devices) { for (PIIODevice * d: devices) {
int ret = d->write(data); int ret = d->write(data);
PIDiagnostics * diag = parent->diags_.value(d, nullptr); if (ret > 0) {
if (diag && ret > 0) diag->sended(ret); 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. //! \~russian Создает объект Lua-программы и открывает стандартные библиотеки Lua.
PILuaProgram(); 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. //! \~english Loads and executes Lua source code from \a script.
//! \~russian Загружает и выполняет исходный код Lua из \a script. //! \~russian Загружает и выполняет исходный код Lua из \a script.
bool load(const PIString & 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); BOOL ok = WriteFile(pipes[StdIn][PipeWrite], data.data(), data.size(), &sz, NULL);
if (!ok) sz = 0; if (!ok) sz = 0;
# else # 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 # endif
return sz == (SizeType)data.size_s(); 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(); l_df.pop_front();
for (const auto & s: l_df) { for (const auto & s: l_df) {
PIStringList ml(s.replacedAll(" ", " ").split(" ")); PIStringList ml(s.replacedAll(" ", " ").split(" "));
if (ml.size_s() < 2) continue; if (ml.size_s() < 3) continue;
if (ml.front() == "none") continue; if (ml.front() == "none") continue;
m.space_all = ml[1].toULLong(); m.space_all = ml[1].toULLong();
m.space_used = ml[2].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; if (condition()) break;
bool isTimeout; bool isTimeout;
#if defined(WINDOWS) #if defined(WINDOWS)
isTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, {
(PCRITICAL_SECTION)lk.handle(), int remain = (int)(timeout.toMilliseconds() - (int)measurer.elapsed_m());
timeout.toMilliseconds() - (int)measurer.elapsed_m()) == 0; if (remain <= 0) return false;
isTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), remain) == 0;
}
#elif defined(FREERTOS) #elif defined(FREERTOS)
{
int remain = (int)(timeout.toMilliseconds() - (int)measurer.elapsed_m());
if (remain <= 0) return false;
EventBits_t uxBits; EventBits_t uxBits;
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, remain / portTICK_PERIOD_MS);
1,
pdTRUE,
pdTRUE,
(timeout.toMilliseconds() - (int)measurer.elapsed_m()) / portTICK_PERIOD_MS);
isTimeout = (uxBits & 1) == 0; isTimeout = (uxBits & 1) == 0;
}
#else #else
isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t *)lk.handle(), &expire_ts) != 0; isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t *)lk.handle(), &expire_ts) != 0;
#endif #endif
-1
View File
@@ -1080,7 +1080,6 @@ bool PIThread::_waitForFinish(PISystemTime max_tm) {
if (!running_) return true; if (!running_) return true;
#ifdef WINDOWS #ifdef WINDOWS
if (!isExists(PRIVATE->thread)) { if (!isExists(PRIVATE->thread)) {
unlock();
return true; return true;
} }
#endif #endif
+4 -1
View File
@@ -173,7 +173,10 @@ public:
//! \~english Remove one bit from the end of array. //! \~english Remove one bit from the end of array.
//! \~russian Удаляет один бит с конца массива. //! \~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. //! \~english Remove one bit from the beginning of array.
//! \~russian Удаляет один бит с начала массива. //! \~russian Удаляет один бит с начала массива.
+2 -1
View File
@@ -198,10 +198,11 @@ PIByteArray PIByteArray::fromBase64(const PIByteArray & base64) {
base64HelpStruct hs; base64HelpStruct hs;
PIByteArray ret; PIByteArray ret;
const int sz = base64.size_s(); const int sz = base64.size_s();
if (sz < 4) return PIByteArray();
int ind = -1; int ind = -1;
uchar t[4]; uchar t[4];
ret.resize(sz / 4 * 3); 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.setAscii(base64.data(i));
hs.getBytes(t); hs.getBytes(t);
ret[++ind] = (t[0]); ret[++ind] = (t[0]);
+3 -3
View File
@@ -133,15 +133,15 @@ void PIVariant::setValueFromString(const PIString & v) {
case PIVariant::pivComplexf: { case PIVariant::pivComplexf: {
PIStringList sl = v.mid(1, v.size_s() - 2).split(';'); 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)); setValue(complexf(sl.size() > 0 ? sl[0].toFloat() : 0.f, sl.size() > 1 ? sl[1].toFloat() : 0.f));
} } break;
case PIVariant::pivComplexd: { case PIVariant::pivComplexd: {
PIStringList sl = v.mid(1, v.size_s() - 2).split(';'); 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.)); setValue(complexd(sl.size() > 0 ? sl[0].toDouble() : 0., sl.size() > 1 ? sl[1].toDouble() : 0.));
} } break;
case PIVariant::pivComplexld: { case PIVariant::pivComplexld: {
PIStringList sl = v.mid(1, v.size_s() - 2).split(';'); 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)); setValue(complexld(sl.size() > 0 ? sl[0].toLDouble() : 0.L, sl.size() > 1 ? sl[1].toLDouble() : 0.L));
} } break;
case PIVariant::pivTime: { case PIVariant::pivTime: {
setValue(PITime::fromString(v)); setValue(PITime::fromString(v));
} break; } break;
+1
View File
@@ -213,6 +213,7 @@ PIOpenCL::Context * PIOpenCL::Context::create(const PIOpenCL::DeviceList & dl) {
if (ret != 0) { if (ret != 0) {
piCout << "[PIOpenCL::Context]" piCout << "[PIOpenCL::Context]"
<< "clCreateCommandQueue error" << ret; << "clCreateCommandQueue error" << ret;
clReleaseContext(con);
return 0; return 0;
} }
piCout << "create done for" << dl[0].name; 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) { for (int i = 0; i < dc.bNumInterfaces; ++i) {
conf.interfaces << Interface(); conf.interfaces << Interface();
Interface & infc(conf.interfaces.back()); 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.index = i;
infc.value_to_select = di->bAlternateSetting; infc.value_to_select = di->bAlternateSetting;
infc.class_code = di->bInterfaceClass; infc.class_code = di->bInterfaceClass;
@@ -320,7 +320,7 @@ bool PIUSB::openDevice() {
bool PIUSB::closeDevice() { bool PIUSB::closeDevice() {
#ifdef PIP_USB #ifdef PIP_USB
if (hdev == 0) return true; if (hdev == 0) return true;
usb_release_interface(hdev, intefrace_); if (interface_claimed >= 0) usb_release_interface(hdev, interface_claimed);
usb_close(hdev); usb_close(hdev);
hdev = 0; hdev = 0;
interface_claimed = -1; interface_claimed = -1;
@@ -340,6 +340,7 @@ ssize_t PIUSB::readDevice(void * read_to, ssize_t max_size) {
case Endpoint::Bulk: case Endpoint::Bulk:
/*piCoutObj << "bulk read" << max_size;*/ /*piCoutObj << "bulk read" << max_size;*/
ret = usb_bulk_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r); 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); case Endpoint::Interrupt: ret = usb_interrupt_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
default: break; 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) { ssize_t PIUSB::writeDevice(const void * data, ssize_t max_size) {
#ifdef PIP_USB #ifdef PIP_USB
if (isClosed() || ep_write.isNull()) return -1; if (isClosed() || ep_write.isNull()) return -1;
switch (ep_read.transfer_type) { switch (ep_write.transfer_type) {
case Endpoint::Bulk: case Endpoint::Bulk:
/*piCoutObj << "bulk write" << max_size;*/ /*piCoutObj << "bulk write" << max_size;*/
return usb_bulk_write(hdev, ep_write.address, (char *)const_cast<void *>(data), max_size, timeout_w); 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; default: break;
} }
return -1; 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());
}