From dd4a3b583a0ebe61b9e87dc42304b36e6e446945 Mon Sep 17 00:00:00 2001 From: Kim Grasman Date: Wed, 13 Jul 2016 15:14:45 +0200 Subject: [PATCH 01/40] Redefine Poco assertions for static analysis Static analyzers typically don't do cross-translation unit analysis, so they don't understand that most of the Poco::Bugcheck methods never return. Unfortunately, some of them also don't understand noreturn annotations (see e.g. http://en.cppreference.com/w/cpp/language/attributes), so decorating Bugcheck doesn't help. Instead redefine all the Poco assertion macros to just call abort() iff we're parsed by a known static analyzer. --- Foundation/include/Poco/Bugcheck.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Foundation/include/Poco/Bugcheck.h b/Foundation/include/Poco/Bugcheck.h index 941676029..12f5ca252 100644 --- a/Foundation/include/Poco/Bugcheck.h +++ b/Foundation/include/Poco/Bugcheck.h @@ -81,6 +81,25 @@ protected: // // useful macros (these automatically supply line number and file name) // +#if defined(__KLOCWORK__) || defined(__clang_analyzer__) + +// Short-circuit these macros when under static analysis. +// Ideally, static analysis tools should understand and reason correctly about +// noreturn methods such as Bugcheck::bugcheck. In practice, they don't. +// Help them by turning these macros into 'abort' as described here: +// https://developer.klocwork.com/documentation/en/insight/10-1/tuning-cc-analysis#Usingthe__KLOCWORK__macro + +#include // for abort +#define poco_assert_dbg(cond) do { if (!(cond)) abort(); } while (0) +#define poco_assert_msg_dbg(cond, text) do { if (!(cond)) abort(); } while (0) +#define poco_assert(cond) do { if (!(cond)) abort(); } while (0) +#define poco_assert_msg(cond, text) do { if (!(cond)) abort(); } while (0) +#define poco_check_ptr(ptr) do { if (!(ptr)) abort(); } while (0) +#define poco_bugcheck() do { abort(); } while (0) +#define poco_bugcheck_msg(msg) do { abort(); } while (0) + +#else // defined(__KLOCWORK__) || defined(__clang_analyzer__) + #if defined(_DEBUG) #define poco_assert_dbg(cond) \ if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__); else (void) 0 @@ -112,6 +131,7 @@ protected: #define poco_bugcheck_msg(msg) \ Poco::Bugcheck::bugcheck(msg, __FILE__, __LINE__) +#endif // defined(__KLOCWORK__) || defined(__clang_analyzer__) #define poco_unexpected() \ Poco::Bugcheck::unexpected(__FILE__, __LINE__); From f62ee1466d8026b47e76a03e2ff96a7f60fbf511 Mon Sep 17 00:00:00 2001 From: zosrothko Date: Wed, 7 Sep 2016 21:27:19 +0200 Subject: [PATCH 02/40] Issue with gcc strerror_r in Net/Socket.cpp@151 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All Travis jobs fail with ```src/Socket.cpp: In static member function ‘static int Poco::Net::Socket::select(Poco::Net::Socket::SocketList&, Poco::Net::Socket::SocketList&, Poco::Net::Socket::SocketList&, const Poco::Timespan&)’: src/Socket.cpp:151:47: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive] src/Socket.cpp:164:49: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive] ``` From man strerror_r ``` int strerror_r(int errnum, char *buf, size_t buflen); /* XSI-compliant */ char *strerror_r(int errnum, char *buf, size_t bufle); /* GNU-specific */ Feature Test Macro Requirements for glibc (see feature_test_macros(7)): The XSI-compliant version of strerror_r() is provided if: (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE Otherwise, the GNU-specific version is provided. ``` --- build/config/Linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/config/Linux b/build/config/Linux index 39bdc8e81..40ef8f059 100644 --- a/build/config/Linux +++ b/build/config/Linux @@ -69,7 +69,7 @@ RELEASEOPT_LINK = -O2 # # System Specific Flags # -SYSFLAGS = -D_XOPEN_SOURCE=500 -D_REENTRANT -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DPOCO_HAVE_FD_EPOLL -DPOCO_HAVE_ADDRINFO -DPOCO_HAVE_LIBRESOLV +SYSFLAGS = -D_XOPEN_SOURCE=600 -D_REENTRANT -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DPOCO_HAVE_FD_EPOLL -DPOCO_HAVE_ADDRINFO -DPOCO_HAVE_LIBRESOLV # # System Specific Libraries From 9cb7979dc98ae9106905a8d609a31749c93fcbdb Mon Sep 17 00:00:00 2001 From: zosrothko Date: Fri, 9 Sep 2016 09:25:39 +0200 Subject: [PATCH 03/40] Fix space issue with the msbuild's logger path With ```LOGGER='"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"';``` ```if (not "%LOGGER%"==""``` evaluate to ```Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll""=="" was unexpected at this time``` --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 9f65ccd18..1a266261b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -384,7 +384,7 @@ build_script: } if ($env:builder -eq "msbuild") { - $logger='"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"'; + $logger='"C:\Progra~1\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"'; $verbosity='minimal'; $process = Start-Process -PassThru -nnw -Wait -FilePath "$env:poco_base\buildwin.cmd" -RSO cout -RSE cerr ` From eb01c3f5396a5639b51df93a7986a9504a4fb463 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Sun, 11 Sep 2016 01:40:28 +0200 Subject: [PATCH 04/40] don't include connection string in exception message --- Data/src/SessionPool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Data/src/SessionPool.cpp b/Data/src/SessionPool.cpp index 40b74d2a3..be87fb1c1 100644 --- a/Data/src/SessionPool.cpp +++ b/Data/src/SessionPool.cpp @@ -82,7 +82,7 @@ Session SessionPool::get() _idleSessions.push_front(pHolder); ++_nSessions; } - else throw SessionPoolExhaustedException(_connector, _connectionString); + else throw SessionPoolExhaustedException(_connector); } PooledSessionHolderPtr pHolder(_idleSessions.front()); From 762e1ff899aa816f75d9456af48ee3a6d69c91f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Mon, 12 Sep 2016 18:53:26 +0200 Subject: [PATCH 05/40] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d771181e7..1773923fb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,8 @@ --- If you think you've found a bug or would like to see a feature in one of the [upcoming releases](https://github.com/pocoproject/poco/milestones), file an [issue](https://github.com/pocoproject/poco/issues). Please make sure that your explanations are clear and coherent; do the homework of understanding the problem and searching for existing solutions before posting. +Possible security issues or vulnerabilities can also be reported via email directly to the core team security pocoproject.org. + If you're in a hurry, the fastest way to have bugs fixed or features added are code contributions. Good code contributions, to be precise; if you want to contribute, read on ... --- From df37d79f8848d96a990b86610e9148b987a9bc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Mon, 12 Sep 2016 18:53:58 +0200 Subject: [PATCH 06/40] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1773923fb..7fc2afa31 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ --- If you think you've found a bug or would like to see a feature in one of the [upcoming releases](https://github.com/pocoproject/poco/milestones), file an [issue](https://github.com/pocoproject/poco/issues). Please make sure that your explanations are clear and coherent; do the homework of understanding the problem and searching for existing solutions before posting. -Possible security issues or vulnerabilities can also be reported via email directly to the core team security pocoproject.org. +Possible security issues or vulnerabilities can also be reported via email directly to the core team security AT pocoproject.org. If you're in a hurry, the fastest way to have bugs fixed or features added are code contributions. Good code contributions, to be precise; if you want to contribute, read on ... From 1fa6f34882ab2799e1c2bf4a777c15ea688b0d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Mon, 12 Sep 2016 18:54:25 +0200 Subject: [PATCH 07/40] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7fc2afa31..8c9e1c3b8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Contributing --- -## Bug Reports and Feature requests +## Bug Reports and Feature Requests --- If you think you've found a bug or would like to see a feature in one of the [upcoming releases](https://github.com/pocoproject/poco/milestones), file an [issue](https://github.com/pocoproject/poco/issues). Please make sure that your explanations are clear and coherent; do the homework of understanding the problem and searching for existing solutions before posting. From 251cb4aa2c71b8f095fed15ef897c9fa3c0b60fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Mon, 12 Sep 2016 19:35:37 +0200 Subject: [PATCH 08/40] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7e67491b7..49a5eb18e 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Build Status - Travis: [![Travis Build Status](https://travis-ci.org/pocoproject/poco.png?branch=develop)](https://travis-ci.org/pocoproject/poco) - AppVeyor: [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/7iyrx3f233s3akae)](https://ci.appveyor.com/project/obiltschnig/poco) +- [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/370/badge)](https://bestpractices.coreinfrastructure.org/projects/370) ![alt text][logo] From 75a43b8723d66861ab5457e4a8e737aa80a54f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Tue, 13 Sep 2016 07:15:12 +0200 Subject: [PATCH 09/40] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8c9e1c3b8..239272ffd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ --- If you think you've found a bug or would like to see a feature in one of the [upcoming releases](https://github.com/pocoproject/poco/milestones), file an [issue](https://github.com/pocoproject/poco/issues). Please make sure that your explanations are clear and coherent; do the homework of understanding the problem and searching for existing solutions before posting. -Possible security issues or vulnerabilities can also be reported via email directly to the core team security AT pocoproject.org. +Possible security issues or vulnerabilities can also be reported via email directly to the core team security AT pocoproject.org. The core team will respond to security issues within 24 hours. If you're in a hurry, the fastest way to have bugs fixed or features added are code contributions. Good code contributions, to be precise; if you want to contribute, read on ... From dfb03273c67b617b16d0f678110fb94d08aa6bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Tue, 13 Sep 2016 07:16:40 +0200 Subject: [PATCH 10/40] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 49a5eb18e..ab7a0caaa 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ To start using POCO, see the [Guided Tour](http://pocoproject.org/docs/00100-Gui POCO has an active user and contributing community, please visit our [web site](http://pocoproject.org), [forum](http://pocoproject.org/forum) and [blog](http://pocoproject.org/blog). Answers to POCO-related questions can also be found on [Stack Overflow](http://stackoverflow.com/questions/tagged/poco-libraries). +Please see [CONTRIBUTING](CONTRIBUTING.md) for submitting bugs, feature requests or security issues. + ---- In regards to Boost, in spite of some functional overlapping, POCO is best thought of as a Boost complement (rather than replacement). From 2701c2e0ca1233b5e5f20ea94450c9acdddc6428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Tue, 13 Sep 2016 07:17:16 +0200 Subject: [PATCH 11/40] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab7a0caaa..bc13a2b4d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ To start using POCO, see the [Guided Tour](http://pocoproject.org/docs/00100-Gui POCO has an active user and contributing community, please visit our [web site](http://pocoproject.org), [forum](http://pocoproject.org/forum) and [blog](http://pocoproject.org/blog). Answers to POCO-related questions can also be found on [Stack Overflow](http://stackoverflow.com/questions/tagged/poco-libraries). -Please see [CONTRIBUTING](CONTRIBUTING.md) for submitting bugs, feature requests or security issues. +Please see [CONTRIBUTING](CONTRIBUTING.md) for submitting contributions, bugs reports, feature requests or security issues. ---- In regards to Boost, in spite of some functional overlapping, From fbbf197fd2a779c1f533ba6b71e05ac179b0fcde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Tue, 13 Sep 2016 07:45:35 +0200 Subject: [PATCH 12/40] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bc13a2b4d..90f1024d0 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,11 @@ POrtable COmponents C++ Libraries are: - Open Source, licensed under the [Boost Software License](https://spdx.org/licenses/BSL-1.0). ---- -To start using POCO, see the [Guided Tour](http://pocoproject.org/docs/00100-GuidedTour.html) and [Getting Started](http://pocoproject.org/docs/00200-GettingStarted.html) documents. +To start using POCO, see the [Guided Tour](https://pocoproject.org/docs/00100-GuidedTour.html) and [Getting Started](https://pocoproject.org/docs/00200-GettingStarted.html) documents. ---- -POCO has an active user and contributing community, please visit our [web site](http://pocoproject.org), [forum](http://pocoproject.org/forum) and [blog](http://pocoproject.org/blog). -Answers to POCO-related questions can also be found on [Stack Overflow](http://stackoverflow.com/questions/tagged/poco-libraries). +POCO has an active user and contributing community, please visit our [web site](https://pocoproject.org), [forum](https://pocoproject.org/forum) and [blog](https://pocoproject.org/blog). +Answers to POCO-related questions can also be found on [Stack Overflow](https://stackoverflow.com/questions/tagged/poco-libraries). Please see [CONTRIBUTING](CONTRIBUTING.md) for submitting contributions, bugs reports, feature requests or security issues. From ae3c4a4ba31d6d140d4dc01a4185f6f1fa4173f7 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Tue, 13 Sep 2016 11:37:12 +0200 Subject: [PATCH 13/40] fixed some warnings and minor issues detected by clang-analyzer Conflicts: Data/src/RecordSet.cpp --- Data/src/RecordSet.cpp | 6 ++---- Foundation/src/StreamCopier.cpp | 4 ++-- Net/src/HTTPResponse.cpp | 1 + Net/src/MailMessage.cpp | 5 ++++- Net/src/MultipartReader.cpp | 8 ++++---- Net/src/QuotedPrintableDecoder.cpp | 2 +- NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp | 2 +- PageCompiler/src/PageReader.cpp | 4 ++-- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Data/src/RecordSet.cpp b/Data/src/RecordSet.cpp index b630a3153..555fe2a03 100644 --- a/Data/src/RecordSet.cpp +++ b/Data/src/RecordSet.cpp @@ -256,8 +256,7 @@ bool RecordSet::moveFirst() return true; } - std::size_t currentRow = _currentRow; - currentRow = 0; + std::size_t currentRow = 0; while (!isAllowed(currentRow)) { if (currentRow >= rc - 1) return false; @@ -303,8 +302,7 @@ bool RecordSet::moveLast() { if (storageRowCount() > 0) { - std::size_t currentRow = _currentRow; - currentRow = storageRowCount() - 1; + std::size_t currentRow = subTotalRowCount() - 1; if (!isFiltered()) { _currentRow = currentRow; diff --git a/Foundation/src/StreamCopier.cpp b/Foundation/src/StreamCopier.cpp index f0c4445b1..92f923ec6 100644 --- a/Foundation/src/StreamCopier.cpp +++ b/Foundation/src/StreamCopier.cpp @@ -119,7 +119,7 @@ Poco::UInt64 StreamCopier::copyToString64(std::istream& istr, std::string& str, std::streamsize StreamCopier::copyStreamUnbuffered(std::istream& istr, std::ostream& ostr) { - char c; + char c = 0; std::streamsize len = 0; istr.get(c); while (istr && ostr) @@ -135,7 +135,7 @@ std::streamsize StreamCopier::copyStreamUnbuffered(std::istream& istr, std::ostr #if defined(POCO_HAVE_INT64) Poco::UInt64 StreamCopier::copyStreamUnbuffered64(std::istream& istr, std::ostream& ostr) { - char c; + char c = 0; Poco::UInt64 len = 0; istr.get(c); while (istr && ostr) diff --git a/Net/src/HTTPResponse.cpp b/Net/src/HTTPResponse.cpp index cf6a47b4f..8782d3cc8 100644 --- a/Net/src/HTTPResponse.cpp +++ b/Net/src/HTTPResponse.cpp @@ -242,6 +242,7 @@ void HTTPResponse::read(std::istream& istr) while (ch != '\r' && ch != '\n' && ch != eof && reason.length() < MAX_REASON_LENGTH) { reason += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("HTTP reason string too long"); if (ch == '\r') ch = istr.get(); + if (ch != '\n') throw MessageException("Unterminated HTTP response line"); HTTPMessage::read(istr); ch = istr.get(); diff --git a/Net/src/MailMessage.cpp b/Net/src/MailMessage.cpp index 69a6d88c1..54ee3c104 100644 --- a/Net/src/MailMessage.cpp +++ b/Net/src/MailMessage.cpp @@ -105,18 +105,21 @@ namespace poco_check_ptr (pPS); NameValueCollection::ConstIterator it = header.begin(); NameValueCollection::ConstIterator end = header.end(); + bool added = false; for (; it != end; ++it) { - if (MailMessage::HEADER_CONTENT_DISPOSITION == it->first) + if (!added && MailMessage::HEADER_CONTENT_DISPOSITION == it->first) { if (it->second == "inline") _pMsg->addContent(pPS, cte); else _pMsg->addAttachment("", pPS, cte); + added = true; } pPS->headers().set(it->first, it->second); } + if (!added) delete pPS; } } diff --git a/Net/src/MultipartReader.cpp b/Net/src/MultipartReader.cpp index 1ee9a98e5..d167906d3 100644 --- a/Net/src/MultipartReader.cpp +++ b/Net/src/MultipartReader.cpp @@ -88,13 +88,13 @@ int MultipartStreamBuf::readFromDevice(char* buffer, std::streamsize length) { if (ch == '\r') { - ch = buf.sbumpc(); // '\n' + buf.sbumpc(); // '\n' } return 0; } else if (ch == '-' && buf.sgetc() == '-') { - ch = buf.sbumpc(); // '-' + buf.sbumpc(); // '-' _lastPart = true; return 0; } @@ -268,7 +268,7 @@ void MultipartReader::guessBoundary() ch = _istr.peek(); } if (ch == '\r' || ch == '\n') - ch = _istr.get(); + _istr.get(); if (_istr.peek() == '\n') _istr.get(); } @@ -281,7 +281,7 @@ void MultipartReader::parseHeader(MessageHeader& messageHeader) messageHeader.clear(); messageHeader.read(_istr); int ch = _istr.get(); - if (ch == '\r' && _istr.peek() == '\n') ch = _istr.get(); + if (ch == '\r' && _istr.peek() == '\n') _istr.get(); } diff --git a/Net/src/QuotedPrintableDecoder.cpp b/Net/src/QuotedPrintableDecoder.cpp index 331d8b148..d664f63ae 100644 --- a/Net/src/QuotedPrintableDecoder.cpp +++ b/Net/src/QuotedPrintableDecoder.cpp @@ -48,7 +48,7 @@ int QuotedPrintableDecoderBuf::readFromDevice() ch = _buf.sbumpc(); if (ch == '\r') { - ch = _buf.sbumpc(); // read \n + _buf.sbumpc(); // read \n } else if (Poco::Ascii::isHexDigit(ch)) { diff --git a/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp b/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp index 40cf8ce8b..839ea13a9 100644 --- a/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp +++ b/NetSSL_OpenSSL/src/ConsoleCertificateHandler.cpp @@ -43,7 +43,7 @@ void ConsoleCertificateHandler::onInvalidCertificate(const void*, VerificationEr std::cout << "The certificate yielded the error: " << errorCert.errorMessage() << "\n\n"; std::cout << "The error occurred in the certificate chain at position " << errorCert.errorDepth() << "\n"; std::cout << "Accept the certificate (y,n)? "; - char c; + char c = 0; std::cin >> c; if (c == 'y' || c == 'Y') errorCert.setIgnoreError(true); diff --git a/PageCompiler/src/PageReader.cpp b/PageCompiler/src/PageReader.cpp index d435ca07f..02a08a110 100644 --- a/PageCompiler/src/PageReader.cpp +++ b/PageCompiler/src/PageReader.cpp @@ -267,7 +267,7 @@ void PageReader::nextToken(std::istream& istr, std::string& token) if (ch == '<' && istr.peek() == '%') { token += "<%"; - ch = istr.get(); + istr.get(); ch = istr.peek(); switch (ch) { @@ -300,7 +300,7 @@ void PageReader::nextToken(std::istream& istr, std::string& token) else if (ch == '%' && istr.peek() == '>') { token += "%>"; - ch = istr.get(); + istr.get(); } else token += (char) ch; } From dcdcee5afab6e8972f1b144ef7e7e884f85e83a3 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Wed, 14 Sep 2016 17:06:55 +0200 Subject: [PATCH 14/40] minor fixes for style --- Foundation/include/Poco/Bugcheck.h | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Foundation/include/Poco/Bugcheck.h b/Foundation/include/Poco/Bugcheck.h index 12f5ca252..06f12c24d 100644 --- a/Foundation/include/Poco/Bugcheck.h +++ b/Foundation/include/Poco/Bugcheck.h @@ -22,6 +22,7 @@ #include "Poco/Foundation.h" #include +#include #if defined(_DEBUG) # include #endif @@ -83,23 +84,26 @@ protected: // #if defined(__KLOCWORK__) || defined(__clang_analyzer__) + // Short-circuit these macros when under static analysis. // Ideally, static analysis tools should understand and reason correctly about -// noreturn methods such as Bugcheck::bugcheck. In practice, they don't. -// Help them by turning these macros into 'abort' as described here: +// noreturn methods such as Bugcheck::bugcheck(). In practice, they don't. +// Help them by turning these macros into std::abort() as described here: // https://developer.klocwork.com/documentation/en/insight/10-1/tuning-cc-analysis#Usingthe__KLOCWORK__macro #include // for abort -#define poco_assert_dbg(cond) do { if (!(cond)) abort(); } while (0) -#define poco_assert_msg_dbg(cond, text) do { if (!(cond)) abort(); } while (0) -#define poco_assert(cond) do { if (!(cond)) abort(); } while (0) -#define poco_assert_msg(cond, text) do { if (!(cond)) abort(); } while (0) -#define poco_check_ptr(ptr) do { if (!(ptr)) abort(); } while (0) -#define poco_bugcheck() do { abort(); } while (0) -#define poco_bugcheck_msg(msg) do { abort(); } while (0) +#define poco_assert_dbg(cond) do { if (!(cond)) std::abort(); } while (0) +#define poco_assert_msg_dbg(cond, text) do { if (!(cond)) std::abort(); } while (0) +#define poco_assert(cond) do { if (!(cond)) std::abort(); } while (0) +#define poco_assert_msg(cond, text) do { if (!(cond)) std::abort(); } while (0) +#define poco_check_ptr(ptr) do { if (!(ptr)) std::abort(); } while (0) +#define poco_bugcheck() do { std::abort(); } while (0) +#define poco_bugcheck_msg(msg) do { std::abort(); } while (0) + #else // defined(__KLOCWORK__) || defined(__clang_analyzer__) + #if defined(_DEBUG) #define poco_assert_dbg(cond) \ if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__); else (void) 0 @@ -131,8 +135,10 @@ protected: #define poco_bugcheck_msg(msg) \ Poco::Bugcheck::bugcheck(msg, __FILE__, __LINE__) + #endif // defined(__KLOCWORK__) || defined(__clang_analyzer__) + #define poco_unexpected() \ Poco::Bugcheck::unexpected(__FILE__, __LINE__); From e87a8fe962ec3424b73305117343a167afe79b9a Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Thu, 15 Sep 2016 12:01:30 +0200 Subject: [PATCH 15/40] handle MySQL connection lost/server gone when starting a transaction --- Data/MySQL/src/SessionHandle.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Data/MySQL/src/SessionHandle.cpp b/Data/MySQL/src/SessionHandle.cpp index 9815e4243..5af93044a 100644 --- a/Data/MySQL/src/SessionHandle.cpp +++ b/Data/MySQL/src/SessionHandle.cpp @@ -150,8 +150,17 @@ void SessionHandle::close() void SessionHandle::startTransaction() { - if (mysql_autocommit(_pHandle, false) != 0) - throw TransactionException("Start transaction failed.", _pHandle); + int rc = mysql_autocommit(_pHandle, false); + if (rc != 0) + { + // retry if connection lost + int err = mysql_errno(_pHandle); + if (err == 2006 /* CR_SERVER_GONE_ERROR */ || err == 2013 /* CR_SERVER_LOST */) + { + rc = mysql_autocommit(_pHandle, false); + } + } + if (rc != 0) throw TransactionException("Start transaction failed.", _pHandle); } From ad1be5fe87a5cc14f602f368b86dd71b080f7f7b Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Tue, 20 Sep 2016 20:48:36 +0200 Subject: [PATCH 16/40] fixed GH #1418:Poco::Delegate assignment operator fails to compile for some specializations --- Foundation/include/Poco/Delegate.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Foundation/include/Poco/Delegate.h b/Foundation/include/Poco/Delegate.h index eaed9c3e3..1a6a315e6 100644 --- a/Foundation/include/Poco/Delegate.h +++ b/Foundation/include/Poco/Delegate.h @@ -128,7 +128,6 @@ public: { if (&delegate != this) { - this->_pTarget = delegate._pTarget; this->_receiverObject = delegate._receiverObject; this->_receiverMethod = delegate._receiverMethod; } @@ -341,7 +340,6 @@ public: { if (&delegate != this) { - this->_pTarget = delegate._pTarget; this->_receiverObject = delegate._receiverObject; this->_receiverMethod = delegate._receiverMethod; } From f1b75ec44277a61e12d7b3729bdd54f21af07b1e Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Wed, 21 Sep 2016 08:31:23 +0200 Subject: [PATCH 17/40] updated .gitattributes linguist settings --- .gitattributes | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitattributes b/.gitattributes index 8c88af1d7..95c524dd0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -31,3 +31,8 @@ *.png binary *.jpg binary *.gif binary + +# Linguist overrides +.cpp linguist-language=C++ +.h linguist-language=C++ + From 68e3676ddc4e8a868e1e7dba559cba9175cba6e2 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 16:51:13 +0200 Subject: [PATCH 18/40] fixed an unlikely potential memory leak if one of two new fails --- Foundation/include/Poco/ClassLoader.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Foundation/include/Poco/ClassLoader.h b/Foundation/include/Poco/ClassLoader.h index 1dd63a7ac..d8a5682e3 100644 --- a/Foundation/include/Poco/ClassLoader.h +++ b/Foundation/include/Poco/ClassLoader.h @@ -158,11 +158,13 @@ public: if (it == _map.end()) { LibraryInfo li; - li.pLibrary = new SharedLibrary(path); - li.pManifest = new Manif(); + li.pLibrary = 0; + li.pManifest = 0; li.refCount = 1; try { + li.pLibrary = new SharedLibrary(path); + li.pManifest = new Manif(); std::string pocoBuildManifestSymbol("pocoBuildManifest"); pocoBuildManifestSymbol.append(manifest); if (li.pLibrary->hasSymbol("pocoInitializeLibrary")) From 89998df17aa7d7dfe85a7e10d27c17362d311c11 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 16:53:59 +0200 Subject: [PATCH 19/40] bugfix: _null member not initialized in ctor --- Data/include/Poco/Data/Extraction.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Data/include/Poco/Data/Extraction.h b/Data/include/Poco/Data/Extraction.h index 81153c979..9594e5022 100644 --- a/Data/include/Poco/Data/Extraction.h +++ b/Data/include/Poco/Data/Extraction.h @@ -90,7 +90,8 @@ public: AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(), - _extracted(false) + _extracted(false), + _null(false) /// Creates an Extraction object at specified position. /// Uses an empty object T as default value. { @@ -100,7 +101,8 @@ public: AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def), - _extracted(false) + _extracted(false), + _null(false) /// Creates an Extraction object at specified position. /// Uses the provided def object as default value. { From b0026b6a1c5ffc4f0693d2f6bb66d90284b3e8ec Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:00:20 +0200 Subject: [PATCH 20/40] style fix --- Data/include/Poco/Data/Extraction.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Data/include/Poco/Data/Extraction.h b/Data/include/Poco/Data/Extraction.h index 9594e5022..ddc1f0830 100644 --- a/Data/include/Poco/Data/Extraction.h +++ b/Data/include/Poco/Data/Extraction.h @@ -182,7 +182,6 @@ public: AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() - { _rResult.clear(); } From c9437273543a542a365067d26489be7efe9f4498 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:00:42 +0200 Subject: [PATCH 21/40] style fix --- NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp b/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp index 37c3a47be..67296cd6d 100644 --- a/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp +++ b/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp @@ -132,7 +132,8 @@ std::istream* HTTPSStreamFactory::open(const URI& uri) resolvedURI.setUserInfo(username + ":" + password); authorize = false; } - delete pSession; pSession = 0; + delete pSession; + pSession = 0; ++redirects; retry = true; } From b1004587b265d04de6c6a2986c2ab96b677e4ec3 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:19:55 +0200 Subject: [PATCH 22/40] code cleanup; fixed some issues reported by Klocwork --- Net/include/Poco/Net/ICMPSocket.h | 28 +----------------------- Net/include/Poco/Net/ICMPSocketImpl.h | 31 +++++++++++++++++++++++++++ Net/src/ICMPSocket.cpp | 23 ++++++++++++++++---- Net/src/ICMPSocketImpl.cpp | 19 ++++++---------- 4 files changed, 58 insertions(+), 43 deletions(-) diff --git a/Net/include/Poco/Net/ICMPSocket.h b/Net/include/Poco/Net/ICMPSocket.h index 3b98dd6e8..ebc5d175e 100644 --- a/Net/include/Poco/Net/ICMPSocket.h +++ b/Net/include/Poco/Net/ICMPSocket.h @@ -42,7 +42,7 @@ public: ICMPSocket(const Socket& socket); /// Creates the ICMPSocket with the SocketImpl /// from another socket. The SocketImpl must be - /// a DatagramSocketImpl, otherwise an InvalidArgumentException + /// a ICMPSocketImpl, otherwise an InvalidArgumentException /// will be thrown. ~ICMPSocket(); @@ -84,35 +84,9 @@ protected: /// /// The SocketImpl must be a ICMPSocketImpl, otherwise /// an InvalidArgumentException will be thrown. - -private: - int _dataSize; - int _ttl; - int _timeout; }; -// -// inlines -// -inline int ICMPSocket::dataSize() const -{ - return _dataSize; -} - - -inline int ICMPSocket::ttl() const -{ - return _ttl; -} - - -inline int ICMPSocket::timeout() const -{ - return _timeout; -} - - } } // namespace Poco::Net diff --git a/Net/include/Poco/Net/ICMPSocketImpl.h b/Net/include/Poco/Net/ICMPSocketImpl.h index 771c5a227..b59988e0b 100644 --- a/Net/include/Poco/Net/ICMPSocketImpl.h +++ b/Net/include/Poco/Net/ICMPSocketImpl.h @@ -50,15 +50,46 @@ public: /// /// Returns the time elapsed since the originating request was sent. + int dataSize() const; + /// Returns the data size in bytes. + + int ttl() const; + /// Returns the Time-To-Live value. + + int timeout() const; + /// Returns the socket timeout value. + protected: ~ICMPSocketImpl(); private: ICMPPacket _icmpPacket; + int _ttl; int _timeout; }; +// +// inlines +// +inline int ICMPSocketImpl::dataSize() const +{ + return _icmpPacket.getDataSize(); +} + + +inline int ICMPSocketImpl::ttl() const +{ + return _ttl; +} + + +inline int ICMPSocketImpl::timeout() const +{ + return _timeout; +} + + } } // namespace Poco::Net diff --git a/Net/src/ICMPSocket.cpp b/Net/src/ICMPSocket.cpp index ece9871c3..7e1204fe1 100644 --- a/Net/src/ICMPSocket.cpp +++ b/Net/src/ICMPSocket.cpp @@ -27,10 +27,7 @@ namespace Net { ICMPSocket::ICMPSocket(IPAddress::Family family, int dataSize, int ttl, int timeout): - Socket(new ICMPSocketImpl(family, dataSize, ttl, timeout)), - _dataSize(dataSize), - _ttl(ttl), - _timeout(timeout) + Socket(new ICMPSocketImpl(family, dataSize, ttl, timeout)) { } @@ -78,4 +75,22 @@ int ICMPSocket::receiveFrom(SocketAddress& address, int flags) } +int ICMPSocket::dataSize() const +{ + return static_cast(impl())->dataSize(); +} + + +int ICMPSocket::ttl() const +{ + return static_cast(impl())->ttl(); +} + + +int ICMPSocket::timeout() const +{ + return static_cast(impl())->timeout(); +} + + } } // namespace Poco::Net diff --git a/Net/src/ICMPSocketImpl.cpp b/Net/src/ICMPSocketImpl.cpp index 2deefbaae..11ebc30d2 100644 --- a/Net/src/ICMPSocketImpl.cpp +++ b/Net/src/ICMPSocketImpl.cpp @@ -19,6 +19,7 @@ #include "Poco/Timespan.h" #include "Poco/Timestamp.h" #include "Poco/Exception.h" +#include "Poco/Buffer.h" using Poco::TimeoutException; @@ -33,6 +34,7 @@ namespace Net { ICMPSocketImpl::ICMPSocketImpl(IPAddress::Family family, int dataSize, int ttl, int timeout): RawSocketImpl(family, IPPROTO_ICMP), _icmpPacket(family, dataSize), + _ttl(ttl), _timeout(timeout) { setOption(IPPROTO_IP, IP_TTL, ttl); @@ -55,7 +57,7 @@ int ICMPSocketImpl::sendTo(const void*, int, const SocketAddress& address, int f int ICMPSocketImpl::receiveFrom(void*, int, SocketAddress& address, int flags) { int maxPacketSize = _icmpPacket.maxPacketSize(); - unsigned char* buffer = new unsigned char[maxPacketSize]; + Poco::Buffer buffer(maxPacketSize); try { @@ -68,31 +70,24 @@ int ICMPSocketImpl::receiveFrom(void*, int, SocketAddress& address, int flags) // fake ping responses will cause an endless loop. throw TimeoutException(); } - SocketImpl::receiveFrom(buffer, maxPacketSize, address, flags); + SocketImpl::receiveFrom(buffer.begin(), maxPacketSize, address, flags); } - while (!_icmpPacket.validReplyID(buffer, maxPacketSize)); - } - catch (TimeoutException&) - { - delete [] buffer; - throw; + while (!_icmpPacket.validReplyID(buffer.begin(), maxPacketSize)); } catch (Exception&) { - std::string err = _icmpPacket.errorDescription(buffer, maxPacketSize); - delete [] buffer; + std::string err = _icmpPacket.errorDescription(buffer.begin(), maxPacketSize); if (!err.empty()) throw ICMPException(err); else throw; } - struct timeval then = _icmpPacket.time(buffer, maxPacketSize); + struct timeval then = _icmpPacket.time(buffer.begin(), maxPacketSize); struct timeval now = _icmpPacket.time(); int elapsed = (((now.tv_sec * 1000000) + now.tv_usec) - ((then.tv_sec * 1000000) + then.tv_usec))/1000; - delete[] buffer; return elapsed; } From 5d750ac8edc4b81a9d186ed5248f8c7df09e9576 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:28:41 +0200 Subject: [PATCH 23/40] fixed issues reported by Klocwork --- Foundation/src/DeflatingStream.cpp | 15 +++++++++++---- Foundation/src/InflatingStream.cpp | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Foundation/src/DeflatingStream.cpp b/Foundation/src/DeflatingStream.cpp index 1adb54fb3..56d7b9146 100644 --- a/Foundation/src/DeflatingStream.cpp +++ b/Foundation/src/DeflatingStream.cpp @@ -27,13 +27,20 @@ DeflatingStreamBuf::DeflatingStreamBuf(std::istream& istr, StreamType type, int _pOstr(0), _eof(false) { + _zstr.next_in = 0; + _zstr.avail_in = 0; + _zstr.total_in = 0; + _zstr.next_out = 0; + _zstr.avail_out = 0; + _zstr.total_out = 0; + _zstr.msg = 0; + _zstr.state = 0; _zstr.zalloc = Z_NULL; _zstr.zfree = Z_NULL; _zstr.opaque = Z_NULL; - _zstr.next_in = 0; - _zstr.avail_in = 0; - _zstr.next_out = 0; - _zstr.avail_out = 0; + _zstr.data_type = 0; + _zstr.adler = 0; + _zstr.reserved = 0; _buffer = new char[DEFLATE_BUFFER_SIZE]; diff --git a/Foundation/src/InflatingStream.cpp b/Foundation/src/InflatingStream.cpp index 77ecb500b..1eac3fa1a 100644 --- a/Foundation/src/InflatingStream.cpp +++ b/Foundation/src/InflatingStream.cpp @@ -16,6 +16,7 @@ #include "Poco/InflatingStream.h" #include "Poco/Exception.h" +#include namespace Poco { @@ -28,13 +29,20 @@ InflatingStreamBuf::InflatingStreamBuf(std::istream& istr, StreamType type): _eof(false), _check(type != STREAM_ZIP) { + _zstr.next_in = 0; + _zstr.avail_in = 0; + _zstr.total_in = 0; + _zstr.next_out = 0; + _zstr.avail_out = 0; + _zstr.total_out = 0; + _zstr.msg = 0; + _zstr.state = 0; _zstr.zalloc = Z_NULL; _zstr.zfree = Z_NULL; _zstr.opaque = Z_NULL; - _zstr.next_in = 0; - _zstr.avail_in = 0; - _zstr.next_out = 0; - _zstr.avail_out = 0; + _zstr.data_type = 0; + _zstr.adler = 0; + _zstr.reserved = 0; _buffer = new char[INFLATE_BUFFER_SIZE]; From 34b9b1284ccc54498e56594764e99832a7e1db71 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:31:29 +0200 Subject: [PATCH 24/40] fixed uninitialized _encoding member --- Net/src/MailMessage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Net/src/MailMessage.cpp b/Net/src/MailMessage.cpp index 54ee3c104..3fa4641ba 100644 --- a/Net/src/MailMessage.cpp +++ b/Net/src/MailMessage.cpp @@ -194,6 +194,7 @@ const std::string MailMessage::CTE_BASE64("base64"); MailMessage::MailMessage(PartStoreFactory* pStoreFactory): + _encoding(), _pStoreFactory(pStoreFactory) { Poco::Timestamp now; From 8935e19bbcd357ec2000abf54981caa1f4ff847a Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:39:29 +0200 Subject: [PATCH 25/40] fixed potential memory leak in out-of-memory situations --- Foundation/include/Poco/MemoryPool.h | 2 ++ Foundation/src/MemoryPool.cpp | 29 +++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Foundation/include/Poco/MemoryPool.h b/Foundation/include/Poco/MemoryPool.h index 048c9e199..2ab807031 100644 --- a/Foundation/include/Poco/MemoryPool.h +++ b/Foundation/include/Poco/MemoryPool.h @@ -73,6 +73,8 @@ private: MemoryPool(const MemoryPool&); MemoryPool& operator = (const MemoryPool&); + void clear(); + enum { BLOCK_RESERVE = 128 diff --git a/Foundation/src/MemoryPool.cpp b/Foundation/src/MemoryPool.cpp index ee940fc3f..fb83b7403 100644 --- a/Foundation/src/MemoryPool.cpp +++ b/Foundation/src/MemoryPool.cpp @@ -35,19 +35,35 @@ MemoryPool::MemoryPool(std::size_t blockLength, int preAlloc, int maxAlloc): if (maxAlloc > 0 && maxAlloc < r) r = maxAlloc; _blocks.reserve(r); - for (int i = 0; i < preAlloc; ++i) + + try { - _blocks.push_back(new char[_blockSize]); + for (int i = 0; i < preAlloc; ++i) + { + _blocks.push_back(new char[_blockSize]); + } + } + catch (...) + { + clear(); + throw; } } MemoryPool::~MemoryPool() +{ + clear(); +} + + +void MemoryPool::clear() { for (BlockVec::iterator it = _blocks.begin(); it != _blocks.end(); ++it) { delete [] *it; } + _blocks.clear(); } @@ -77,7 +93,14 @@ void MemoryPool::release(void* ptr) { FastMutex::ScopedLock lock(_mutex); - _blocks.push_back(reinterpret_cast(ptr)); + try + { + _blocks.push_back(reinterpret_cast(ptr)); + } + catch (...) + { + delete [] reinterpret_cast(ptr); + } } From 1bb795e7ede043d3bfcb42ead8dcfe1463b0815f Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:42:01 +0200 Subject: [PATCH 26/40] initialize all members in default ctor --- Data/src/MetaColumn.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Data/src/MetaColumn.cpp b/Data/src/MetaColumn.cpp index c743665a7..a4ecb1ef2 100644 --- a/Data/src/MetaColumn.cpp +++ b/Data/src/MetaColumn.cpp @@ -21,7 +21,12 @@ namespace Poco { namespace Data { -MetaColumn::MetaColumn() +MetaColumn::MetaColumn(): + _length(), + _precision(), + _position(), + _type(), + _nullable() { } From eabae863bbc1fd88cd273cfa6a665c53bdde4a6e Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:48:09 +0200 Subject: [PATCH 27/40] fixed uninitialized member in ctor --- Net/src/NetworkInterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Net/src/NetworkInterface.cpp b/Net/src/NetworkInterface.cpp index 85ae403f2..359df059b 100644 --- a/Net/src/NetworkInterface.cpp +++ b/Net/src/NetworkInterface.cpp @@ -228,7 +228,8 @@ NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, _pointToPoint(false), _up(false), _running(false), - _mtu(0) + _mtu(0), + _type(NetworkInterface::NI_TYPE_OTHER) { _addressList.push_back(AddressTuple(address, subnetMask, broadcastAddress)); setPhyParams(); From 9bd74daef9b37a27c553a64e3fff21fc7c3ca2fd Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 17:50:28 +0200 Subject: [PATCH 28/40] fixed uninitialized members in ctor --- Data/SQLite/src/Notifier.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Data/SQLite/src/Notifier.cpp b/Data/SQLite/src/Notifier.cpp index 6484b07cd..b279db91c 100644 --- a/Data/SQLite/src/Notifier.cpp +++ b/Data/SQLite/src/Notifier.cpp @@ -25,7 +25,9 @@ namespace SQLite { Notifier::Notifier(const Session& session, EnabledEventType enabled): - _session(session) + _session(session), + _row(), + _enabledEvents() { if (enabled & SQLITE_NOTIFY_UPDATE) enableUpdate(); if (enabled & SQLITE_NOTIFY_COMMIT) enableCommit(); @@ -35,7 +37,9 @@ Notifier::Notifier(const Session& session, EnabledEventType enabled): Notifier::Notifier(const Session& session, const Any& value, EnabledEventType enabled): _session(session), - _value(value) + _value(value), + _row(), + _enabledEvents() { if (enabled & SQLITE_NOTIFY_UPDATE) enableUpdate(); if (enabled & SQLITE_NOTIFY_COMMIT) enableCommit(); From 9c684af4785a5fdbf2c3e1cbcc07eb3c7d3912e2 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 18:08:36 +0200 Subject: [PATCH 29/40] handle unlikely situation that XML_ParserCreate() fails --- XML/src/ParserEngine.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/XML/src/ParserEngine.cpp b/XML/src/ParserEngine.cpp index 89c2385f1..bd1cdc5dd 100644 --- a/XML/src/ParserEngine.cpp +++ b/XML/src/ParserEngine.cpp @@ -450,19 +450,27 @@ void ParserEngine::init() if (dynamic_cast(_pNamespaceStrategy)) { _parser = XML_ParserCreateNS(_encodingSpecified ? _encoding.c_str() : 0, '\t'); - XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl); + if (_parser) + { + XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl); + } } else if (dynamic_cast(_pNamespaceStrategy)) { _parser = XML_ParserCreateNS(_encodingSpecified ? _encoding.c_str() : 0, '\t'); - XML_SetReturnNSTriplet(_parser, 1); - XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl); + if (_parser) + { + XML_SetReturnNSTriplet(_parser, 1); + XML_SetNamespaceDeclHandler(_parser, handleStartNamespaceDecl, handleEndNamespaceDecl); + } } else { _parser = XML_ParserCreate(_encodingSpecified ? _encoding.c_str() : 0); } + if (!_parser) throw XMLException("Cannot create Expat parser"); + XML_SetUserData(_parser, this); XML_SetElementHandler(_parser, handleStartElement, handleEndElement); XML_SetCharacterDataHandler(_parser, handleCharacterData); @@ -720,6 +728,8 @@ int ParserEngine::handleExternalEntityRef(XML_Parser parser, const XML_Char* con if (pInputSource) { XML_Parser extParser = XML_ExternalEntityParserCreate(pThis->_parser, context, 0); + if (!extParser) throw XMLException("Cannot create external entity parser"); + try { pThis->parseExternal(extParser, pInputSource); From 142ad284947f78331c3f9af1240c6876f4e4e857 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 18:10:07 +0200 Subject: [PATCH 30/40] initialize all members in ctor --- Data/src/SQLChannel.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Data/src/SQLChannel.cpp b/Data/src/SQLChannel.cpp index 7c2afaf08..8e7130317 100644 --- a/Data/src/SQLChannel.cpp +++ b/Data/src/SQLChannel.cpp @@ -47,7 +47,10 @@ SQLChannel::SQLChannel(): _table("T_POCO_LOG"), _timeout(1000), _throw(true), - _async(true) + _async(true), + _pid(), + _tid(), + _priority() { } @@ -61,7 +64,10 @@ SQLChannel::SQLChannel(const std::string& connector, _table("T_POCO_LOG"), _timeout(1000), _throw(true), - _async(true) + _async(true), + _pid(), + _tid(), + _priority() { open(); } From b0140637d523defb4b3d019032b38a79035ffd75 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 18:12:56 +0200 Subject: [PATCH 31/40] fix uninitialized member in ctor --- JSON/src/Template.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/JSON/src/Template.cpp b/JSON/src/Template.cpp index 862a7783a..4effd54e2 100644 --- a/JSON/src/Template.cpp +++ b/JSON/src/Template.cpp @@ -350,14 +350,16 @@ private: Template::Template(const Path& templatePath) - : _parts(NULL) + : _parts(0) + , _currentPart(0) , _templatePath(templatePath) { } Template::Template() - : _parts(NULL) + : _parts(0) + , _currentPart(0) { } From 78f954f58ff65a9eb438a44a11ac2ed300e148b2 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 18:15:36 +0200 Subject: [PATCH 32/40] fixed issues reported by Klocwork --- Foundation/include/Poco/Nullable.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Foundation/include/Poco/Nullable.h b/Foundation/include/Poco/Nullable.h index adceafd87..4b23aac6c 100644 --- a/Foundation/include/Poco/Nullable.h +++ b/Foundation/include/Poco/Nullable.h @@ -63,28 +63,32 @@ public: Nullable(): /// Creates an empty Nullable. _value(), - _isNull(true) + _isNull(true), + _null() { } Nullable(const NullType&): /// Creates an empty Nullable. _value(), - _isNull(true) + _isNull(true), + _null() { } Nullable(const C& value): /// Creates a Nullable with the given value. _value(value), - _isNull(false) + _isNull(false), + _null() { } Nullable(const Nullable& other): /// Creates a Nullable by copying another one. _value(other._value), - _isNull(other._isNull) + _isNull(other._isNull), + _null() { } From 18e594e7ffdf552acef90a52869f2cc95342d81e Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 18:15:43 +0200 Subject: [PATCH 33/40] fixed issues reported by Klocwork --- Foundation/include/Poco/Thread_POSIX.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Foundation/include/Poco/Thread_POSIX.h b/Foundation/include/Poco/Thread_POSIX.h index 5d43603ed..6963929c5 100644 --- a/Foundation/include/Poco/Thread_POSIX.h +++ b/Foundation/include/Poco/Thread_POSIX.h @@ -132,6 +132,7 @@ private: ThreadData(): thread(0), prio(PRIO_NORMAL_IMPL), + osPrio(), policy(SCHED_OTHER), done(Event::EVENT_MANUALRESET), stackSize(POCO_THREAD_STACK_SIZE), From dd30db6ca9b05c8e5984b35f012ca3ed534913d6 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Mon, 26 Sep 2016 19:29:55 +0200 Subject: [PATCH 34/40] fixed Klocwork issues --- Zip/src/ZipFileInfo.cpp | 67 ++++++++++++++++++++++------------ Zip/src/ZipLocalFileHeader.cpp | 67 ++++++++++++++++++++-------------- 2 files changed, 82 insertions(+), 52 deletions(-) diff --git a/Zip/src/ZipFileInfo.cpp b/Zip/src/ZipFileInfo.cpp index c426e247a..e29cd73c8 100644 --- a/Zip/src/ZipFileInfo.cpp +++ b/Zip/src/ZipFileInfo.cpp @@ -101,34 +101,53 @@ void ZipFileInfo::parse(std::istream& inp, bool assumeHeaderRead) _localHeaderOffset = getOffsetFromHeader(); parseDateTime(); Poco::UInt16 len = getFileNameLength(); - Poco::Buffer buf(len); - inp.read(buf.begin(), len); - _fileName = std::string(buf.begin(), len); + if (len > 0) + { + Poco::Buffer buf(len); + inp.read(buf.begin(), len); + _fileName = std::string(buf.begin(), len); + } if (hasExtraField()) { len = getExtraFieldLength(); - Poco::Buffer xtra(len); - inp.read(xtra.begin(), len); - _extraField = std::string(xtra.begin(), len); - char* ptr = xtra.begin(); - while(ptr <= xtra.begin() + len - 4) { - Poco::UInt16 id = ZipUtil::get16BitValue(ptr, 0); ptr +=2; - Poco::UInt16 size = ZipUtil::get16BitValue(ptr, 0); ptr += 2; - if(id == ZipCommon::ZIP64_EXTRA_ID) { - poco_assert(size >= 8); - if(getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) { - setUncompressedSize(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8; - } - if(size >= 8 && getCompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) { - setCompressedSize(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8; - } - if(size >= 8 && getOffsetFromHeader() == ZipCommon::ZIP64_MAGIC) { - setOffset(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8; - } - } - else + if (len > 0) + { + Poco::Buffer xtra(len); + inp.read(xtra.begin(), len); + _extraField = std::string(xtra.begin(), len); + char* ptr = xtra.begin(); + while (ptr <= xtra.begin() + len - 4) { - ptr += size; + Poco::UInt16 id = ZipUtil::get16BitValue(ptr, 0); + ptr += 2; + Poco::UInt16 size = ZipUtil::get16BitValue(ptr, 0); + ptr += 2; + if (id == ZipCommon::ZIP64_EXTRA_ID) + { + poco_assert(size >= 8); + if (getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) + { + setUncompressedSize(ZipUtil::get64BitValue(ptr, 0)); + size -= 8; + ptr += 8; + } + if (size >= 8 && getCompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) + { + setCompressedSize(ZipUtil::get64BitValue(ptr, 0)); + size -= 8; + ptr += 8; + } + if (size >= 8 && getOffsetFromHeader() == ZipCommon::ZIP64_MAGIC) + { + setOffset(ZipUtil::get64BitValue(ptr, 0)); + size -= 8; + ptr += 8; + } + } + else + { + ptr += size; + } } } } diff --git a/Zip/src/ZipLocalFileHeader.cpp b/Zip/src/ZipLocalFileHeader.cpp index a2a7eb7ba..7b7f63a1c 100644 --- a/Zip/src/ZipLocalFileHeader.cpp +++ b/Zip/src/ZipLocalFileHeader.cpp @@ -131,10 +131,13 @@ void ZipLocalFileHeader::parse(std::istream& inp, bool assumeHeaderRead) poco_assert (ZipUtil::get16BitValue(_rawHeader, COMPR_METHOD_POS) < ZipCommon::CM_UNUSED); parseDateTime(); Poco::UInt16 len = getFileNameLength(); - Poco::Buffer buf(len); - inp.read(buf.begin(), len); - _fileName = std::string(buf.begin(), len); - + if (len > 0) + { + Poco::Buffer buf(len); + inp.read(buf.begin(), len); + _fileName = std::string(buf.begin(), len); + } + if (!searchCRCAndSizesAfterData()) { _crc32 = getCRCFromHeader(); @@ -145,33 +148,41 @@ void ZipLocalFileHeader::parse(std::istream& inp, bool assumeHeaderRead) if (hasExtraField()) { len = getExtraFieldLength(); - Poco::Buffer xtra(len); - inp.read(xtra.begin(), len); - _extraField = std::string(xtra.begin(), len); - char* ptr = xtra.begin(); - while (ptr <= xtra.begin() + len - 4) + if (len > 0) { - Poco::UInt16 id = ZipUtil::get16BitValue(ptr, 0); ptr +=2; - Poco::UInt16 size = ZipUtil::get16BitValue(ptr, 0); ptr += 2; - if (id == ZipCommon::ZIP64_EXTRA_ID) - { - poco_assert(size >= 8); - if (getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) - { - setUncompressedSize(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8; - } - if (size >= 8 && getCompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) - { - setCompressedSize(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8; - } - } - else - { - ptr += size; - } + Poco::Buffer xtra(len); + inp.read(xtra.begin(), len); + _extraField = std::string(xtra.begin(), len); + char* ptr = xtra.begin(); + while (ptr <= xtra.begin() + len - 4) + { + Poco::UInt16 id = ZipUtil::get16BitValue(ptr, 0); + ptr += 2; + Poco::UInt16 size = ZipUtil::get16BitValue(ptr, 0); + ptr += 2; + if (id == ZipCommon::ZIP64_EXTRA_ID) + { + poco_assert(size >= 8); + if (getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) + { + setUncompressedSize(ZipUtil::get64BitValue(ptr, 0)); + size -= 8; + ptr += 8; + } + if (size >= 8 && getCompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) + { + setCompressedSize(ZipUtil::get64BitValue(ptr, 0)); + size -= 8; + ptr += 8; + } + } + else + { + ptr += size; + } + } } } - } From 61e0561182312bc1c155be6aef96b54e2af6424b Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Wed, 28 Sep 2016 12:31:48 +0200 Subject: [PATCH 35/40] fixed GH #1429: exception thrown in MongoDB when using replicaset --- MongoDB/include/Poco/MongoDB/Element.h | 48 ++++++++++++++++++++++++++ MongoDB/src/Document.cpp | 5 ++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/MongoDB/include/Poco/MongoDB/Element.h b/MongoDB/include/Poco/MongoDB/Element.h index 346bef60c..e383adb7c 100644 --- a/MongoDB/include/Poco/MongoDB/Element.h +++ b/MongoDB/include/Poco/MongoDB/Element.h @@ -247,6 +247,54 @@ inline void BSONWriter::write(NullValue& from) } +struct BSONTimestamp +{ + Poco::Timestamp ts; + Poco::Int32 inc; +}; + + +// BSON Timestamp +// spec: int64 +template<> +struct ElementTraits +{ + enum { TypeId = 0x11 }; + + static std::string toString(const BSONTimestamp& value, int indent = 0) + { + std::string result; + result.append(1, '"'); + result.append(DateTimeFormatter::format(value.ts, "%Y-%m-%dT%H:%M:%s%z")); + result.append(1, ' '); + result.append(NumberFormatter::format(value.inc)); + result.append(1, '"'); + return result; + } +}; + + +template<> +inline void BSONReader::read(BSONTimestamp& to) +{ + Poco::Int64 value; + _reader >> value; + to.inc = value & 0xffffffff; + value >>= 32; + to.ts = Timestamp::fromEpochTime(static_cast(value)); +} + + +template<> +inline void BSONWriter::write(BSONTimestamp& from) +{ + Poco::Int64 value = from.ts.epochMicroseconds() / 1000; + value <<= 32; + value += from.inc; + _writer << value; +} + + // BSON 64-bit integer // spec: int64 template<> diff --git a/MongoDB/src/Document.cpp b/MongoDB/src/Document.cpp index 43f652358..a968f1780 100644 --- a/MongoDB/src/Document.cpp +++ b/MongoDB/src/Document.cpp @@ -118,6 +118,9 @@ void Document::read(BinaryReader& reader) case ElementTraits::TypeId: element = new ConcreteElement(name, Poco::Timestamp()); break; + case ElementTraits::TypeId: + element = new ConcreteElement(name, BSONTimestamp()); + break; case ElementTraits::TypeId: element = new ConcreteElement(name, NullValue(0)); break; @@ -133,7 +136,7 @@ void Document::read(BinaryReader& reader) default: { std::stringstream ss; - ss << "Element " << name << " contains an unsupported type " << std::hex << (int) type; + ss << "Element " << name << " contains an unsupported type 0x" << std::hex << (int) type; throw Poco::NotImplementedException(ss.str()); } //TODO: x0F -> JavaScript code with scope From 5d8faa371e82898529b3932c7aa9fff75a0afde5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Thu, 29 Sep 2016 17:41:37 +0200 Subject: [PATCH 36/40] added URISyntaxException; better error handling in URIStreamOpener --- Foundation/include/Poco/Exception.h | 2 ++ Foundation/src/Exception.cpp | 3 ++- Foundation/src/URI.cpp | 14 +++++------ Foundation/src/URIStreamOpener.cpp | 37 +++++++++++++++++++++++++---- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/Foundation/include/Poco/Exception.h b/Foundation/include/Poco/Exception.h index fb76576c3..5e582e045 100644 --- a/Foundation/include/Poco/Exception.h +++ b/Foundation/include/Poco/Exception.h @@ -255,6 +255,8 @@ POCO_DECLARE_EXCEPTION(Foundation_API, OpenFileException, FileException) POCO_DECLARE_EXCEPTION(Foundation_API, WriteFileException, FileException) POCO_DECLARE_EXCEPTION(Foundation_API, ReadFileException, FileException) POCO_DECLARE_EXCEPTION(Foundation_API, UnknownURISchemeException, RuntimeException) +POCO_DECLARE_EXCEPTION(Foundation_API, TooManyURIRedirectsException, RuntimeException) +POCO_DECLARE_EXCEPTION(Foundation_API, URISyntaxException, SyntaxException) POCO_DECLARE_EXCEPTION(Foundation_API, ApplicationException, Exception) POCO_DECLARE_EXCEPTION(Foundation_API, BadCastException, RuntimeException) diff --git a/Foundation/src/Exception.cpp b/Foundation/src/Exception.cpp index fd1eacd66..738d4dfc8 100644 --- a/Foundation/src/Exception.cpp +++ b/Foundation/src/Exception.cpp @@ -179,7 +179,8 @@ POCO_IMPLEMENT_EXCEPTION(OpenFileException, FileException, "Cannot open file") POCO_IMPLEMENT_EXCEPTION(WriteFileException, FileException, "Cannot write file") POCO_IMPLEMENT_EXCEPTION(ReadFileException, FileException, "Cannot read file") POCO_IMPLEMENT_EXCEPTION(UnknownURISchemeException, RuntimeException, "Unknown URI scheme") - +POCO_IMPLEMENT_EXCEPTION(TooManyURIRedirectsException, RuntimeException, "Too many URI redirects") +POCO_IMPLEMENT_EXCEPTION(URISyntaxException, SyntaxException, "Bad URI syntax") POCO_IMPLEMENT_EXCEPTION(ApplicationException, Exception, "Application exception") POCO_IMPLEMENT_EXCEPTION(BadCastException, RuntimeException, "Bad cast exception") diff --git a/Foundation/src/URI.cpp b/Foundation/src/URI.cpp index 0f375bd29..e0cbb241a 100644 --- a/Foundation/src/URI.cpp +++ b/Foundation/src/URI.cpp @@ -660,9 +660,9 @@ void URI::decode(const std::string& str, std::string& decodedStr, bool plusAsSpa if (inQuery && plusAsSpace && c == '+') c = ' '; else if (c == '%') { - if (it == end) throw SyntaxException("URI encoding: no hex digit following percent sign", str); + if (it == end) throw URISyntaxException("URI encoding: no hex digit following percent sign", str); char hi = *it++; - if (it == end) throw SyntaxException("URI encoding: two hex digits must follow percent sign", str); + if (it == end) throw URISyntaxException("URI encoding: two hex digits must follow percent sign", str); char lo = *it++; if (hi >= '0' && hi <= '9') c = hi - '0'; @@ -670,7 +670,7 @@ void URI::decode(const std::string& str, std::string& decodedStr, bool plusAsSpa c = hi - 'A' + 10; else if (hi >= 'a' && hi <= 'f') c = hi - 'a' + 10; - else throw SyntaxException("URI encoding: not a hex digit"); + else throw URISyntaxException("URI encoding: not a hex digit"); c *= 16; if (lo >= '0' && lo <= '9') c += lo - '0'; @@ -678,7 +678,7 @@ void URI::decode(const std::string& str, std::string& decodedStr, bool plusAsSpa c += lo - 'A' + 10; else if (lo >= 'a' && lo <= 'f') c += lo - 'a' + 10; - else throw SyntaxException("URI encoding: not a hex digit"); + else throw URISyntaxException("URI encoding: not a hex digit"); } decodedStr += c; } @@ -732,7 +732,7 @@ void URI::parse(const std::string& uri) if (it != end && *it == ':') { ++it; - if (it == end) throw SyntaxException("URI scheme must be followed by authority or path", uri); + if (it == end) throw URISyntaxException("URI scheme must be followed by authority or path", uri); setScheme(scheme); if (*it == '/') { @@ -786,7 +786,7 @@ void URI::parseHostAndPort(std::string::const_iterator& it, const std::string::c // IPv6 address ++it; while (it != end && *it != ']') host += *it++; - if (it == end) throw SyntaxException("unterminated IPv6 address"); + if (it == end) throw URISyntaxException("unterminated IPv6 address"); ++it; } else @@ -804,7 +804,7 @@ void URI::parseHostAndPort(std::string::const_iterator& it, const std::string::c if (NumberParser::tryParse(port, nport) && nport > 0 && nport < 65536) _port = (unsigned short) nport; else - throw SyntaxException("bad or invalid port number", port); + throw URISyntaxException("bad or invalid port number", port); } else _port = getWellKnownPort(); } diff --git a/Foundation/src/URIStreamOpener.cpp b/Foundation/src/URIStreamOpener.cpp index 825fb1c60..14ffa6d3a 100644 --- a/Foundation/src/URIStreamOpener.cpp +++ b/Foundation/src/URIStreamOpener.cpp @@ -62,13 +62,34 @@ std::istream* URIStreamOpener::open(const std::string& pathOrURI) const std::string scheme(uri.getScheme()); FactoryMap::const_iterator it = _map.find(scheme); if (it != _map.end()) + { return openURI(scheme, uri); + } + else + { + Path path; + if (path.tryParse(pathOrURI, Path::PATH_GUESS)) + return openFile(path); + else + throw UnknownURISchemeException(pathOrURI); + } } - catch (Exception&) + catch (UnknownURISchemeException&) { + throw; + } + catch (TooManyURIRedirectsException&) + { + throw; + } + catch (URISyntaxException&) + { + Path path; + if (path.tryParse(pathOrURI, Path::PATH_GUESS)) + return openFile(path); + else + throw; } - Path path(pathOrURI, Path::PATH_GUESS); - return openFile(path); } @@ -87,6 +108,14 @@ std::istream* URIStreamOpener::open(const std::string& basePathOrURI, const std: return openURI(scheme, uri); } } + catch (UnknownURISchemeException&) + { + throw; + } + catch (TooManyURIRedirectsException&) + { + throw; + } catch (Exception&) { } @@ -176,7 +205,7 @@ std::istream* URIStreamOpener::openURI(const std::string& scheme, const URI& uri ++redirects; } } - throw IOException("Too many redirects while opening URI", uri.toString()); + throw TooManyURIRedirectsException(uri.toString()); } From e87a3a6e45a878d5e8dde82652f97d4ef6b2f481 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Thu, 29 Sep 2016 17:44:34 +0200 Subject: [PATCH 37/40] style fix --- Foundation/src/Exception.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Foundation/src/Exception.cpp b/Foundation/src/Exception.cpp index 738d4dfc8..e3cdd7ca7 100644 --- a/Foundation/src/Exception.cpp +++ b/Foundation/src/Exception.cpp @@ -185,4 +185,5 @@ POCO_IMPLEMENT_EXCEPTION(URISyntaxException, SyntaxException, "Bad URI syntax") POCO_IMPLEMENT_EXCEPTION(ApplicationException, Exception, "Application exception") POCO_IMPLEMENT_EXCEPTION(BadCastException, RuntimeException, "Bad cast exception") + } // namespace Poco From a73eef0487398c8756f7a504626d1496f230a868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Thu, 29 Sep 2016 19:06:46 +0200 Subject: [PATCH 38/40] improvement of URIStreamOpener::open() implementation --- Foundation/src/URIStreamOpener.cpp | 49 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/Foundation/src/URIStreamOpener.cpp b/Foundation/src/URIStreamOpener.cpp index 14ffa6d3a..b9494c4e2 100644 --- a/Foundation/src/URIStreamOpener.cpp +++ b/Foundation/src/URIStreamOpener.cpp @@ -65,22 +65,15 @@ std::istream* URIStreamOpener::open(const std::string& pathOrURI) const { return openURI(scheme, uri); } - else + else if (scheme.length() <= 1) // could be Windows path { Path path; if (path.tryParse(pathOrURI, Path::PATH_GUESS)) + { return openFile(path); - else - throw UnknownURISchemeException(pathOrURI); + } } - } - catch (UnknownURISchemeException&) - { - throw; - } - catch (TooManyURIRedirectsException&) - { - throw; + throw UnknownURISchemeException(pathOrURI); } catch (URISyntaxException&) { @@ -105,24 +98,32 @@ std::istream* URIStreamOpener::open(const std::string& basePathOrURI, const std: if (it != _map.end()) { uri.resolve(pathOrURI); + scheme = uri.getScheme(); return openURI(scheme, uri); } + else if (scheme.length() <= 1) // could be Windows path + { + Path base; + Path path; + if (base.tryParse(basePathOrURI, Path::PATH_GUESS) && path.tryParse(pathOrURI, Path::PATH_GUESS)) + { + base.resolve(path); + return openFile(base); + } + } + throw UnknownURISchemeException(basePathOrURI); } - catch (UnknownURISchemeException&) - { - throw; - } - catch (TooManyURIRedirectsException&) - { - throw; - } - catch (Exception&) + catch (URISyntaxException&) { + Path base; + Path path; + if (base.tryParse(basePathOrURI, Path::PATH_GUESS) && path.tryParse(pathOrURI, Path::PATH_GUESS)) + { + base.resolve(path); + return openFile(base); + } + else throw; } - Path base(basePathOrURI, Path::PATH_GUESS); - Path path(pathOrURI, Path::PATH_GUESS); - base.resolve(path); - return openFile(base); } From f86dfa82393dfe635ce51c7bb9109115dc896479 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Thu, 29 Sep 2016 20:10:10 +0200 Subject: [PATCH 39/40] integrated fixes for #1416 from poco-1.7.6 branch --- Zip/include/Poco/Zip/ZipArchive.h | 1 - Zip/src/AutoDetectStream.cpp | 9 ++++----- Zip/src/Compress.cpp | 15 ++++++++------- Zip/src/Decompress.cpp | 2 +- Zip/src/PartialStream.cpp | 2 +- Zip/src/SkipCallback.cpp | 2 ++ Zip/src/ZipArchiveInfo.cpp | 18 +++++++++++++++--- Zip/src/ZipDataInfo.cpp | 16 ++++++++++------ Zip/src/ZipFileInfo.cpp | 6 +++++- Zip/src/ZipLocalFileHeader.cpp | 8 ++++++-- Zip/src/ZipManipulator.cpp | 2 +- Zip/src/ZipStream.cpp | 12 +++++++----- Zip/src/ZipUtil.cpp | 25 +++++++++---------------- 13 files changed, 69 insertions(+), 49 deletions(-) diff --git a/Zip/include/Poco/Zip/ZipArchive.h b/Zip/include/Poco/Zip/ZipArchive.h index aa5a8498c..150f003e9 100644 --- a/Zip/include/Poco/Zip/ZipArchive.h +++ b/Zip/include/Poco/Zip/ZipArchive.h @@ -24,7 +24,6 @@ #include "Poco/Zip/ZipLocalFileHeader.h" #include "Poco/Zip/ZipFileInfo.h" #include "Poco/Zip/ZipArchiveInfo.h" - #include #include diff --git a/Zip/src/AutoDetectStream.cpp b/Zip/src/AutoDetectStream.cpp index 1229e3294..3664df9a1 100644 --- a/Zip/src/AutoDetectStream.cpp +++ b/Zip/src/AutoDetectStream.cpp @@ -69,6 +69,7 @@ int AutoDetectStreamBuf::readFromDevice(char* buffer, std::streamsize length) { _pIstr->seekg(_start, std::ios_base::beg); _reposition = false; + if (!_pIstr->good()) return -1; } if (!_prefix.empty()) @@ -145,11 +146,9 @@ int AutoDetectStreamBuf::readFromDevice(char* buffer, std::streamsize length) { if (c-1 == byte3) { - // a match, pushback - _pIstr->putback(c); - _pIstr->putback(byte3); - _pIstr->putback(ZipLocalFileHeader::HEADER[1]); - _pIstr->putback(ZipLocalFileHeader::HEADER[0]); + // a match, seek back + _pIstr->seekg(-4, std::ios::cur); + if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream"); _eofDetected = true; return tempPos; } diff --git a/Zip/src/Compress.cpp b/Zip/src/Compress.cpp index b335a3074..b74333d1a 100644 --- a/Zip/src/Compress.cpp +++ b/Zip/src/Compress.cpp @@ -78,7 +78,7 @@ void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt, _offset = hdr.getEndPos(); _offset += extraDataSize; _files.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), hdr)); - poco_assert (_out); + if (!_out) throw Poco::IOException("Bad output stream"); ZipFileInfo nfo(hdr); nfo.setOffset(localHeaderOffset); nfo.setZip64Data(); @@ -89,12 +89,13 @@ void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt, void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const Poco::Path& fileName) { + if (!in.good()) + throw ZipException("Invalid input stream"); + std::string fn = ZipUtil::validZipEntryFileName(fileName); //bypass the header of the input stream and point to the first byte of the data payload in.seekg(h.getDataStartPos(), std::ios_base::beg); - - if (!in.good()) - throw ZipException("Invalid input stream"); + if (!in.good()) throw Poco::IOException("Failed to seek on input stream"); std::streamoff localHeaderOffset = _offset; ZipLocalFileHeader hdr(h); @@ -161,7 +162,7 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P } _files.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), hdr)); - poco_assert (_out); + if (!_out) throw Poco::IOException("Bad output stream"); ZipFileInfo nfo(hdr); nfo.setOffset(localHeaderOffset); nfo.setZip64Data(); @@ -229,7 +230,7 @@ void Compress::addDirectory(const Poco::Path& entryName, const Poco::DateTime& l if (hdr.searchCRCAndSizesAfterData()) _offset += extraDataSize; _files.insert(std::make_pair(entryName.toString(Poco::Path::PATH_UNIX), hdr)); - poco_assert (_out); + if (!_out) throw Poco::IOException("Bad output stream"); ZipFileInfo nfo(hdr); nfo.setOffset(localHeaderOffset); nfo.setZip64Data(); @@ -314,7 +315,7 @@ ZipArchive Compress::close() centralDirSize64 += entrySize; _offset += entrySize; } - poco_assert (_out); + if (!_out) throw Poco::IOException("Bad output stream"); Poco::UInt64 numEntries64 = _infos.size(); needZip64 = needZip64 || _offset >= ZipCommon::ZIP64_MAGIC; diff --git a/Zip/src/Decompress.cpp b/Zip/src/Decompress.cpp index 2f94fa949..e01f47e9d 100644 --- a/Zip/src/Decompress.cpp +++ b/Zip/src/Decompress.cpp @@ -39,7 +39,7 @@ Decompress::Decompress(std::istream& in, const Poco::Path& outputDir, bool flatt { _outDir.makeAbsolute(); _outDir.makeDirectory(); - poco_assert (_in.good()); + if (!_in.good()) throw Poco::IOException("Bad input stream"); Poco::File tmp(_outDir); if (!tmp.exists()) { diff --git a/Zip/src/PartialStream.cpp b/Zip/src/PartialStream.cpp index 85587278e..d6d9e302b 100644 --- a/Zip/src/PartialStream.cpp +++ b/Zip/src/PartialStream.cpp @@ -69,7 +69,7 @@ int PartialStreamBuf::readFromDevice(char* buffer, std::streamsize length) _pIstr->clear(); _pIstr->seekg(_start, std::ios_base::beg); if (_pIstr->fail()) - throw Poco::IOException("Failed to reposition in stream"); + throw Poco::IOException("Failed to seek on input stream"); } if (!_prefix.empty()) { diff --git a/Zip/src/SkipCallback.cpp b/Zip/src/SkipCallback.cpp index 20d0ca491..febbd0af6 100644 --- a/Zip/src/SkipCallback.cpp +++ b/Zip/src/SkipCallback.cpp @@ -17,6 +17,7 @@ #include "Poco/Zip/SkipCallback.h" #include "Poco/Zip/ZipLocalFileHeader.h" #include "Poco/Zip/ZipUtil.h" +#include "Poco/Exception.h" namespace Poco { @@ -39,6 +40,7 @@ bool SkipCallback::handleZipEntry(std::istream& zipStream, const ZipLocalFileHea zipStream.seekg(hdr.getCompressedSize(), std::ios_base::cur); else ZipUtil::sync(zipStream); + if (!zipStream.good()) throw Poco::IOException("Failed to seek on input stream"); return true; } diff --git a/Zip/src/ZipArchiveInfo.cpp b/Zip/src/ZipArchiveInfo.cpp index 9299eb4cb..6985efab3 100644 --- a/Zip/src/ZipArchiveInfo.cpp +++ b/Zip/src/ZipArchiveInfo.cpp @@ -59,12 +59,16 @@ void ZipArchiveInfo::parse(std::istream& inp, bool assumeHeaderRead) if (!assumeHeaderRead) { inp.read(_rawInfo, ZipCommon::HEADER_SIZE); + if (inp.gcount() != ZipCommon::HEADER_SIZE) + throw Poco::IOException("Failed to read archive info header"); + if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0) + throw Poco::DataFormatException("Bad archive info header"); } else { std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE); } - poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0); + // read the rest of the header inp.read(_rawInfo + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE); Poco::UInt16 len = getZipCommentSize(); @@ -136,12 +140,16 @@ void ZipArchiveInfo64::parse(std::istream& inp, bool assumeHeaderRead) if (!assumeHeaderRead) { inp.read(_rawInfo, ZipCommon::HEADER_SIZE); + if (inp.gcount() != ZipCommon::HEADER_SIZE) + throw Poco::IOException("Failed to read archive info header"); + if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0) + throw Poco::DataFormatException("Bad archive info header"); } else { std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE); } - poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0); + std::memset(_rawInfo + ZipCommon::HEADER_SIZE, 0, FULL_HEADER_SIZE - ZipCommon::HEADER_SIZE); // read the rest of the header @@ -164,7 +172,11 @@ void ZipArchiveInfo64::parse(std::istream& inp, bool assumeHeaderRead) ZipUtil::set64BitValue(FULL_HEADER_SIZE + len - offset, _rawInfo, RECORDSIZE_POS); } inp.read(_locInfo, FULL_LOCATOR_SIZE); - poco_assert (std::memcmp(_locInfo, LOCATOR_HEADER, ZipCommon::HEADER_SIZE) == 0); + if (inp.gcount() != FULL_LOCATOR_SIZE) + throw Poco::IOException("Failed to read locator"); + if (std::memcmp(_locInfo, LOCATOR_HEADER, ZipCommon::HEADER_SIZE) != 0) + throw Poco::DataFormatException("Bad locator header"); + } diff --git a/Zip/src/ZipDataInfo.cpp b/Zip/src/ZipDataInfo.cpp index c2b6bf645..e03b82074 100644 --- a/Zip/src/ZipDataInfo.cpp +++ b/Zip/src/ZipDataInfo.cpp @@ -15,6 +15,7 @@ #include "Poco/Zip/ZipDataInfo.h" +#include "Poco/Exception.h" #include #include @@ -47,10 +48,11 @@ ZipDataInfo::ZipDataInfo(std::istream& in, bool assumeHeaderRead): else { in.read(_rawInfo, ZipCommon::HEADER_SIZE); - if ((!in) || (in.gcount() != ZipCommon::HEADER_SIZE)) - return; + if (in.gcount() != ZipCommon::HEADER_SIZE) + throw Poco::IOException("Failed to read data info header"); + if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0) + throw Poco::DataFormatException("Bad data info header"); } - poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0); // now copy the rest of the header in.read(_rawInfo+ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE); _valid = (!in.eof() && in.good()); @@ -87,10 +89,12 @@ ZipDataInfo64::ZipDataInfo64(std::istream& in, bool assumeHeaderRead): else { in.read(_rawInfo, ZipCommon::HEADER_SIZE); - if ((!in) || (in.gcount() != ZipCommon::HEADER_SIZE)) - return; + if (in.gcount() != ZipCommon::HEADER_SIZE) + throw Poco::IOException("Failed to read data info header"); + if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0) + throw Poco::DataFormatException("Bad data info header"); } - poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0); + // now copy the rest of the header in.read(_rawInfo+ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE); _valid = (!in.eof() && in.good()); diff --git a/Zip/src/ZipFileInfo.cpp b/Zip/src/ZipFileInfo.cpp index e29cd73c8..e23d0870e 100644 --- a/Zip/src/ZipFileInfo.cpp +++ b/Zip/src/ZipFileInfo.cpp @@ -87,12 +87,16 @@ void ZipFileInfo::parse(std::istream& inp, bool assumeHeaderRead) if (!assumeHeaderRead) { inp.read(_rawInfo, ZipCommon::HEADER_SIZE); + if (inp.gcount() != ZipCommon::HEADER_SIZE) + throw Poco::IOException("Failed to read file info header"); + if (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) != 0) + throw Poco::DataFormatException("Bad file info header"); } else { std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE); } - poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0); + // read the rest of the header inp.read(_rawInfo + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE); _crc32 = getCRCFromHeader(); diff --git a/Zip/src/ZipLocalFileHeader.cpp b/Zip/src/ZipLocalFileHeader.cpp index 7b7f63a1c..aab16fdf1 100644 --- a/Zip/src/ZipLocalFileHeader.cpp +++ b/Zip/src/ZipLocalFileHeader.cpp @@ -118,13 +118,17 @@ void ZipLocalFileHeader::parse(std::istream& inp, bool assumeHeaderRead) if (!assumeHeaderRead) { inp.read(_rawHeader, ZipCommon::HEADER_SIZE); + if (inp.gcount() != ZipCommon::HEADER_SIZE) + throw Poco::IOException("Failed to read local file header"); + if (std::memcmp(_rawHeader, HEADER, ZipCommon::HEADER_SIZE) != 0) + throw Poco::DataFormatException("Bad local file header"); } else { std::memcpy(_rawHeader, HEADER, ZipCommon::HEADER_SIZE); } - poco_assert (std::memcmp(_rawHeader, HEADER, ZipCommon::HEADER_SIZE) == 0); - // read the rest of the header + + // read the rest of the header inp.read(_rawHeader + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE); poco_assert (_rawHeader[VERSION_POS + 1]>= ZipCommon::HS_FAT && _rawHeader[VERSION_POS + 1] < ZipCommon::HS_UNUSED); poco_assert (getMajorVersionNumber() <= 4); // Allow for Zip64 version 4.5 diff --git a/Zip/src/ZipManipulator.cpp b/Zip/src/ZipManipulator.cpp index 5fc00e9ae..73e8e7e1c 100644 --- a/Zip/src/ZipManipulator.cpp +++ b/Zip/src/ZipManipulator.cpp @@ -111,7 +111,7 @@ const ZipLocalFileHeader& ZipManipulator::getForChange(const std::string& zipPat { ZipArchive::FileHeaders::const_iterator it = _in->findHeader(zipPath); if (it == _in->headerEnd()) - throw ZipManipulationException("entry not found: " + zipPath); + throw ZipManipulationException("Entry not found: " + zipPath); if (_changes.find(zipPath) != _changes.end()) throw ZipManipulationException("A change request exists already for entry " + zipPath); diff --git a/Zip/src/ZipStream.cpp b/Zip/src/ZipStream.cpp index fdda20eb2..26514feb5 100644 --- a/Zip/src/ZipStream.cpp +++ b/Zip/src/ZipStream.cpp @@ -177,8 +177,8 @@ int ZipStreamBuf::readFromDevice(char* buffer, std::streamsize length) Poco::Int32 size = static_cast(nfo.getFullHeaderSize()); _expectedCrc32 = nfo.getCRC32(); const char* rawHeader = nfo.getRawHeader(); - for (Poco::Int32 i = size-1; i >= 0; --i) - _pIstr->putback(rawHeader[i]); + _pIstr->seekg(-size, std::ios::cur); + if (!_pIstr->good()) throw Poco::IOException("Failed to seek on input stream"); if (!crcValid()) throw ZipException("CRC failure"); } @@ -215,7 +215,8 @@ void ZipStreamBuf::close(Poco::UInt64& extraDataSize) _ptrOHelper->close(); } _ptrOBuf = 0; - poco_assert (*_pOstr); + if (!*_pOstr) throw Poco::IOException("Bad output stream"); + // write an extra datablock if required // or fix the crc entries poco_check_ptr(_pHeader); @@ -248,13 +249,14 @@ void ZipStreamBuf::close(Poco::UInt64& extraDataSize) else { _pOstr->seekp(_pHeader->getStartPos(), std::ios_base::beg); - poco_assert (*_pOstr); + if (!*_pOstr) throw Poco::IOException("Bad output stream"); + if (_pHeader->hasExtraField()) // Update sizes in header extension. _pHeader->setZip64Data(); std::string header = _pHeader->createHeader(); _pOstr->write(header.c_str(), static_cast(header.size())); _pOstr->seekp(0, std::ios_base::end); - poco_assert (*_pOstr); + if (!*_pOstr) throw Poco::IOException("Bad output stream"); } _pHeader = 0; } diff --git a/Zip/src/ZipUtil.cpp b/Zip/src/ZipUtil.cpp index 069074651..7bdb76dfe 100644 --- a/Zip/src/ZipUtil.cpp +++ b/Zip/src/ZipUtil.cpp @@ -117,31 +117,23 @@ void ZipUtil::sync(std::istream& in) { if (std::memcmp(ZipLocalFileHeader::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0) { - in.putback(ZipLocalFileHeader::HEADER[3]); - in.putback(ZipLocalFileHeader::HEADER[2]); - in.putback(ZipLocalFileHeader::HEADER[1]); - in.putback(ZipLocalFileHeader::HEADER[0]); + in.seekg(-4, std::ios::cur); + if (!in.good()) throw Poco::IOException("Failed to seek on input stream"); } else if (std::memcmp(ZipArchiveInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0) { - in.putback(ZipArchiveInfo::HEADER[3]); - in.putback(ZipArchiveInfo::HEADER[2]); - in.putback(ZipArchiveInfo::HEADER[1]); - in.putback(ZipArchiveInfo::HEADER[0]); + in.seekg(-4, std::ios::cur); + if (!in.good()) throw Poco::IOException("Failed to seek on input stream"); } else if (std::memcmp(ZipFileInfo::HEADER+PREFIX, &temp[tempPos - PREFIX], PREFIX) == 0) { - in.putback(ZipFileInfo::HEADER[3]); - in.putback(ZipFileInfo::HEADER[2]); - in.putback(ZipFileInfo::HEADER[1]); - in.putback(ZipFileInfo::HEADER[0]); + in.seekg(-4, std::ios::cur); + if (!in.good()) throw Poco::IOException("Failed to seek on input stream"); } else { - in.putback(ZipDataInfo::HEADER[3]); - in.putback(ZipDataInfo::HEADER[2]); - in.putback(ZipDataInfo::HEADER[1]); - in.putback(ZipDataInfo::HEADER[0]); + in.seekg(-4, std::ios::cur); + if (!in.good()) throw Poco::IOException("Failed to seek on input stream"); } return; } @@ -149,6 +141,7 @@ void ZipUtil::sync(std::istream& in) { // we have read 2 bytes, should only be one: putback the last char in.putback(temp[tempPos - 1]); + if (!in.good()) throw Poco::IOException("Failed to putback on input stream"); --tempPos; } } From 48862bf08ef04e640a16f5a557656970a126d802 Mon Sep 17 00:00:00 2001 From: Scott Davis Date: Tue, 4 Oct 2016 14:43:01 -0400 Subject: [PATCH 40/40] Use stable_sort to preserve order of IP addresses from DNS --- Net/src/SocketAddress.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Net/src/SocketAddress.cpp b/Net/src/SocketAddress.cpp index 1c2608394..fa5290472 100644 --- a/Net/src/SocketAddress.cpp +++ b/Net/src/SocketAddress.cpp @@ -170,7 +170,7 @@ SocketAddress& SocketAddress::operator = (const SocketAddress& socketAddress) destruct(); if (socketAddress.family() == IPv4) newIPv4(reinterpret_cast(socketAddress.addr())); -#if defined(POCO_HAVE_IPv6) +#if defined(POCO_HAVE_IPv6) else if (socketAddress.family() == IPv6) newIPv6(reinterpret_cast(socketAddress.addr())); #endif @@ -252,7 +252,7 @@ void SocketAddress::init(const std::string& hostAddress, Poco::UInt16 portNumber { #if defined(POCO_HAVE_IPv6) // if we get both IPv4 and IPv6 addresses, prefer IPv4 - std::sort(addresses.begin(), addresses.end(), AFLT()); + std::stable_sort(addresses.begin(), addresses.end(), AFLT()); #endif init(addresses[0], portNumber); } @@ -285,7 +285,7 @@ void SocketAddress::init(const std::string& hostAndPort) std::string port; std::string::const_iterator it = hostAndPort.begin(); std::string::const_iterator end = hostAndPort.end(); - + #if defined(POCO_OS_FAMILY_UNIX) if (*it == '/') {