diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index be9c61d15..0bec1734e 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -90,32 +90,35 @@ public: private: // TODO: how to log file name in error? - void writeToPipe(PipeSignal type, const std::string &data) const + void writeToPipeInternal(PipeSignal type, const void* data, std::size_t to_write) const { - unsigned int len = static_cast(data.length() + 1); - char *out = new char[len + 1 + sizeof(len)]; - out[0] = static_cast(type); - std::memcpy(&(out[1]), &len, sizeof(len)); - std::memcpy(&(out[1+sizeof(len)]), data.c_str(), len); - - std::size_t bytes_to_write = len + 1 + sizeof(len); - ssize_t bytes_written = write(mWpipe, out, len + 1 + sizeof(len)); + const ssize_t bytes_written = write(mWpipe, data, to_write); if (bytes_written <= 0) { const int err = errno; - delete[] out; - out = nullptr; - std::cerr << "#### ThreadExecutor::writeToPipe() error for type " << type << ": " << std::strerror(err) << std::endl; + std::cerr << "#### ThreadExecutor::writeToPipeInternal() error for type " << type << ": " << std::strerror(err) << std::endl; std::exit(EXIT_FAILURE); } // TODO: write until everything is written - if (bytes_written != bytes_to_write) { - delete[] out; - out = nullptr; - std::cerr << "#### ThreadExecutor::writeToPipe() error for type " << type << ": insufficient data written (expected: " << bytes_to_write << " / got: " << bytes_written << ")" << std::endl; + if (bytes_written != to_write) { + std::cerr << "#### ThreadExecutor::writeToPipeInternal() error for type " << type << ": insufficient data written (expected: " << to_write << " / got: " << bytes_written << ")" << std::endl; std::exit(EXIT_FAILURE); } + } - delete[] out; + void writeToPipe(PipeSignal type, const std::string &data) const + { + { + const char t = static_cast(type); + writeToPipeInternal(type, &t, 1); + } + + const unsigned int len = static_cast(data.length() + 1); + { + static constexpr std::size_t l_size = sizeof(unsigned int); + writeToPipeInternal(type, &len, l_size); + } + + writeToPipeInternal(type, data.c_str(), len); } const int mWpipe; @@ -164,8 +167,8 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str // Don't rely on incoming data being null-terminated. // Allocate +1 element and null-terminate the buffer. - char *buf = new char[len + 1]; - char *data_start = buf; + std::string buf(len + 1, '\0'); + char *data_start = &buf[0]; bytes_to_read = len; do { bytes_read = read(rpipe, data_start, bytes_to_read); @@ -177,13 +180,14 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str bytes_to_read -= bytes_read; data_start += bytes_read; } while (bytes_to_read != 0); - buf[len] = 0; + buf[len] = '\0'; bool res = true; if (type == PipeWriter::REPORT_OUT) { // the first character is the color const Color c = static_cast(buf[0]); - mErrorLogger.reportOut(buf + 1, c); + // TODO: avoid string copy + mErrorLogger.reportOut(buf.substr(1), c); } else if (type == PipeWriter::REPORT_ERROR) { ErrorMessage msg; try { @@ -200,7 +204,6 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str res = false; } - delete[] buf; return res; } diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 08ac7fbae..b9cd3f510 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -227,35 +227,50 @@ Suppressions::ErrorMessage ErrorMessage::toSuppressionsErrorMessage() const return ret; } +static void serializeString(std::string &oss, const std::string & str) +{ + oss += std::to_string(str.length()); + oss += " "; + oss += str; +} std::string ErrorMessage::serialize() const { // Serialize this message into a simple string - std::ostringstream oss; - oss << id.length() << " " << id; - oss << Severity::toString(severity).length() << " " << Severity::toString(severity); - oss << MathLib::toString(cwe.id).length() << " " << MathLib::toString(cwe.id); - oss << MathLib::toString(hash).length() << " " << MathLib::toString(hash); - oss << file0.size() << " " << file0; + std::string oss; + serializeString(oss, id); + serializeString(oss, Severity::toString(severity)); + serializeString(oss, MathLib::toString(cwe.id)); + serializeString(oss, MathLib::toString(hash)); + serializeString(oss, file0); if (certainty == Certainty::inconclusive) { const std::string text("inconclusive"); - oss << text.length() << " " << text; + serializeString(oss, text); } const std::string saneShortMessage = fixInvalidChars(mShortMessage); const std::string saneVerboseMessage = fixInvalidChars(mVerboseMessage); - oss << saneShortMessage.length() << " " << saneShortMessage; - oss << saneVerboseMessage.length() << " " << saneVerboseMessage; - oss << callStack.size() << " "; + serializeString(oss, saneShortMessage); + serializeString(oss, saneVerboseMessage); + oss += std::to_string(callStack.size()); + oss += " "; for (std::list::const_iterator loc = callStack.cbegin(); loc != callStack.cend(); ++loc) { - std::ostringstream smallStream; - smallStream << (*loc).line << '\t' << (*loc).column << '\t' << (*loc).getfile(false) << '\t' << loc->getOrigFile(false) << '\t' << loc->getinfo(); - oss << smallStream.str().length() << " " << smallStream.str(); + std::string frame; + frame += std::to_string((*loc).line); + frame += '\t'; + frame += std::to_string((*loc).column); + frame += '\t'; + frame += (*loc).getfile(false); + frame += '\t'; + frame += loc->getOrigFile(false); + frame += '\t'; + frame += loc->getinfo(); + serializeString(oss, frame); } - return oss.str(); + return oss; } void ErrorMessage::deserialize(const std::string &data)