diff --git a/CHANGELOG b/CHANGELOG index cd69036fe..a0bb3f7ad 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,30 @@ This is the changelog file for the POCO C++ Libraries. +Release 1.7.7 (2016-12-31) +========================== + +- fixed GH #865: FileChannel compress fails leaving empty .gz files +- fixed GH #990: Potential race condition in Poco::File on Windows +- fixed GH #1157: Fixing a bug in the NetSSL_Win module (Host name verification failed error) +- fixed GH #1351: Fix for android include pthread.h from /usr/include +- fixed GH #1436: ODBC Bug: Unicode text(NVARCHAT) read from DB is truncated to half +- fixed GH #1453: _clock_gettime Symbol not found on Mac 10.11 +- fixed GH #1460: POCO does not build with OpenSSL 1.1 +- fixed GH #1461: Poco::Data::SQLite::SQLiteStatementImpl::next() error +- fixed GH #1462: AbstractConfiguration::getUInt does not parse hex numbers +- fixed GH #1464: ODBCMetaColumn::init() always maps integer NUMERIC/DECIMAL to Int32 +- fixed GH #1465: Assertion violation in DateTime.cpp using ZipArchive +- fixed GH #1472: HTTP(S)StreamFactory should send a User-Agent header. +- fixed GH #1476: Fixed error with Poco::UTF8Encoding::isLegal() +- fixed GH #1484: ODBC: fix uninitialized variable +- fixed GH #1486: Support ODBC GUID data type as string +- fixed GH #1488: Poco::ObjectPool shrinks if returned object is not valid +- fixed GH #1515: Detection of closed websocket connection +- fixed GH #1521: bug in JSON ParseHandler.cpp (empty keys should be valid) +- fixed GH #1526: iOS app rejected, IPv6 not working +- fixed GH #1532: RecordSet and RowFilter: bad use of reference counter + + Release 1.7.6 (2016-10-18) ========================== diff --git a/Crypto/include/Poco/Crypto/DigestEngine.h b/Crypto/include/Poco/Crypto/DigestEngine.h index 5de75392a..e2121c414 100644 --- a/Crypto/include/Poco/Crypto/DigestEngine.h +++ b/Crypto/include/Poco/Crypto/DigestEngine.h @@ -61,7 +61,7 @@ protected: private: std::string _name; - EVP_MD_CTX* _ctx; + EVP_MD_CTX* _pContext; Poco::DigestEngine::Digest _digest; OpenSSLInitializer _openSSLInitializer; }; diff --git a/Crypto/src/CipherImpl.cpp b/Crypto/src/CipherImpl.cpp index b115ede8f..b8708a78c 100644 --- a/Crypto/src/CipherImpl.cpp +++ b/Crypto/src/CipherImpl.cpp @@ -77,7 +77,11 @@ namespace private: const EVP_CIPHER* _pCipher; - EVP_CIPHER_CTX _ctx; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_CIPHER_CTX* _pContext; +#else + EVP_CIPHER_CTX _context; +#endif ByteVec _key; ByteVec _iv; }; @@ -92,30 +96,52 @@ namespace _key(key), _iv(iv) { +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + _pContext = EVP_CIPHER_CTX_new(); EVP_CipherInit( - &_ctx, + _pContext, _pCipher, &_key[0], _iv.empty() ? 0 : &_iv[0], (dir == DIR_ENCRYPT) ? 1 : 0); +#else + EVP_CipherInit( + &_context, + _pCipher, + &_key[0], + _iv.empty() ? 0 : &_iv[0], + (dir == DIR_ENCRYPT) ? 1 : 0); +#endif } CryptoTransformImpl::~CryptoTransformImpl() { - EVP_CIPHER_CTX_cleanup(&_ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_CIPHER_CTX_cleanup(_pContext); +#else + EVP_CIPHER_CTX_cleanup(&_context); +#endif } std::size_t CryptoTransformImpl::blockSize() const { - return EVP_CIPHER_CTX_block_size(&_ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + return EVP_CIPHER_CTX_block_size(_pContext); +#else + return EVP_CIPHER_CTX_block_size(&_context); +#endif } int CryptoTransformImpl::setPadding(int padding) { - return EVP_CIPHER_CTX_set_padding(&_ctx, padding); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + return EVP_CIPHER_CTX_block_size(_pContext); +#else + return EVP_CIPHER_CTX_set_padding(&_context, padding); +#endif } @@ -128,13 +154,21 @@ namespace poco_assert (outputLength >= (inputLength + blockSize() - 1)); int outLen = static_cast(outputLength); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L int rc = EVP_CipherUpdate( - &_ctx, + _pContext, output, &outLen, input, static_cast(inputLength)); - +#else + int rc = EVP_CipherUpdate( + &_context, + output, + &outLen, + input, + static_cast(inputLength)); +#endif if (rc == 0) throwError(); @@ -153,7 +187,11 @@ namespace // Use the '_ex' version that does not perform implicit cleanup since we // will call EVP_CIPHER_CTX_cleanup() from the dtor as there is no // guarantee that finalize() will be called if an error occurred. - int rc = EVP_CipherFinal_ex(&_ctx, output, &len); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + int rc = EVP_CipherFinal_ex(_pContext, output, &len); +#else + int rc = EVP_CipherFinal_ex(&_context, output, &len); +#endif if (rc == 0) throwError(); diff --git a/Crypto/src/DigestEngine.cpp b/Crypto/src/DigestEngine.cpp index 6e574ab42..64042589f 100644 --- a/Crypto/src/DigestEngine.cpp +++ b/Crypto/src/DigestEngine.cpp @@ -23,46 +23,51 @@ namespace Crypto { DigestEngine::DigestEngine(const std::string& name): - _name(name) + _name(name), + _pContext(EVP_MD_CTX_create()) { const EVP_MD* md = EVP_get_digestbyname(_name.c_str()); if (!md) throw Poco::NotFoundException(_name); - _ctx = EVP_MD_CTX_create(); - EVP_DigestInit_ex(_ctx, md, NULL); + EVP_DigestInit_ex(_pContext, md, NULL); } DigestEngine::~DigestEngine() { - EVP_MD_CTX_destroy(_ctx); + EVP_MD_CTX_destroy(_pContext); } int DigestEngine::nid() const { - return EVP_MD_nid(_ctx->digest); + return EVP_MD_nid(EVP_MD_CTX_md(_pContext)); } std::size_t DigestEngine::digestLength() const { - return EVP_MD_CTX_size(_ctx); + return EVP_MD_CTX_size(_pContext); } void DigestEngine::reset() { - EVP_MD_CTX_cleanup(_ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_MD_CTX_free(_pContext); + _pContext = EVP_MD_CTX_create(); +#else + EVP_MD_CTX_cleanup(_pContext); +#endif const EVP_MD* md = EVP_get_digestbyname(_name.c_str()); if (!md) throw Poco::NotFoundException(_name); - EVP_DigestInit_ex(_ctx, md, NULL); + EVP_DigestInit_ex(_pContext, md, NULL); } const Poco::DigestEngine::Digest& DigestEngine::digest() { _digest.clear(); - unsigned len = EVP_MD_CTX_size(_ctx); + unsigned len = EVP_MD_CTX_size(_pContext); _digest.resize(len); - EVP_DigestFinal_ex(_ctx, &_digest[0], &len); + EVP_DigestFinal_ex(_pContext, &_digest[0], &len); reset(); return _digest; } @@ -70,7 +75,7 @@ const Poco::DigestEngine::Digest& DigestEngine::digest() void DigestEngine::updateImpl(const void* data, std::size_t length) { - EVP_DigestUpdate(_ctx, data, length); + EVP_DigestUpdate(_pContext, data, length); } diff --git a/Crypto/src/RSAKeyImpl.cpp b/Crypto/src/RSAKeyImpl.cpp index 8333453ce..3a1580f69 100644 --- a/Crypto/src/RSAKeyImpl.cpp +++ b/Crypto/src/RSAKeyImpl.cpp @@ -207,19 +207,43 @@ int RSAKeyImpl::size() const RSAKeyImpl::ByteVec RSAKeyImpl::modulus() const { +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + const BIGNUM* n = 0; + const BIGNUM* e = 0; + const BIGNUM* d = 0; + RSA_get0_key(_pRSA, &n, &e, &d); + return convertToByteVec(n); +#else return convertToByteVec(_pRSA->n); +#endif } RSAKeyImpl::ByteVec RSAKeyImpl::encryptionExponent() const { +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + const BIGNUM* n = 0; + const BIGNUM* e = 0; + const BIGNUM* d = 0; + RSA_get0_key(_pRSA, &n, &e, &d); + return convertToByteVec(e); +#else return convertToByteVec(_pRSA->e); +#endif } RSAKeyImpl::ByteVec RSAKeyImpl::decryptionExponent() const { +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + const BIGNUM* n = 0; + const BIGNUM* e = 0; + const BIGNUM* d = 0; + RSA_get0_key(_pRSA, &n, &e, &d); + return convertToByteVec(d); +#else return convertToByteVec(_pRSA->d); +#endif } diff --git a/Crypto/src/X509Certificate.cpp b/Crypto/src/X509Certificate.cpp index a56cc10d4..f7f37965e 100644 --- a/Crypto/src/X509Certificate.cpp +++ b/Crypto/src/X509Certificate.cpp @@ -59,7 +59,11 @@ X509Certificate::X509Certificate(X509* pCert, bool shared): if (shared) { +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + X509_up_ref(_pCert); +#else _pCert->references++; +#endif } init(); diff --git a/DLLVersion.rc b/DLLVersion.rc index a5def2f2c..8c8f85dbe 100644 --- a/DLLVersion.rc +++ b/DLLVersion.rc @@ -4,8 +4,8 @@ #include "winres.h" -#define POCO_VERSION 1,7,6,0 -#define POCO_VERSION_STR "1.7.6" +#define POCO_VERSION 1,7,7,0 +#define POCO_VERSION_STR "1.7.7" VS_VERSION_INFO VERSIONINFO FILEVERSION POCO_VERSION diff --git a/Data/ODBC/include/Poco/Data/ODBC/Preparator.h b/Data/ODBC/include/Poco/Data/ODBC/Preparator.h index 275777f52..123d021e9 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/Preparator.h +++ b/Data/ODBC/include/Poco/Data/ODBC/Preparator.h @@ -627,7 +627,7 @@ private: (SQLUSMALLINT) pos + 1, valueType, (SQLPOINTER) pCache, - (SQLINTEGER) size, + (SQLINTEGER) size*sizeof(T), &_lengths[pos]))) { throw StatementException(_rStmt, "SQLBindCol()"); @@ -1033,7 +1033,7 @@ inline void Preparator::prepare(std::size_t pos, const std::list& v inline void Preparator::prepare(std::size_t pos, const UTF16String&) { - prepareVariableLen(pos, SQL_C_WCHAR, maxDataSize(pos), DT_CHAR); + prepareVariableLen(pos, SQL_C_WCHAR, maxDataSize(pos), DT_WCHAR); } diff --git a/Data/ODBC/src/ODBCMetaColumn.cpp b/Data/ODBC/src/ODBCMetaColumn.cpp index 2373a525f..5745e6cf5 100644 --- a/Data/ODBC/src/ODBCMetaColumn.cpp +++ b/Data/ODBC/src/ODBCMetaColumn.cpp @@ -87,6 +87,9 @@ void ODBCMetaColumn::init() case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: +#ifdef SQL_GUID + case SQL_GUID: +#endif setType(MetaColumn::FDT_STRING); break; case SQL_WCHAR: @@ -113,12 +116,18 @@ void ODBCMetaColumn::init() case SQL_NUMERIC: case SQL_DECIMAL: if (0 == _columnDesc.decimalDigits) - setType(MetaColumn::FDT_INT32); + { + if (_columnDesc.size > 9) + setType(MetaColumn::FDT_INT64); + else + setType(MetaColumn::FDT_INT32); + } else + { setType(MetaColumn::FDT_DOUBLE); - + } break; - + case SQL_REAL: setType(MetaColumn::FDT_FLOAT); break; diff --git a/Data/ODBC/src/ODBCStatementImpl.cpp b/Data/ODBC/src/ODBCStatementImpl.cpp index 564cfa80e..1e27c281a 100644 --- a/Data/ODBC/src/ODBCStatementImpl.cpp +++ b/Data/ODBC/src/ODBCStatementImpl.cpp @@ -448,7 +448,7 @@ int ODBCStatementImpl::affectedRowCount() const { if (0 == _affectedRowCount) { - SQLLEN rows; + SQLLEN rows = 0; if (!Utility::isError(SQLRowCount(_stmt, &rows))) _affectedRowCount = static_cast(rows); } diff --git a/Data/SQLite/src/SQLiteStatementImpl.cpp b/Data/SQLite/src/SQLiteStatementImpl.cpp index dc6c3778e..ab0690d72 100644 --- a/Data/SQLite/src/SQLiteStatementImpl.cpp +++ b/Data/SQLite/src/SQLiteStatementImpl.cpp @@ -273,7 +273,10 @@ std::size_t SQLiteStatementImpl::next() } _stepCalled = false; if (_affectedRowCount == POCO_SQLITE_INV_ROW_CNT) _affectedRowCount = 0; - _affectedRowCount += (*extracts.begin())->numOfRowsHandled(); + if (extracts.begin() != extracts.end()) + { + _affectedRowCount += (*extracts.begin())->numOfRowsHandled(); + } } else if (SQLITE_DONE == _nextResponse) { diff --git a/Data/include/Poco/Data/RecordSet.h b/Data/include/Poco/Data/RecordSet.h index 6806ea714..d1f46d029 100644 --- a/Data/include/Poco/Data/RecordSet.h +++ b/Data/include/Poco/Data/RecordSet.h @@ -26,10 +26,12 @@ #include "Poco/Data/BulkExtraction.h" #include "Poco/Data/Statement.h" #include "Poco/Data/RowIterator.h" +#include "Poco/Data/RowFilter.h" #include "Poco/Data/LOB.h" #include "Poco/String.h" #include "Poco/Dynamic/Var.h" #include "Poco/Exception.h" +#include "Poco/AutoPtr.h" #include #include @@ -98,7 +100,6 @@ public: _currentRow(0), _pBegin(new RowIterator(this, 0 == rowsExtracted())), _pEnd(new RowIterator(this, true)), - _pFilter(0), _totalRowCount(UNKNOWN_TOTAL_ROW_COUNT) /// Creates the RecordSet. { @@ -471,17 +472,17 @@ private: /// Returns true if the specified row is allowed by the /// currently active filter. - void filter(RowFilter* pFilter); + void filter(const Poco::AutoPtr& pFilter); /// Sets the filter for the RecordSet. - const RowFilter* getFilter() const; + const Poco::AutoPtr& getFilter() const; /// Returns the filter associated with the RecordSet. std::size_t _currentRow; RowIterator* _pBegin; RowIterator* _pEnd; RowMap _rowMap; - RowFilter* _pFilter; + Poco::AutoPtr _pFilter; std::size_t _totalRowCount; friend class RowIterator; @@ -636,7 +637,7 @@ inline RecordSet::Iterator RecordSet::end() } -inline const RowFilter* RecordSet::getFilter() const +inline const Poco::AutoPtr& RecordSet::getFilter() const { return _pFilter; } diff --git a/Data/include/Poco/Data/RowFilter.h b/Data/include/Poco/Data/RowFilter.h index 6ce35c55d..e70156344 100644 --- a/Data/include/Poco/Data/RowFilter.h +++ b/Data/include/Poco/Data/RowFilter.h @@ -21,7 +21,6 @@ #include "Poco/Data/Data.h" -#include "Poco/Data/RecordSet.h" #include "Poco/Dynamic/Var.h" #include "Poco/Tuple.h" #include "Poco/String.h" @@ -36,6 +35,9 @@ namespace Poco { namespace Data { +class RecordSet; + + class Data_API RowFilter: public RefCountedObject /// RowFilter class provides row filtering functionality. /// A filter contains a set of criteria (field name, value and @@ -93,7 +95,7 @@ public: void add(const std::string& name, Comparison comparison, const T& value, LogicOperator op = OP_OR) /// Adds value to the filter. { - if (_pRecordSet) _pRecordSet->moveFirst(); + rewindRecordSet(); _comparisonMap.insert(ComparisonMap::value_type(toUpper(name), ComparisonEntry(value, comparison, op))); } @@ -164,6 +166,8 @@ private: RecordSet& recordSet() const; Comparison getComparison(const std::string& comp) const; + + void rewindRecordSet(); Comparisons _comparisons; ComparisonMap _comparisonMap; diff --git a/Data/src/RecordSet.cpp b/Data/src/RecordSet.cpp index 52cd52b97..071663ed8 100644 --- a/Data/src/RecordSet.cpp +++ b/Data/src/RecordSet.cpp @@ -41,7 +41,6 @@ RecordSet::RecordSet(const Statement& rStatement, _currentRow(0), _pBegin(new RowIterator(this, 0 == rowsExtracted())), _pEnd(new RowIterator(this, true)), - _pFilter(0), _totalRowCount(UNKNOWN_TOTAL_ROW_COUNT) { if (pRowFormatter) setRowFormatter(pRowFormatter); @@ -55,7 +54,6 @@ RecordSet::RecordSet(Session& rSession, _currentRow(0), _pBegin(new RowIterator(this, 0 == rowsExtracted())), _pEnd(new RowIterator(this, true)), - _pFilter(0), _totalRowCount(UNKNOWN_TOTAL_ROW_COUNT) { if (pRowFormatter) setRowFormatter(pRowFormatter); @@ -70,7 +68,6 @@ RecordSet::RecordSet(const RecordSet& other): _pFilter(other._pFilter), _totalRowCount(other._totalRowCount) { - if (_pFilter) _pFilter->duplicate(); } @@ -80,7 +77,6 @@ RecordSet::~RecordSet() { delete _pBegin; delete _pEnd; - if (_pFilter) _pFilter->release(); RowMap::iterator it = _rowMap.begin(); RowMap::iterator end = _rowMap.end(); @@ -377,11 +373,9 @@ std::ostream& RecordSet::copy(std::ostream& os, std::size_t offset, std::size_t } -void RecordSet::filter(RowFilter* pFilter) +void RecordSet::filter(const Poco::AutoPtr& pFilter) { - if (_pFilter) _pFilter->release(); _pFilter = pFilter; - if (_pFilter) _pFilter->duplicate(); } diff --git a/Data/src/RowFilter.cpp b/Data/src/RowFilter.cpp index b5e3ff4fb..3d3de5f47 100644 --- a/Data/src/RowFilter.cpp +++ b/Data/src/RowFilter.cpp @@ -20,6 +20,7 @@ #include "Poco/Exception.h" #include + namespace Poco { namespace Data { @@ -53,8 +54,6 @@ void RowFilter::init() _comparisons.insert(Comparisons::value_type("<>", VALUE_NOT_EQUAL)); _comparisons.insert(Comparisons::value_type("!=", VALUE_NOT_EQUAL)); _comparisons.insert(Comparisons::value_type("IS NULL", VALUE_IS_NULL)); - - duplicate(); } @@ -62,7 +61,6 @@ RowFilter::~RowFilter() { try { - release(); if (_pRecordSet) _pRecordSet->filter(0); if (_pParent.get()) _pParent->removeFilter(this); } @@ -201,6 +199,7 @@ void RowFilter::doCompare(Poco::Dynamic::Var& ret, } } + RecordSet& RowFilter::recordSet() const { if (!_pRecordSet) @@ -214,4 +213,10 @@ RecordSet& RowFilter::recordSet() const } +void RowFilter::rewindRecordSet() +{ + if (_pRecordSet) _pRecordSet->moveFirst(); +} + + } } // namespace Poco::Data diff --git a/Foundation/include/Poco/AtomicCounter.h b/Foundation/include/Poco/AtomicCounter.h index 0554558bb..f8cdb731a 100644 --- a/Foundation/include/Poco/AtomicCounter.h +++ b/Foundation/include/Poco/AtomicCounter.h @@ -24,7 +24,13 @@ #if POCO_OS == POCO_OS_WINDOWS_NT #include "Poco/UnWindows.h" #elif POCO_OS == POCO_OS_MAC_OS_X - #include + #if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_12 || __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_10_0 || __WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0 + #ifndef POCO_HAVE_STD_ATOMICS + #define POCO_HAVE_STD_ATOMICS + #endif + #else + #include + #endif #elif ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2) || __GNUC__ > 4) && (defined(__x86_64__) || defined(__i386__)) #if !defined(POCO_HAVE_GCC_ATOMICS) && !defined(POCO_NO_GCC_ATOMICS) #define POCO_HAVE_GCC_ATOMICS @@ -35,6 +41,9 @@ #endif #endif // POCO_OS #include "Poco/Mutex.h" +#ifdef POCO_HAVE_STD_ATOMICS +#include +#endif namespace Poco { @@ -104,7 +113,9 @@ public: /// Returns true if the counter is zero, false otherwise. private: -#if POCO_OS == POCO_OS_WINDOWS_NT +#if defined(POCO_HAVE_STD_ATOMICS) + typedef std::atomic ImplType; +#elif POCO_OS == POCO_OS_WINDOWS_NT typedef volatile LONG ImplType; #elif POCO_OS == POCO_OS_MAC_OS_X typedef int32_t ImplType; @@ -127,7 +138,53 @@ private: // -#if POCO_OS == POCO_OS_WINDOWS_NT +#if defined(POCO_HAVE_STD_ATOMICS) +// +// C++11 atomics +// +inline AtomicCounter::operator AtomicCounter::ValueType () const +{ + return _counter.load(); +} + + +inline AtomicCounter::ValueType AtomicCounter::value() const +{ + return _counter.load(); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix +{ + return ++_counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix +{ + return _counter++; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix +{ + return --_counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix +{ + return _counter--; +} + + +inline bool AtomicCounter::operator ! () const +{ + return _counter.load() == 0; +} + + +#elif POCO_OS == POCO_OS_WINDOWS_NT // // Windows // diff --git a/Foundation/include/Poco/DeflatingStream.h b/Foundation/include/Poco/DeflatingStream.h index 2def954d3..4502652fd 100644 --- a/Foundation/include/Poco/DeflatingStream.h +++ b/Foundation/include/Poco/DeflatingStream.h @@ -139,7 +139,7 @@ protected: }; -class Foundation_API DeflatingOutputStream: public DeflatingIOS, public std::ostream +class Foundation_API DeflatingOutputStream: public std::ostream, public DeflatingIOS /// This stream compresses all data passing through it /// using zlib's deflate algorithm. /// After all data has been written to the stream, close() @@ -176,7 +176,7 @@ protected: }; -class Foundation_API DeflatingInputStream: public DeflatingIOS, public std::istream +class Foundation_API DeflatingInputStream: public std::istream, public DeflatingIOS /// This stream compresses all data passing through it /// using zlib's deflate algorithm. { diff --git a/Foundation/include/Poco/Exception.h b/Foundation/include/Poco/Exception.h index 2fce85dc3..96bb186aa 100644 --- a/Foundation/include/Poco/Exception.h +++ b/Foundation/include/Poco/Exception.h @@ -248,6 +248,7 @@ POCO_DECLARE_EXCEPTION(Foundation_API, CreateFileException, FileException) 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, DirectoryNotEmptyException, FileException) POCO_DECLARE_EXCEPTION(Foundation_API, UnknownURISchemeException, RuntimeException) POCO_DECLARE_EXCEPTION(Foundation_API, TooManyURIRedirectsException, RuntimeException) POCO_DECLARE_EXCEPTION(Foundation_API, URISyntaxException, SyntaxException) diff --git a/Foundation/include/Poco/InflatingStream.h b/Foundation/include/Poco/InflatingStream.h index ca20cb07e..7f34650cc 100644 --- a/Foundation/include/Poco/InflatingStream.h +++ b/Foundation/include/Poco/InflatingStream.h @@ -143,7 +143,7 @@ protected: }; -class Foundation_API InflatingOutputStream: public InflatingIOS, public std::ostream +class Foundation_API InflatingOutputStream: public std::ostream, public InflatingIOS /// This stream decompresses all data passing through it /// using zlib's inflate algorithm. /// @@ -173,7 +173,7 @@ public: }; -class Foundation_API InflatingInputStream: public InflatingIOS, public std::istream +class Foundation_API InflatingInputStream: public std::istream, public InflatingIOS /// This stream decompresses all data passing through it /// using zlib's inflate algorithm. /// Example: diff --git a/Foundation/include/Poco/ObjectPool.h b/Foundation/include/Poco/ObjectPool.h index a797b0c5f..4e2b1cc33 100644 --- a/Foundation/include/Poco/ObjectPool.h +++ b/Foundation/include/Poco/ObjectPool.h @@ -244,18 +244,18 @@ public: _factory.deactivateObject(pObject); if (_pool.size() < _capacity) { - _pool.push_back(pObject); - } - else - { - _factory.destroyObject(pObject); - _size--; + try + { + _pool.push_back(pObject); + return; + } + catch (...) + { + } } } - else - { - _factory.destroyObject(pObject); - } + _factory.destroyObject(pObject); + _size--; } std::size_t capacity() const diff --git a/Foundation/include/Poco/Version.h b/Foundation/include/Poco/Version.h index 38be95c6f..f4cf1ab7c 100644 --- a/Foundation/include/Poco/Version.h +++ b/Foundation/include/Poco/Version.h @@ -37,7 +37,7 @@ // Ax: alpha releases // Bx: beta releases // -#define POCO_VERSION 0x01070600 +#define POCO_VERSION 0x01070700 #endif // Foundation_Version_INCLUDED diff --git a/Foundation/src/ArchiveStrategy.cpp b/Foundation/src/ArchiveStrategy.cpp index 7491da61f..cc235119a 100644 --- a/Foundation/src/ArchiveStrategy.cpp +++ b/Foundation/src/ArchiveStrategy.cpp @@ -47,28 +47,35 @@ public: { } - ActiveMethod > compress; + ActiveMethod > compress; protected: - Void compressImpl(const std::string& path) + void compressImpl(const std::string& path) { std::string gzPath(path); gzPath.append(".gz"); - FileInputStream istr(path, std::ios::binary | std::ios::in); - if (!istr.good()) throw OpenFileException(path); - FileOutputStream ostr(gzPath, std::ios::binary | std::ios::out); - if (ostr.good()) + FileInputStream istr(path); + FileOutputStream ostr(gzPath); + try { DeflatingOutputStream deflater(ostr, DeflatingStreamBuf::STREAM_GZIP); StreamCopier::copyStream(istr, deflater); + if (!deflater.good() || !ostr.good()) throw WriteFileException(gzPath); deflater.close(); ostr.close(); istr.close(); - File f(path); - f.remove(); } - else throw CreateFileException(gzPath); - return Void(); + catch (Poco::Exception&) + { + // deflating failed - remove gz file and leave uncompressed log file + ostr.close(); + Poco::File gzf(gzPath); + gzf.remove(); + return; + } + File f(path); + f.remove(); + return; } }; diff --git a/Foundation/src/AtomicCounter.cpp b/Foundation/src/AtomicCounter.cpp index 9a858aad5..93cca010f 100644 --- a/Foundation/src/AtomicCounter.cpp +++ b/Foundation/src/AtomicCounter.cpp @@ -20,7 +20,48 @@ namespace Poco { -#if POCO_OS == POCO_OS_WINDOWS_NT +#if defined(POCO_HAVE_STD_ATOMICS) +// +// C++11 atomics +// +AtomicCounter::AtomicCounter(): + _counter(0) +{ +} + + +AtomicCounter::AtomicCounter(AtomicCounter::ValueType initialValue): + _counter(initialValue) +{ +} + + +AtomicCounter::AtomicCounter(const AtomicCounter& counter): + _counter(counter.value()) +{ +} + + +AtomicCounter::~AtomicCounter() +{ +} + + +AtomicCounter& AtomicCounter::operator = (const AtomicCounter& counter) +{ + _counter.store(counter._counter.load()); + return *this; +} + + +AtomicCounter& AtomicCounter::operator = (AtomicCounter::ValueType value) +{ + _counter.store(value); + return *this; +} + + +#elif POCO_OS == POCO_OS_WINDOWS_NT // // Windows // diff --git a/Foundation/src/Clock.cpp b/Foundation/src/Clock.cpp index ac95bfc80..abef10a9a 100644 --- a/Foundation/src/Clock.cpp +++ b/Foundation/src/Clock.cpp @@ -34,6 +34,15 @@ #include +#ifndef POCO_HAVE_CLOCK_GETTIME + #if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__) + #ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac OS 10.12/iOS 10 + #define POCO_HAVE_CLOCK_GETTIME + #endif + #endif +#endif + + namespace Poco { @@ -120,7 +129,7 @@ void Clock::update() #endif _clock = ClockVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000; -#elif (defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)) || defined(__QNX__) +#elif defined(POCO_HAVE_CLOCK_GETTIME) struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts)) diff --git a/Foundation/src/DeflatingStream.cpp b/Foundation/src/DeflatingStream.cpp index 56d7b9146..e68b7ea1e 100644 --- a/Foundation/src/DeflatingStream.cpp +++ b/Foundation/src/DeflatingStream.cpp @@ -334,15 +334,15 @@ DeflatingStreamBuf* DeflatingIOS::rdbuf() DeflatingOutputStream::DeflatingOutputStream(std::ostream& ostr, DeflatingStreamBuf::StreamType type, int level): - DeflatingIOS(ostr, type, level), - std::ostream(&_buf) + std::ostream(&_buf), + DeflatingIOS(ostr, type, level) { } DeflatingOutputStream::DeflatingOutputStream(std::ostream& ostr, int windowBits, int level): - DeflatingIOS(ostr, windowBits, level), - std::ostream(&_buf) + std::ostream(&_buf), + DeflatingIOS(ostr, windowBits, level) { } @@ -365,15 +365,15 @@ int DeflatingOutputStream::sync() DeflatingInputStream::DeflatingInputStream(std::istream& istr, DeflatingStreamBuf::StreamType type, int level): - DeflatingIOS(istr, type, level), - std::istream(&_buf) + std::istream(&_buf), + DeflatingIOS(istr, type, level) { } DeflatingInputStream::DeflatingInputStream(std::istream& istr, int windowBits, int level): - DeflatingIOS(istr, windowBits, level), - std::istream(&_buf) + std::istream(&_buf), + DeflatingIOS(istr, windowBits, level) { } diff --git a/Foundation/src/Event_POSIX.cpp b/Foundation/src/Event_POSIX.cpp index 6b0abbe94..2b183e966 100644 --- a/Foundation/src/Event_POSIX.cpp +++ b/Foundation/src/Event_POSIX.cpp @@ -31,9 +31,18 @@ // availability of non-standard pthread_cond_timedwait_monotonic(). // #ifndef POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT -#if (defined(__linux__) || defined(__QNX__)) && !(defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) -#define POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT 1 + #if (defined(__linux__) || defined(__QNX__)) && !(defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) + #define POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT 1 + #endif #endif + + +#ifndef POCO_HAVE_CLOCK_GETTIME + #if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__) + #ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac OS 10.12/iOS 10 + #define POCO_HAVE_CLOCK_GETTIME + #endif + #endif #endif @@ -127,7 +136,7 @@ bool EventImpl::waitImpl(long milliseconds) abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } -#elif (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) +#elif defined(POCO_HAVE_CLOCK_GETTIME) clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += milliseconds / 1000; abstime.tv_nsec += (milliseconds % 1000)*1000000; diff --git a/Foundation/src/Exception.cpp b/Foundation/src/Exception.cpp index 1dbdf0fa6..5dbe73c2d 100644 --- a/Foundation/src/Exception.cpp +++ b/Foundation/src/Exception.cpp @@ -171,6 +171,7 @@ POCO_IMPLEMENT_EXCEPTION(CreateFileException, FileException, "Cannot create file 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(DirectoryNotEmptyException, FileException, "Directory not empty") 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") diff --git a/Foundation/src/File.cpp b/Foundation/src/File.cpp index abbbae157..3e90d176c 100644 --- a/Foundation/src/File.cpp +++ b/Foundation/src/File.cpp @@ -34,6 +34,7 @@ #else #include "File_VMS.cpp" #endif +#include "Poco/Thread.h" namespace Poco { @@ -269,8 +270,37 @@ void File::remove(bool recursive) { it->remove(true); } + + // Note: On Windows, removing a directory may not succeed at first + // try because deleting files is not a synchronous operation. Files + // are merely marked as deleted, and actually removed at a later time. + // + // An alternate strategy would be moving files to a different directory + // first (on the same drive, but outside the deleted tree), and marking + // them as hidden, before deleting them, but this could lead to other issues. + // So we simply retry after some time until we succeed, or give up. + + int retry = 8; + long sleep = 10; + while (retry > 0) + { + try + { + removeImpl(); + retry = 0; + } + catch (DirectoryNotEmptyException&) + { + if (--retry == 0) throw; + Poco::Thread::sleep(sleep); + sleep *= 2; + } + } + } + else + { + removeImpl(); } - removeImpl(); } diff --git a/Foundation/src/File_UNIX.cpp b/Foundation/src/File_UNIX.cpp index 84a606a65..703ca7ec8 100644 --- a/Foundation/src/File_UNIX.cpp +++ b/Foundation/src/File_UNIX.cpp @@ -434,7 +434,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path) throw FileException("disk quota exceeded", path, errno); #if !defined(_AIX) case ENOTEMPTY: - throw FileException("directory not empty", path, errno); + throw DirectoryNotEmptyException(path, errno); #endif case ENAMETOOLONG: throw PathSyntaxException(path, errno); diff --git a/Foundation/src/File_VMS.cpp b/Foundation/src/File_VMS.cpp index 40880ed29..d875acc9d 100644 --- a/Foundation/src/File_VMS.cpp +++ b/Foundation/src/File_VMS.cpp @@ -375,7 +375,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path) case EDQUOT: throw FileException("disk quota exceeded", path); case ENOTEMPTY: - throw FileException("directory not empty", path); + throw DirectoryNotEmptyException(path, err); case ENAMETOOLONG: throw PathSyntaxException(path); default: diff --git a/Foundation/src/File_VX.cpp b/Foundation/src/File_VX.cpp index 13878f2a6..cc7a2f585 100644 --- a/Foundation/src/File_VX.cpp +++ b/Foundation/src/File_VX.cpp @@ -353,7 +353,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path) case ENOSPC: throw FileException("no space left on device", path); case ENOTEMPTY: - throw FileException("directory not empty", path); + throw DirectoryNotEmptyException(path); case ENAMETOOLONG: throw PathSyntaxException(path); case ENFILE: diff --git a/Foundation/src/File_WIN32.cpp b/Foundation/src/File_WIN32.cpp index 343f80ca0..2fab90265 100644 --- a/Foundation/src/File_WIN32.cpp +++ b/Foundation/src/File_WIN32.cpp @@ -376,7 +376,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path) case ERROR_CANNOT_MAKE: throw CreateFileException(path, err); case ERROR_DIR_NOT_EMPTY: - throw FileException("directory not empty", path, err); + throw DirectoryNotEmptyException(path, err); case ERROR_WRITE_FAULT: throw WriteFileException(path, err); case ERROR_READ_FAULT: diff --git a/Foundation/src/File_WIN32U.cpp b/Foundation/src/File_WIN32U.cpp index 94bc2e553..e6c1b3b3e 100644 --- a/Foundation/src/File_WIN32U.cpp +++ b/Foundation/src/File_WIN32U.cpp @@ -384,7 +384,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path) case ERROR_CANNOT_MAKE: throw CreateFileException(path, err); case ERROR_DIR_NOT_EMPTY: - throw FileException("directory not empty", path, err); + throw DirectoryNotEmptyException(path, err); case ERROR_WRITE_FAULT: throw WriteFileException(path, err); case ERROR_READ_FAULT: diff --git a/Foundation/src/File_WINCE.cpp b/Foundation/src/File_WINCE.cpp index c321a76ee..58bf03fe2 100644 --- a/Foundation/src/File_WINCE.cpp +++ b/Foundation/src/File_WINCE.cpp @@ -374,7 +374,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path) case ERROR_CANNOT_MAKE: throw CreateFileException(path); case ERROR_DIR_NOT_EMPTY: - throw FileException("directory not empty", path); + throw DirectoryNotEmptyException(path); case ERROR_WRITE_FAULT: throw WriteFileException(path); case ERROR_READ_FAULT: diff --git a/Foundation/src/InflatingStream.cpp b/Foundation/src/InflatingStream.cpp index 1eac3fa1a..274c3b79c 100644 --- a/Foundation/src/InflatingStream.cpp +++ b/Foundation/src/InflatingStream.cpp @@ -309,15 +309,15 @@ InflatingStreamBuf* InflatingIOS::rdbuf() InflatingOutputStream::InflatingOutputStream(std::ostream& ostr, InflatingStreamBuf::StreamType type): - InflatingIOS(ostr, type), - std::ostream(&_buf) + std::ostream(&_buf), + InflatingIOS(ostr, type) { } InflatingOutputStream::InflatingOutputStream(std::ostream& ostr, int windowBits): - InflatingIOS(ostr, windowBits), - std::ostream(&_buf) + std::ostream(&_buf), + InflatingIOS(ostr, windowBits) { } @@ -334,15 +334,15 @@ int InflatingOutputStream::close() InflatingInputStream::InflatingInputStream(std::istream& istr, InflatingStreamBuf::StreamType type): - InflatingIOS(istr, type), - std::istream(&_buf) + std::istream(&_buf), + InflatingIOS(istr, type) { } InflatingInputStream::InflatingInputStream(std::istream& istr, int windowBits): - InflatingIOS(istr, windowBits), - std::istream(&_buf) + std::istream(&_buf), + InflatingIOS(istr, windowBits) { } diff --git a/Foundation/src/Mutex_POSIX.cpp b/Foundation/src/Mutex_POSIX.cpp index 09b10bec5..78aacd4f6 100644 --- a/Foundation/src/Mutex_POSIX.cpp +++ b/Foundation/src/Mutex_POSIX.cpp @@ -29,9 +29,18 @@ #if defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS - 200112L) >= 0L -#if defined(_POSIX_THREADS) && (_POSIX_THREADS - 200112L) >= 0L -#define POCO_HAVE_MUTEX_TIMEOUT + #if defined(_POSIX_THREADS) && (_POSIX_THREADS - 200112L) >= 0L + #define POCO_HAVE_MUTEX_TIMEOUT + #endif #endif + + +#ifndef POCO_HAVE_CLOCK_GETTIME + #if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__) + #ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac OS 10.12/iOS 10 + #define POCO_HAVE_CLOCK_GETTIME + #endif + #endif #endif @@ -98,7 +107,7 @@ bool MutexImpl::tryLockImpl(long milliseconds) { #if defined(POCO_HAVE_MUTEX_TIMEOUT) struct timespec abstime; -#if defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME) +#if defined(POCO_HAVE_CLOCK_GETTIME) clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += milliseconds / 1000; abstime.tv_nsec += (milliseconds % 1000)*1000000; diff --git a/Foundation/src/Semaphore_POSIX.cpp b/Foundation/src/Semaphore_POSIX.cpp index 57c5dae15..e602410db 100644 --- a/Foundation/src/Semaphore_POSIX.cpp +++ b/Foundation/src/Semaphore_POSIX.cpp @@ -31,9 +31,18 @@ // availability of non-standard pthread_cond_timedwait_monotonic(). // #ifndef POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT -#if (defined(__linux__) || defined(__QNX__)) && !(defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) -#define POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT 1 + #if (defined(__linux__) || defined(__QNX__)) && !(defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) + #define POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT 1 + #endif #endif + + +#ifndef POCO_HAVE_CLOCK_GETTIME + #if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__) + #ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac OS 10.12/iOS 10 + #define POCO_HAVE_CLOCK_GETTIME + #endif + #endif #endif @@ -127,7 +136,7 @@ bool SemaphoreImpl::waitImpl(long milliseconds) abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } -#elif (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) +#elif defined(POCO_HAVE_CLOCK_GETTIME) clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += milliseconds / 1000; abstime.tv_nsec += (milliseconds % 1000)*1000000; diff --git a/Foundation/src/Timestamp.cpp b/Foundation/src/Timestamp.cpp index bba23aa4f..8a37c9a05 100644 --- a/Foundation/src/Timestamp.cpp +++ b/Foundation/src/Timestamp.cpp @@ -38,6 +38,15 @@ #endif +#ifndef POCO_HAVE_CLOCK_GETTIME + #if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__) + #ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac OS 10.12/iOS 10 + #define POCO_HAVE_CLOCK_GETTIME + #endif + #endif +#endif + + #if defined(_WIN32_WCE) && defined(POCO_WINCE_TIMESTAMP_HACK) @@ -226,7 +235,7 @@ void Timestamp::update() ts.QuadPart -= epoch.QuadPart; _ts = ts.QuadPart/10; -#elif (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__) +#elif defined(POCO_HAVE_CLOCK_GETTIME) struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts)) diff --git a/Foundation/src/UTF8Encoding.cpp b/Foundation/src/UTF8Encoding.cpp index 1ebebdfd5..d4d055701 100644 --- a/Foundation/src/UTF8Encoding.cpp +++ b/Foundation/src/UTF8Encoding.cpp @@ -224,23 +224,23 @@ bool UTF8Encoding::isLegal(const unsigned char *bytes, int length) case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; case 2: - if ((a = (*--srcptr)) > 0xBF) return false; - switch (*bytes) + a = (*--srcptr); + switch (*bytes) { case 0xE0: - if (a < 0xA0) return false; + if (a < 0xA0 || a > 0xBF) return false; break; case 0xED: - if (a > 0x9F) return false; + if (a < 0x80 || a > 0x9F) return false; break; case 0xF0: - if (a < 0x90) return false; + if (a < 0x90 || a > 0xBF) return false; break; case 0xF4: - if (a > 0x8F) return false; + if (a < 0x80 || a > 0x8F) return false; break; default: - if (a < 0x80) return false; + if (a < 0x80 || a > 0xBF) return false; } case 1: if (*bytes >= 0x80 && *bytes < 0xC2) return false; diff --git a/JSON/src/ParseHandler.cpp b/JSON/src/ParseHandler.cpp index 74296493a..30c8ece07 100644 --- a/JSON/src/ParseHandler.cpp +++ b/JSON/src/ParseHandler.cpp @@ -133,7 +133,6 @@ void ParseHandler::setValue(const Var& value) } else if ( parent.type() == typeid(Object::Ptr) ) { - poco_assert_dbg(!_key.empty()); Object::Ptr obj = parent.extract(); obj->set(_key, value); _key.clear(); diff --git a/JSON/testsuite/src/JSONTest.cpp b/JSON/testsuite/src/JSONTest.cpp index 1a8126fde..a63b63cd2 100644 --- a/JSON/testsuite/src/JSONTest.cpp +++ b/JSON/testsuite/src/JSONTest.cpp @@ -369,6 +369,37 @@ void JSONTest::testEmptyObject() } +void JSONTest::testEmptyPropertyName() +{ + std::string json = "{\"\": 42}"; + Parser parser; + Var result; + + try + { + result = parser.parse(json); + } + catch(JSONException& jsone) + { + std::cout << jsone.message() << std::endl; + assert(false); + } + + assert(result.type() == typeid(Object::Ptr)); + + Object::Ptr object = result.extract(); + assert(object->size() == 1); + + DynamicStruct ds = *object; + assert (ds.size() == 1); + + const DynamicStruct& rds = *object; + assert (rds.size() == 1); + + assert (ds[""] == 42); +} + + void JSONTest::testComplexObject() { std::string json = @@ -1822,6 +1853,7 @@ CppUnit::Test* JSONTest::suite() #endif CppUnit_addTest(pSuite, JSONTest, testStringProperty); CppUnit_addTest(pSuite, JSONTest, testEmptyObject); + CppUnit_addTest(pSuite, JSONTest, testEmptyPropertyName); CppUnit_addTest(pSuite, JSONTest, testComplexObject); CppUnit_addTest(pSuite, JSONTest, testDoubleProperty); CppUnit_addTest(pSuite, JSONTest, testDouble2Property); diff --git a/JSON/testsuite/src/JSONTest.h b/JSON/testsuite/src/JSONTest.h index e705bf4bb..cfad2582e 100644 --- a/JSON/testsuite/src/JSONTest.h +++ b/JSON/testsuite/src/JSONTest.h @@ -46,6 +46,7 @@ public: #endif void testStringProperty(); void testEmptyObject(); + void testEmptyPropertyName(); void testComplexObject(); void testDoubleProperty(); void testDouble2Property(); diff --git a/Net/samples/WebSocketServer/src/WebSocketServer.cpp b/Net/samples/WebSocketServer/src/WebSocketServer.cpp index 440ab7d5d..8e067129e 100644 --- a/Net/samples/WebSocketServer/src/WebSocketServer.cpp +++ b/Net/samples/WebSocketServer/src/WebSocketServer.cpp @@ -119,7 +119,7 @@ public: app.logger().information(Poco::format("Frame received (length=%d, flags=0x%x).", n, unsigned(flags))); ws.sendFrame(buffer, n, flags); } - while (n > 0 || (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE); + while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE); app.logger().information("WebSocket connection closed."); } catch (WebSocketException& exc) diff --git a/Net/src/HTTPStreamFactory.cpp b/Net/src/HTTPStreamFactory.cpp index a7b14ce31..708ad7acf 100644 --- a/Net/src/HTTPStreamFactory.cpp +++ b/Net/src/HTTPStreamFactory.cpp @@ -26,6 +26,8 @@ #include "Poco/UnbufferedStreamBuf.h" #include "Poco/NullStream.h" #include "Poco/StreamCopier.h" +#include "Poco/Format.h" +#include "Poco/Version.h" using Poco::URIStreamFactory; @@ -115,6 +117,12 @@ std::istream* HTTPStreamFactory::open(const URI& uri) cred.authenticate(req, res); } + req.set("User-Agent", Poco::format("poco/%d.%d.%d", + (POCO_VERSION >> 24) & 0xFF, + (POCO_VERSION >> 16) & 0xFF, + (POCO_VERSION >> 8) & 0xFF)); + req.set("Accept", "*/*"); + pSession->sendRequest(req); std::istream& rs = pSession->receiveResponse(res); bool moved = (res.getStatus() == HTTPResponse::HTTP_MOVED_PERMANENTLY || diff --git a/Net/src/MailMessage.cpp b/Net/src/MailMessage.cpp index 3fa4641ba..a0c23dbf6 100644 --- a/Net/src/MailMessage.cpp +++ b/Net/src/MailMessage.cpp @@ -119,6 +119,13 @@ namespace pPS->headers().set(it->first, it->second); } + + if (contentDisp.empty()) + { + _pMsg->addContent(pPS, cte); + added = true; + } + if (!added) delete pPS; } } diff --git a/NetSSL_OpenSSL/src/Context.cpp b/NetSSL_OpenSSL/src/Context.cpp index aa5e314ab..c386c4047 100644 --- a/NetSSL_OpenSSL/src/Context.cpp +++ b/NetSSL_OpenSSL/src/Context.cpp @@ -494,6 +494,17 @@ void Context::initDH(const std::string& dhParamsFile) std::string msg = Utility::getLastError(); throw SSLContextException("Error creating Diffie-Hellman parameters", msg); } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + BIGNUM* p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0); + BIGNUM* g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0); + DH_set0_pqg(dh, p, 0, g); + DH_set_length(dh, 160); + if (!p || !g) + { + DH_free(dh); + throw SSLContextException("Error creating Diffie-Hellman parameters"); + } +#else dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0); dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0); dh->length = 160; @@ -502,6 +513,7 @@ void Context::initDH(const std::string& dhParamsFile) DH_free(dh); throw SSLContextException("Error creating Diffie-Hellman parameters"); } +#endif } SSL_CTX_set_tmp_dh(_pSSLContext, dh); SSL_CTX_set_options(_pSSLContext, SSL_OP_SINGLE_DH_USE); diff --git a/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp b/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp index 67296cd6d..d0438486d 100644 --- a/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp +++ b/NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp @@ -26,6 +26,8 @@ #include "Poco/UnbufferedStreamBuf.h" #include "Poco/NullStream.h" #include "Poco/StreamCopier.h" +#include "Poco/Format.h" +#include "Poco/Version.h" using Poco::URIStreamFactory; @@ -118,6 +120,12 @@ std::istream* HTTPSStreamFactory::open(const URI& uri) cred.authenticate(req, res); } + req.set("User-Agent", Poco::format("poco/%d.%d.%d", + (POCO_VERSION >> 24) & 0xFF, + (POCO_VERSION >> 16) & 0xFF, + (POCO_VERSION >> 8) & 0xFF)); + req.set("Accept", "*/*"); + pSession->sendRequest(req); std::istream& rs = pSession->receiveResponse(res); bool moved = (res.getStatus() == HTTPResponse::HTTP_MOVED_PERMANENTLY || diff --git a/PocoDoc/cfg/mkdoc-poco.xml b/PocoDoc/cfg/mkdoc-poco.xml index 3ae5021a8..609c2f739 100644 --- a/PocoDoc/cfg/mkdoc-poco.xml +++ b/PocoDoc/cfg/mkdoc-poco.xml @@ -28,7 +28,7 @@ ${PocoBuild}/*/doc/images - g++ + clang++ ${Includes}, -I/usr/local/mysql/include, @@ -36,7 +36,10 @@ -D_DEBUG, -E, -C, - -DPOCO_NO_GCC_API_ATTRIBUTE + -DPOCO_NO_GCC_API_ATTRIBUTE, + -xc++ + -std=c++11, + -stdlib=libc++ true diff --git a/PocoDoc/src/DocWriter.cpp b/PocoDoc/src/DocWriter.cpp index 112f44e06..197975002 100644 --- a/PocoDoc/src/DocWriter.cpp +++ b/PocoDoc/src/DocWriter.cpp @@ -48,7 +48,8 @@ using namespace Poco::CppParser; std::string DocWriter::_language; DocWriter::StringMap DocWriter::_strings; Poco::Logger* DocWriter::_pLogger(0); -const std::string DocWriter::RFC_URI("http://www.ietf.org/rfc/rfc"); +const std::string DocWriter::RFC_URI("https://www.ietf.org/rfc/rfc"); +const std::string DocWriter::GITHUB_POCO_URI("https://github.com/pocoproject/poco"); DocWriter::DocWriter(const NameSpace::SymbolTable& symbols, const std::string& path, bool prettifyCode, bool noFrames): @@ -1133,6 +1134,39 @@ void DocWriter::writeText(std::ostream& ostr, std::string::const_iterator begin, } begin = it; } + if (token == "GH") + { + std::string uri(GITHUB_POCO_URI); + std::string::const_iterator it(begin); + std::string spc; + nextToken(begin, end, spc); + if (spc == ":") + { + std::string proj; + nextToken(begin, end, proj); + uri = projectURI(proj); + nextToken(begin, end, spc); + } + if (spc == " ") + { + std::string hash; + nextToken(begin, end, hash); + if (hash == "#") + { + std::string n; + nextToken(begin, end, n); + if (!n.empty() && std::isdigit(n[0])) + { + uri += "/issues/"; + uri += n; + writeTargetLink(ostr, uri, token + " #" + n, "_blank"); + nextToken(begin, end, token); + continue; + } + } + } + begin = it; + } if (token == "http") { std::string::const_iterator it(begin); @@ -2233,17 +2267,22 @@ void DocWriter::writeTOC(std::ostream& ostr, const TOC& toc) ostr << "
" << std::endl; ostr << "
  • " << tr("TOC") << std::endl; int lastLevel = 0; + std::vector levelStack; + levelStack.push_back(0); for (TOC::const_iterator it = toc.begin(); it != toc.end(); ++it) { int level = it->level; - if (level > lastLevel) + if (level > levelStack.back()) { + levelStack.push_back(level); ostr << "
      " << std::endl; } - else if (level < lastLevel) + else if (level < levelStack.back()) { - for (int i = level; i < lastLevel; i++) + ostr << "" << std::endl; + while (level < levelStack.back()) { + levelStack.pop_back(); ostr << "
  • " << std::endl; } } @@ -2254,11 +2293,12 @@ void DocWriter::writeTOC(std::ostream& ostr, const TOC& toc) ostr << "
  • id << "\">" << htmlize(it->title) << "" << std::endl; lastLevel = level; } - while (lastLevel-- > 1) + while (!levelStack.empty()) { ostr << "
" << std::endl; + levelStack.pop_back(); } - ostr << "
" << std::endl; + ostr << "" << std::endl; } @@ -2370,3 +2410,18 @@ void DocWriter::loadStrings(const std::string& language) loadString("Types", "Types", language); loadString("Variables", "Variables", language); } + + +std::string DocWriter::projectURI(const std::string& proj) +{ + Application& app = Application::instance(); + std::string key("PocoDoc.projects."); + key += proj; + std::string uri = app.config().getString(key, ""); + if (uri.empty()) + { + app.logger().warning("No project URI found for %s", proj); + uri = GITHUB_POCO_URI; + } + return uri; +} diff --git a/PocoDoc/src/DocWriter.h b/PocoDoc/src/DocWriter.h index 8a2c33e07..57877a4d1 100644 --- a/PocoDoc/src/DocWriter.h +++ b/PocoDoc/src/DocWriter.h @@ -187,10 +187,12 @@ protected: static const std::string& tr(const std::string& id); static void loadStrings(const std::string& language); static void loadString(const std::string& id, const std::string& def, const std::string& language); + static std::string projectURI(const std::string& id); static Poco::Logger& logger(); static const std::string RFC_URI; + static const std::string GITHUB_POCO_URI; private: bool _prettifyCode; diff --git a/Util/include/Poco/Util/AbstractConfiguration.h b/Util/include/Poco/Util/AbstractConfiguration.h index 4cc09cf07..d1e746793 100644 --- a/Util/include/Poco/Util/AbstractConfiguration.h +++ b/Util/include/Poco/Util/AbstractConfiguration.h @@ -346,7 +346,7 @@ protected: /// implementation throws a Poco::NotImplementedException. static int parseInt(const std::string& value); - static int parseUInt(const std::string& value); + static unsigned parseUInt(const std::string& value); #if defined(POCO_HAVE_INT64) diff --git a/Util/src/AbstractConfiguration.cpp b/Util/src/AbstractConfiguration.cpp index d9981ead2..6b4f07f37 100644 --- a/Util/src/AbstractConfiguration.cpp +++ b/Util/src/AbstractConfiguration.cpp @@ -147,7 +147,7 @@ unsigned AbstractConfiguration::getUInt(const std::string& key) const std::string value; if (getRaw(key, value)) - return NumberParser::parseUnsigned(internalExpand(value)); + return parseUInt(internalExpand(value)); else throw NotFoundException(key); } @@ -159,7 +159,7 @@ unsigned AbstractConfiguration::getUInt(const std::string& key, unsigned default std::string value; if (getRaw(key, value)) - return NumberParser::parseUnsigned(internalExpand(value)); + return parseUInt(internalExpand(value)); else return defaultValue; } @@ -174,7 +174,7 @@ Int64 AbstractConfiguration::getInt64(const std::string& key) const std::string value; if (getRaw(key, value)) - return NumberParser::parse64(internalExpand(value)); + return parseInt64(internalExpand(value)); else throw NotFoundException(key); } @@ -186,7 +186,7 @@ Int64 AbstractConfiguration::getInt64(const std::string& key, Int64 defaultValue std::string value; if (getRaw(key, value)) - return NumberParser::parse64(internalExpand(value)); + return parseInt64(internalExpand(value)); else return defaultValue; } @@ -198,7 +198,7 @@ UInt64 AbstractConfiguration::getUInt64(const std::string& key) const std::string value; if (getRaw(key, value)) - return NumberParser::parseUnsigned64(internalExpand(value)); + return parseUInt64(internalExpand(value)); else throw NotFoundException(key); } @@ -210,7 +210,7 @@ UInt64 AbstractConfiguration::getUInt64(const std::string& key, UInt64 defaultVa std::string value; if (getRaw(key, value)) - return NumberParser::parseUnsigned64(internalExpand(value)); + return parseUInt64(internalExpand(value)); else return defaultValue; } @@ -462,13 +462,13 @@ std::string AbstractConfiguration::uncheckedExpand(const std::string& value) con int AbstractConfiguration::parseInt(const std::string& value) { if ((value.compare(0, 2, "0x") == 0) || (value.compare(0, 2, "0X") == 0)) - return NumberParser::parseHex(value); + return static_cast(NumberParser::parseHex(value)); else return NumberParser::parse(value); } -int AbstractConfiguration::parseUInt(const std::string& value) +unsigned AbstractConfiguration::parseUInt(const std::string& value) { if ((value.compare(0, 2, "0x") == 0) || (value.compare(0, 2, "0X") == 0)) return NumberParser::parseHex(value); @@ -480,7 +480,7 @@ int AbstractConfiguration::parseUInt(const std::string& value) Int64 AbstractConfiguration::parseInt64(const std::string& value) { if ((value.compare(0, 2, "0x") == 0) || (value.compare(0, 2, "0X") == 0)) - return NumberParser::parseHex64(value); + return static_cast(NumberParser::parseHex64(value)); else return NumberParser::parse64(value); } diff --git a/Util/testsuite/src/AbstractConfigurationTest.cpp b/Util/testsuite/src/AbstractConfigurationTest.cpp index c74ca5c0d..fef002ee1 100644 --- a/Util/testsuite/src/AbstractConfigurationTest.cpp +++ b/Util/testsuite/src/AbstractConfigurationTest.cpp @@ -89,6 +89,7 @@ void AbstractConfigurationTest::testGetInt() assert (pConf->getInt("prop4.int1") == 42); assert (pConf->getInt("prop4.int2") == -42); assert (pConf->getInt("prop4.hex") == 0x1f); + assert (pConf->getUInt("prop4.hex") == 0x1f); assert (pConf->getInt("ref2") == 42); try @@ -114,6 +115,8 @@ void AbstractConfigurationTest::testGetInt64() assert (pConf->getInt64("prop4.bigint1") == std::numeric_limits::max()); assert (pConf->getInt64("prop4.bigint2") == std::numeric_limits::min()); assert (pConf->getUInt64("prop4.biguint") == std::numeric_limits::max()); + assert (pConf->getInt64("prop4.hex") == 0x1f); + assert (pConf->getUInt64("prop4.hex") == 0x1f); assert (pConf->getInt64("ref2") == 42); try diff --git a/VERSION b/VERSION index de28578af..91c74a589 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7.6 +1.7.7 diff --git a/Zip/src/ZipUtil.cpp b/Zip/src/ZipUtil.cpp index 7bdb76dfe..1aa6d3bdc 100644 --- a/Zip/src/ZipUtil.cpp +++ b/Zip/src/ZipUtil.cpp @@ -31,31 +31,33 @@ Poco::DateTime ZipUtil::parseDateTime(const char* pVal, const Poco::UInt32 timeP { Poco::UInt16 time = ZipUtil::get16BitValue(pVal, timePos); Poco::UInt16 date = ZipUtil::get16BitValue(pVal, datePos); - //TIME: second 0-4, minute 5-10, hour 11-15, second resolution is 2! - int sec = 2*(time & 0x001fu); // 0000 0000 0001 1111 - int min = ((time & 0x07e0u) >> 5); // 0000 0111 1110 0000 - int hour= ((time & 0xf800u) >> 11); // 1111 1000 0000 0000 + // TIME: second 0-4, minute 5-10, hour 11-15, second resolution is 2! + int sec = 2*(time & 0x001fu); // 0000 0000 0001 1111 + int min = ((time & 0x07e0u) >> 5); // 0000 0111 1110 0000 + int hour = ((time & 0xf800u) >> 11); // 1111 1000 0000 0000 - //DATE: day 0-4, month 5-8, year (starting with 1980): 9-16 - int day = (date & 0x001fu); // 0000 0000 0001 1111 - int mon = ((date & 0x01e0u) >> 5); // 0000 0001 1110 0000 - int year= 1980+((date & 0xfe00u) >> 9); // 1111 1110 0000 0000 - return Poco::DateTime(year, mon, day, hour, min, sec); + // DATE: day 0-4, month 5-8, year (starting with 1980): 9-16 + int day = (date & 0x001fu); // 0000 0000 0001 1111 + int mon = ((date & 0x01e0u) >> 5); // 0000 0001 1110 0000 + int year = 1980+((date & 0xfe00u) >> 9); // 1111 1110 0000 0000 + + if (Poco::DateTime::isValid(year, mon, day, hour, min, sec)) + return Poco::DateTime(year, mon, day, hour, min, sec); + else + return Poco::DateTime(1970, 01, 01); } void ZipUtil::setDateTime(const Poco::DateTime& dt, char* pVal, const Poco::UInt32 timePos, const Poco::UInt32 datePos) { - //TIME: second 0-4, minute 5-10, hour 11-15 + // TIME: second 0-4, minute 5-10, hour 11-15 Poco::UInt16 time = static_cast((dt.second()/2) + (dt.minute()<<5) + (dt.hour()<<11)); - //DATE: day 0-4, month 5-8, year (starting with 1980): 9-16 + // DATE: day 0-4, month 5-8, year (starting with 1980): 9-16 int year = dt.year() - 1980; - if (year<0) - year = 0; + if (year < 0) year = 0; Poco::UInt16 date = static_cast(dt.day() + (dt.month()<<5) + (year<<9)); ZipUtil::set16BitValue(time, pVal, timePos); ZipUtil::set16BitValue(date, pVal, datePos); - } diff --git a/build/config/AppleTV b/build/config/AppleTV index 4f68d8bab..b20d1bbf7 100644 --- a/build/config/AppleTV +++ b/build/config/AppleTV @@ -90,7 +90,7 @@ RELEASEOPT_LINK = # # System Specific Flags # -SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES -DPOCO_NO_FORK_EXEC +SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_SOCKETADDRESS_DONT_PREFER_IPV4 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES -DPOCO_NO_FORK_EXEC # # System Specific Libraries diff --git a/build/config/Darwin b/build/config/Darwin index d611ed60e..7ae2baf65 100644 --- a/build/config/Darwin +++ b/build/config/Darwin @@ -9,4 +9,4 @@ # Use the Darwin32 build configuration to build 32-bit binaries. # -include $(POCO_BASE)/build/config/Darwin-clang +include $(POCO_BASE)/build/config/Darwin-clang-libc++ diff --git a/build/config/Darwin-clang b/build/config/Darwin-clang index acfd32c08..26a1df86f 100644 --- a/build/config/Darwin-clang +++ b/build/config/Darwin-clang @@ -29,8 +29,8 @@ endif # # Tools # -CC = clang -CXX = clang++ +CC = $(shell xcrun -find clang) +CXX = $(shell xcrun -find clang++) LINK = $(CXX) -bind_at_load LIB = libtool -static -o RANLIB = ranlib diff --git a/build/config/Darwin-clang-libc++ b/build/config/Darwin-clang-libc++ index f3e1f793c..781decdd8 100644 --- a/build/config/Darwin-clang-libc++ +++ b/build/config/Darwin-clang-libc++ @@ -18,7 +18,7 @@ LINKMODE ?= SHARED POCO_TARGET_OSARCH ?= x86_64 POCO_HOST_OSARCH := $(POCO_TARGET_OSARCH) -ARCHFLAGS ?= -arch $(POCO_TARGET_OSARCH) +ARCHFLAGS ?= -arch $(POCO_TARGET_OSARCH) OPENSSL_DIR ?= /usr/local/opt/openssl/ @@ -79,4 +79,4 @@ SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_NO_STAT64 -I$(OPENSSL_DIR)/include # # System Specific Libraries # -SYSLIBS = -L$(OPENSSL_DIR)/lib -ldl +SYSLIBS = -L$(OPENSSL_DIR)/lib -ldl diff --git a/build/config/WatchOS b/build/config/WatchOS index d576e0235..da5e5b4ae 100644 --- a/build/config/WatchOS +++ b/build/config/WatchOS @@ -90,7 +90,7 @@ RELEASEOPT_LINK = # # System Specific Flags # -SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES -DPOCO_NO_FORK_EXEC +SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_SOCKETADDRESS_DONT_PREFER_IPV4 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES -DPOCO_NO_FORK_EXEC # # System Specific Libraries diff --git a/build/config/iPhone b/build/config/iPhone index 43ea321c5..5cea4d1e6 100644 --- a/build/config/iPhone +++ b/build/config/iPhone @@ -1,5 +1,5 @@ # -# $Id: //poco/1.4/build/config/iPhone#4 $ +# $Id: //poco/1.4/build/config/iPhone#2 $ # # iPhone # @@ -23,24 +23,25 @@ LINKMODE ?= STATIC # Otherwise use the version found. IPHONE_SDK ?= iPhoneOS -IPHONE_SDK_ROOT = $(shell xcode-select -print-path)/Platforms/$(IPHONE_SDK).platform/Developer/SDKs +IPHONE_SDK_ROOT ?= $(shell xcode-select -print-path)/Platforms/$(IPHONE_SDK).platform/Developer/SDKs IPHONE_SDK_ROOT_DIR = $(IPHONE_SDK_ROOT)/$(IPHONE_SDK) IPHONE_SDK_BASE = $(shell ls -d $(IPHONE_SDK_ROOT_DIR)$(IPHONE_SDK_VERSION)*.sdk | tail -1) IPHONE_SDK_VERSION_MIN ?= $(patsubst %.sdk,%,$(patsubst $(IPHONE_SDK_ROOT_DIR)%,%,$(IPHONE_SDK_BASE))) POCO_TARGET_OSNAME ?= $(IPHONE_SDK) -POCO_TARGET_OSARCH ?= armv6 -TOOL_PREFIX ?= /Developer/Platforms/$(IPHONE_SDK).platform/Developer/usr/bin -OSFLAGS ?= -arch $(POCO_TARGET_OSARCH) -isysroot $(IPHONE_SDK_BASE) -mthumb -miphoneos-version-min=$(IPHONE_SDK_VERSION_MIN) -fembed-bitcode +POCO_TARGET_OSARCH ?= arm64 +TOOL_PREFIX ?= $(shell xcode-select -print-path)/Platforms/$(IPHONE_SDK).platform/Developer/usr/bin +ifneq ($(POCO_TARGET_OSARCH),arm64) +THUMB = -mthumb +endif +OSFLAGS ?= -arch $(POCO_TARGET_OSARCH) -isysroot $(IPHONE_SDK_BASE) $(THUMB) -miphoneos-version-min=$(IPHONE_SDK_VERSION_MIN) # # Tools # -# If GCC_VER is defined then use it. -# Otherwise select the latest version -# -CC = $(shell ls $(TOOL_PREFIX)/llvm-gcc-$(GCC_VER)* | tail -1) -CXX = $(shell ls $(TOOL_PREFIX)/llvm-g++-$(GCC_VER)* | tail -1) + +CC = $(shell xcrun -find clang) +CXX = $(shell xcrun -find clang++) LINK = $(CXX) -bind_at_load LIB = libtool -static -o @@ -67,10 +68,10 @@ SHAREDLIBLINKEXT = .dylib CFLAGS = $(OSFLAGS) CFLAGS32 = CFLAGS64 = -CXXFLAGS = $(OSFLAGS) -Wall -Wno-sign-compare +CXXFLAGS = $(OSFLAGS) -std=gnu++11 -stdlib=libc++ -Wall -Wno-sign-compare CXXFLAGS32 = CXXFLAGS64 = -LINKFLAGS = $(OSFLAGS) +LINKFLAGS = $(OSFLAGS) -stdlib=libc++ LINKFLAGS32 = LINKFLAGS64 = STATICOPT_CC = @@ -89,7 +90,7 @@ RELEASEOPT_LINK = # # System Specific Flags # -SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS +SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_SOCKETADDRESS_DONT_PREFER_IPV4 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES # # System Specific Libraries diff --git a/build/config/iPhone-clang b/build/config/iPhone-clang index d40b457a9..76b8f2b55 100644 --- a/build/config/iPhone-clang +++ b/build/config/iPhone-clang @@ -6,96 +6,4 @@ # Build settings for iPhone OS, using Apple's iPhone SDK # -# -# General Settings -# -# iPhone OS does not allow dynamic linking to user libraries -# -LINKMODE ?= STATIC - -# -# If the SDK is defined use it -# Otherwise find the latest version installed -# -# IPHONE_SDK_VERSION = 2.2.1 - -# if IPHONE_SDK_VERSION_MIN is defined use that -# Otherwise use the version found. - -IPHONE_SDK ?= iPhoneOS -IPHONE_SDK_ROOT ?= $(shell xcode-select -print-path)/Platforms/$(IPHONE_SDK).platform/Developer/SDKs -IPHONE_SDK_ROOT_DIR = $(IPHONE_SDK_ROOT)/$(IPHONE_SDK) -IPHONE_SDK_BASE = $(shell ls -d $(IPHONE_SDK_ROOT_DIR)$(IPHONE_SDK_VERSION)*.sdk | tail -1) -IPHONE_SDK_VERSION_MIN ?= $(patsubst %.sdk,%,$(patsubst $(IPHONE_SDK_ROOT_DIR)%,%,$(IPHONE_SDK_BASE))) - -POCO_TARGET_OSNAME ?= $(IPHONE_SDK) -POCO_TARGET_OSARCH ?= armv7 -TOOL_PREFIX ?= $(shell xcode-select -print-path)/Platforms/$(IPHONE_SDK).platform/Developer/usr/bin -ifneq ($(POCO_TARGET_OSARCH),arm64) -THUMB = -mthumb -endif -OSFLAGS ?= -arch $(POCO_TARGET_OSARCH) -isysroot $(IPHONE_SDK_BASE) $(THUMB) -miphoneos-version-min=$(IPHONE_SDK_VERSION_MIN) - -# -# Tools -# -# If GCC_VER is defined then use it. -# Otherwise select the latest version -# - -CC = $(shell xcrun -find clang) -CXX = $(shell xcrun -find clang++) - -LINK = $(CXX) -bind_at_load -LIB = libtool -static -o -RANLIB = ranlib -SHLIB = $(CXX) $(OSFLAGS) -dynamiclib -Wl,-install_name,$@ -o $@ -DYLIB = $(CXX) $(OSFLAGS) -dynamic -bundle -read_only_relocs suppress -Wl,-bind_at_load -o $@ -SHLIBLN = $(POCO_BASE)/build/script/shlibln -STRIP = -DEP = $(POCO_BASE)/build/script/makedepend.gcc -SHELL = sh -RM = rm -rf -CP = cp -MKDIR = mkdir -p - -# -# Extension for Shared Libraries -# -SHAREDLIBEXT = .$(target_version).dylib -SHAREDLIBLINKEXT = .dylib - -# -# Compiler and Linker Flags -# -CFLAGS = $(OSFLAGS) -CFLAGS32 = -CFLAGS64 = -CXXFLAGS = $(OSFLAGS) -Wall -Wno-sign-compare -CXXFLAGS32 = -CXXFLAGS64 = -LINKFLAGS = $(OSFLAGS) -LINKFLAGS32 = -LINKFLAGS64 = -STATICOPT_CC = -STATICOPT_CXX = -STATICOPT_LINK = -SHAREDOPT_CC = -fPIC -SHAREDOPT_CXX = -fPIC -SHAREDOPT_LINK = -DEBUGOPT_CC = -g -D_DEBUG=$(DEBUGLEVEL) -DEBUGOPT_CXX = -g -D_DEBUG=$(DEBUGLEVEL) -DEBUGOPT_LINK = -RELEASEOPT_CC = -DNDEBUG -O2 -RELEASEOPT_CXX = -DNDEBUG -O -RELEASEOPT_LINK = - -# -# System Specific Flags -# -SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES - -# -# System Specific Libraries -# -SYSLIBS = -ldl +include $(POCO_BASE)/build/config/iPhone diff --git a/build/config/iPhone-clang-libc++ b/build/config/iPhone-clang-libc++ index cc39b97b4..c9b47a121 100644 --- a/build/config/iPhone-clang-libc++ +++ b/build/config/iPhone-clang-libc++ @@ -6,96 +6,4 @@ # Build settings for iPhone OS, using Apple's iPhone SDK # -# -# General Settings -# -# iPhone OS does not allow dynamic linking to user libraries -# -LINKMODE ?= STATIC - -# -# If the SDK is defined use it -# Otherwise find the latest version installed -# -# IPHONE_SDK_VERSION = 2.2.1 - -# if IPHONE_SDK_VERSION_MIN is defined use that -# Otherwise use the version found. - -IPHONE_SDK ?= iPhoneOS -IPHONE_SDK_ROOT ?= $(shell xcode-select -print-path)/Platforms/$(IPHONE_SDK).platform/Developer/SDKs -IPHONE_SDK_ROOT_DIR = $(IPHONE_SDK_ROOT)/$(IPHONE_SDK) -IPHONE_SDK_BASE = $(shell ls -d $(IPHONE_SDK_ROOT_DIR)$(IPHONE_SDK_VERSION)*.sdk | tail -1) -IPHONE_SDK_VERSION_MIN ?= $(patsubst %.sdk,%,$(patsubst $(IPHONE_SDK_ROOT_DIR)%,%,$(IPHONE_SDK_BASE))) - -POCO_TARGET_OSNAME ?= $(IPHONE_SDK) -POCO_TARGET_OSARCH ?= armv7 -TOOL_PREFIX ?= $(shell xcode-select -print-path)/Platforms/$(IPHONE_SDK).platform/Developer/usr/bin -ifneq ($(POCO_TARGET_OSARCH),arm64) -THUMB = -mthumb -endif -OSFLAGS ?= -arch $(POCO_TARGET_OSARCH) -isysroot $(IPHONE_SDK_BASE) $(THUMB) -miphoneos-version-min=$(IPHONE_SDK_VERSION_MIN) - -# -# Tools -# -# If GCC_VER is defined then use it. -# Otherwise select the latest version -# - -CC = $(shell xcrun -find clang) -CXX = $(shell xcrun -find clang++) - -LINK = $(CXX) -bind_at_load -LIB = libtool -static -o -RANLIB = ranlib -SHLIB = $(CXX) $(OSFLAGS) -dynamiclib -Wl,-install_name,$@ -o $@ -DYLIB = $(CXX) $(OSFLAGS) -dynamic -bundle -read_only_relocs suppress -Wl,-bind_at_load -o $@ -SHLIBLN = $(POCO_BASE)/build/script/shlibln -STRIP = -DEP = $(POCO_BASE)/build/script/makedepend.gcc -SHELL = sh -RM = rm -rf -CP = cp -MKDIR = mkdir -p - -# -# Extension for Shared Libraries -# -SHAREDLIBEXT = .$(target_version).dylib -SHAREDLIBLINKEXT = .dylib - -# -# Compiler and Linker Flags -# -CFLAGS = $(OSFLAGS) -CFLAGS32 = -CFLAGS64 = -CXXFLAGS = $(OSFLAGS) -std=c++11 -stdlib=libc++ -Wall -Wno-sign-compare -CXXFLAGS32 = -CXXFLAGS64 = -LINKFLAGS = $(OSFLAGS) -stdlib=libc++ -LINKFLAGS32 = -LINKFLAGS64 = -STATICOPT_CC = -STATICOPT_CXX = -STATICOPT_LINK = -SHAREDOPT_CC = -fPIC -SHAREDOPT_CXX = -fPIC -SHAREDOPT_LINK = -DEBUGOPT_CC = -g -D_DEBUG=$(DEBUGLEVEL) -DEBUGOPT_CXX = -g -D_DEBUG=$(DEBUGLEVEL) -DEBUGOPT_LINK = -RELEASEOPT_CC = -DNDEBUG -O2 -RELEASEOPT_CXX = -DNDEBUG -O -RELEASEOPT_LINK = - -# -# System Specific Flags -# -SYSFLAGS = -DPOCO_HAVE_IPv6 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES - -# -# System Specific Libraries -# -SYSLIBS = -ldl +include $(POCO_BASE)/build/config/iPhone diff --git a/doc/99100-ReleaseNotes.page b/doc/99100-ReleaseNotes.page index bc5c2de4d..32f63565f 100644 --- a/doc/99100-ReleaseNotes.page +++ b/doc/99100-ReleaseNotes.page @@ -1,6 +1,32 @@ POCO C++ Libraries Release Notes AAAIntroduction +!!!Release 1.7.7 + +!!Summary of Changes + + - fixed GH #865: FileChannel compress fails leaving empty .gz files + - fixed GH #990: Potential race condition in Poco::File on Windows + - fixed GH #1157: Fixing a bug in the NetSSL_Win module (Host name verification failed error) + - fixed GH #1351: Fix for android include pthread.h from /usr/include + - fixed GH #1436: ODBC Bug: Unicode text(NVARCHAT) read from DB is truncated to half + - fixed GH #1453: _clock_gettime Symbol not found on Mac 10.11 + - fixed GH #1460: POCO does not build with OpenSSL 1.1 + - fixed GH #1461: Poco::Data::SQLite::SQLiteStatementImpl::next() error + - fixed GH #1462: AbstractConfiguration::getUInt does not parse hex numbers + - fixed GH #1464: ODBCMetaColumn::init() always maps integer NUMERIC/DECIMAL to Int32 + - fixed GH #1465: Assertion violation in DateTime.cpp using ZipArchive + - fixed GH #1472: HTTP(S)StreamFactory should send a User-Agent header. + - fixed GH #1476: Fixed error with Poco::UTF8Encoding::isLegal() + - fixed GH #1484: ODBC: fix uninitialized variable + - fixed GH #1486: Support ODBC GUID data type as string + - fixed GH #1488: Poco::ObjectPool shrinks if returned object is not valid + - fixed GH #1515: Detection of closed websocket connection + - fixed GH #1521: bug in JSON ParseHandler.cpp (empty keys should be valid) + - fixed GH #1526: iOS app rejected, IPv6 not working + - fixed GH #1532: RecordSet and RowFilter: bad use of reference counter + + !!!Release 1.7.6 !!Summary of Changes diff --git a/libversion b/libversion index 9e5feb525..abac1ea7b 100644 --- a/libversion +++ b/libversion @@ -1 +1 @@ -46 +47