diff --git a/builds/win32/msvc15/common_test.vcxproj b/builds/win32/msvc15/common_test.vcxproj index 8ba6d3fc3e5..6c9f713d0d9 100644 --- a/builds/win32/msvc15/common_test.vcxproj +++ b/builds/win32/msvc15/common_test.vcxproj @@ -176,6 +176,8 @@ + + diff --git a/builds/win32/msvc15/common_test.vcxproj.filters b/builds/win32/msvc15/common_test.vcxproj.filters index 3e8ce6deae8..393ee5ddb3b 100644 --- a/builds/win32/msvc15/common_test.vcxproj.filters +++ b/builds/win32/msvc15/common_test.vcxproj.filters @@ -36,5 +36,11 @@ source + + source + + + source + \ No newline at end of file diff --git a/src/common/classes/ClumpletReader.cpp b/src/common/classes/ClumpletReader.cpp index 6dc4add55e2..3d9eee5d81f 100644 --- a/src/common/classes/ClumpletReader.cpp +++ b/src/common/classes/ClumpletReader.cpp @@ -86,8 +86,7 @@ void ClumpletReader::dump() const try { ClumpletDump d(kind, getBuffer(), getBufferLength()); - int t = (kind == SpbStart || kind == UnTagged || kind == WideUnTagged || kind == SpbResponse || kind == InfoResponse) ? - -1 : d.getBufferTag(); + const int t = isTagged() ? d.getBufferTag() : -1; gds__log("Tag=%d Offset=%d Length=%d Eof=%d\n", t, getCurOffset(), getBufferLength(), isEof()); for (d.rewind(); !(d.isEof()); d.moveNext()) { @@ -98,7 +97,7 @@ void ClumpletReader::dump() const catch (const fatal_exception& x) { gds__log("Fatal exception during clumplet dump: %s", x.what()); - FB_SIZE_T l = getBufferLength() - getCurOffset(); + const FB_SIZE_T l = getBufferLength() - getCurOffset(); const UCHAR *p = getBuffer() + getCurOffset(); gds__log("Plain dump starting with offset %d: %s", getCurOffset(), ClumpletDump::hexString(p, l).c_str()); @@ -205,7 +204,7 @@ void ClumpletReader::invalid_structure(const char* what, const int data) const fatal_exception::raiseFmt("Invalid clumplet buffer structure: %s (%d)", what, data); } -bool ClumpletReader::isTagged() const +bool ClumpletReader::isTagged() const noexcept { switch (kind) { @@ -214,13 +213,17 @@ bool ClumpletReader::isTagged() const case WideTagged: case SpbAttach: return true; + default: + return false; } - - return false; } UCHAR ClumpletReader::getBufferTag() const { + if (!isTagged()) { + usage_mistake("buffer is not tagged"); + return 0; + } const UCHAR* const buffer_end = getBufferEnd(); const UCHAR* buffer_start = getBuffer(); @@ -235,16 +238,6 @@ UCHAR ClumpletReader::getBufferTag() const return 0; } return buffer_start[0]; - case SpbStart: - case UnTagged: - case WideUnTagged: - case SpbSendItems: - case SpbReceiveItems: - case SpbResponse: - case InfoResponse: - case InfoItems: - usage_mistake("buffer is not tagged"); - return 0; case SpbAttach: if (buffer_end - buffer_start == 0) { @@ -286,6 +279,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_tpb_lock_timeout: case isc_tpb_at_snapshot_number: return TraditionalDpb; + default: + break; } return SingleTpb; case SpbSendItems: @@ -298,20 +293,14 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_info_length: case isc_info_flag_end: return SingleTpb; + default: + break; } return StringSpb; case SpbReceiveItems: case InfoItems: return SingleTpb; case SpbStart: - switch(tag) - { - case isc_spb_auth_block: - case isc_spb_trusted_auth: - case isc_spb_auth_plugin_name: - case isc_spb_auth_plugin_list: - return Wide; - } switch (spbState) { case 0: @@ -345,6 +334,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_spb_res_access_mode: case isc_spb_res_replica_mode: return ByteSpb; + default: + break; } invalid_structure("unknown parameter for backup/restore", tag); break; @@ -363,6 +354,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_spb_rpr_rollback_trans_64: case isc_spb_rpr_recover_two_phase_64: return BigIntSpb; + default: + break; } invalid_structure("unknown parameter for repair", tag); break; @@ -388,6 +381,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_spb_sec_groupid: case isc_spb_sec_admin: return IntSpb; + default: + break; } invalid_structure("unknown parameter for security database operation", tag); break; @@ -414,6 +409,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_spb_prp_online_mode: case isc_spb_prp_replica_mode: return ByteSpb; + default: + break; } invalid_structure("unknown parameter for setting database properties", tag); break; @@ -428,6 +425,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const return StringSpb; case isc_spb_options: return IntSpb; + default: + break; } invalid_structure("unknown parameter for getting statistics", tag); break; @@ -450,6 +449,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const return IntSpb; case isc_spb_nbk_clean_history: return SingleTpb; + default: + break; } invalid_structure("unknown parameter for nbackup", tag); break; @@ -460,6 +461,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const return StringSpb; case isc_spb_options: return IntSpb; + default: + break; } invalid_structure("unknown parameter for nbackup", tag); break; @@ -474,7 +477,10 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const return StringSpb; case isc_spb_trc_id: return IntSpb; + default: + break; } + invalid_structure("unknown parameter for trace", tag); break; case isc_action_svc_validate: switch (tag) @@ -487,7 +493,12 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const return StringSpb; case isc_spb_val_lock_timeout: return IntSpb; + default: + break; } + invalid_structure("unknown parameter for validate", tag); + break; + default: break; } invalid_structure("wrong spb state", spbState); @@ -533,6 +544,8 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_spb_tra_state: case isc_spb_tra_advise: return ByteSpb; + default: + break; } invalid_structure("unrecognized service response tag", tag); break; @@ -543,8 +556,12 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_info_truncated: case isc_info_flag_end: return SingleTpb; + default: + break; } return StringSpb; + default: + break; } invalid_structure("unknown clumplet kind", kind); return SingleTpb; @@ -552,17 +569,11 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const void ClumpletReader::adjustSpbState() { - switch (kind) + if (kind == SpbStart && + spbState == 0 && // Just started with service start block ... + getClumpletSize(true, true, true) == 1) // and this is action_XXX clumplet { - case SpbStart: - if (spbState == 0 && // Just started with service start block ... - getClumpletSize(true, true, true) == 1) // and this is action_XXX clumplet - { - spbState = getClumpTag(); - } - break; - default: - break; + spbState = getClumpTag(); } } @@ -582,7 +593,7 @@ FB_SIZE_T ClumpletReader::getClumpletSize(bool wTag, bool wLength, bool wData) c FB_SIZE_T lengthSize = 0; FB_SIZE_T dataSize = 0; - ClumpletType t = getClumpletType(clumplet[0]); + const ClumpletType t = getClumpletType(clumplet[0]); switch (t) { @@ -651,13 +662,14 @@ FB_SIZE_T ClumpletReader::getClumpletSize(bool wTag, bool wLength, bool wData) c default: invalid_structure("unknown clumplet type", t); + return rc; } const FB_SIZE_T total = 1 + lengthSize + dataSize; if (clumplet + total > buffer_end) { invalid_structure("buffer end before end of clumplet - clumplet too long", total); - FB_SIZE_T delta = total - (buffer_end - clumplet); + const FB_SIZE_T delta = total - (buffer_end - clumplet); if (delta > dataSize) dataSize = 0; else @@ -678,9 +690,8 @@ void ClumpletReader::moveNext() if (isEof()) return; // no need to raise useless exceptions - switch (kind) + if (kind == InfoResponse) { - case InfoResponse: switch (getClumpTag()) { case isc_info_end: @@ -688,40 +699,24 @@ void ClumpletReader::moveNext() // terminating clumplet cur_offset = getBufferLength(); return; + default: + break; } } - FB_SIZE_T cs = getClumpletSize(true, true, true); + const FB_SIZE_T cs = getClumpletSize(true, true, true); adjustSpbState(); cur_offset += cs; } void ClumpletReader::rewind() { - if (! getBuffer()) - { + if (!getBuffer() || !isTagged()) cur_offset = 0; - spbState = 0; - return; - } - switch (kind) - { - case UnTagged: - case WideUnTagged: - case SpbStart: - case SpbSendItems: - case SpbReceiveItems: - case SpbResponse: - case InfoResponse: - case InfoItems: - cur_offset = 0; - break; - default: - if (kind == SpbAttach && getBufferLength() > 0 && getBuffer()[0] != isc_spb_version1) - cur_offset = 2; - else - cur_offset = 1; - } + else if (kind == SpbAttach && getBufferLength() > 0 && getBuffer()[0] == isc_spb_version) + cur_offset = 2; + else + cur_offset = 1; spbState = 0; } @@ -956,7 +951,7 @@ AuthReader::AuthReader(MemoryPool& pool, const AuthBlock& authBlock) rewind(); } -static inline void erase(NoCaseString& s) +static inline void erase(NoCaseString& s) noexcept { s.erase(); } diff --git a/src/common/classes/ClumpletReader.h b/src/common/classes/ClumpletReader.h index a9be7202cb5..0767121a929 100644 --- a/src/common/classes/ClumpletReader.h +++ b/src/common/classes/ClumpletReader.h @@ -126,21 +126,18 @@ class ClumpletReader : protected AutoStorage // Return the tag for buffer (usually structure version) UCHAR getBufferTag() const; // true if buffer has tag - bool isTagged() const; + bool isTagged() const noexcept; FB_SIZE_T getBufferLength() const { FB_SIZE_T rc = getBufferEnd() - getBuffer(); - if (rc == 1 && kind != UnTagged && kind != SpbStart && - kind != WideUnTagged && kind != SpbSendItems && - kind != SpbReceiveItems && kind != SpbResponse && - kind != InfoResponse && kind != InfoItems) + if (rc == 1 && isTagged()) { rc = 0; } return rc; } - FB_SIZE_T getCurOffset() const { return cur_offset; } - void setCurOffset(FB_SIZE_T newOffset) { cur_offset = newOffset; } + FB_SIZE_T getCurOffset() const noexcept { return cur_offset; } + void setCurOffset(FB_SIZE_T newOffset) noexcept { cur_offset = newOffset; } #ifdef DEBUG_CLUMPLETS // Sometimes it's really useful to have it in case of errors @@ -205,13 +202,13 @@ class ClumpletReader : protected AutoStorage class AuthReader : public ClumpletReader { public: - static const unsigned char AUTH_NAME = 1; // name described by it's type - static const unsigned char AUTH_PLUGIN = 2; // plugin which added a record - static const unsigned char AUTH_TYPE = 3; // it can be user/group/role/etc. - what plugin sets - static const unsigned char AUTH_SECURE_DB = 4; // sec. db in which context record was added - // missing when plugin is server-wide - static const unsigned char AUTH_ORIG_PLUG = 5; // original plugin that added a mapped record - // (human information reasons only) + static constexpr unsigned char AUTH_NAME = 1; // name described by it's type + static constexpr unsigned char AUTH_PLUGIN = 2; // plugin which added a record + static constexpr unsigned char AUTH_TYPE = 3; // it can be user/group/role/etc. - what plugin sets + static constexpr unsigned char AUTH_SECURE_DB = 4; // sec. db in which context record was added + // missing when plugin is server-wide + static constexpr unsigned char AUTH_ORIG_PLUG = 5; // original plugin that added a mapped record + // (human information reasons only) typedef Array AuthBlock; struct Info @@ -219,7 +216,7 @@ class AuthReader : public ClumpletReader NoCaseString type, name, plugin, secDb, origPlug; unsigned found, current; - Info() + Info() noexcept : found(0), current(0) { } @@ -241,7 +238,7 @@ class AuthReader : public ClumpletReader #ifdef AUTH_BLOCK_DEBUG void dumpAuthBlock(const char* text, ClumpletReader* pb, unsigned char param); #else -static inline void dumpAuthBlock(const char*, ClumpletReader*, unsigned char) { } +static inline void dumpAuthBlock(const char*, ClumpletReader*, unsigned char) noexcept { } #endif } // namespace Firebird diff --git a/src/common/classes/ClumpletWriter.cpp b/src/common/classes/ClumpletWriter.cpp index e03b154b69a..4544b0944eb 100644 --- a/src/common/classes/ClumpletWriter.cpp +++ b/src/common/classes/ClumpletWriter.cpp @@ -73,11 +73,11 @@ void ClumpletWriter::initNewBuffer(UCHAR tag) switch (kind) { case SpbAttach: - if (tag != isc_spb_version1) + if (tag == isc_spb_version) { dynamic_buffer.push(isc_spb_version); } - // fall down .... + [[fallthrough]]; case Tagged: case Tpb: case WideTagged: @@ -175,6 +175,7 @@ ClumpletWriter::ClumpletWriter(MemoryPool& given_pool, Kind k, FB_SIZE_T limit, const UCHAR* buffer, FB_SIZE_T buffLen, UCHAR tag) : ClumpletReader(given_pool, k, NULL, 0), sizeLimit(limit), + kindList(NULL), dynamic_buffer(getPool()), flag_overflow(false) { @@ -214,13 +215,13 @@ void ClumpletWriter::reset(UCHAR tag) void ClumpletWriter::reset(const UCHAR* buffer, const FB_SIZE_T buffLen) { + const UCHAR tag = isTagged() ? getBufferTag() : 0; dynamic_buffer.clear(); if (buffer && buffLen) { dynamic_buffer.push(buffer, buffLen); } else - { - UCHAR tag = (kind == SpbStart || kind == UnTagged || kind == WideUnTagged) ? 0 : getBufferTag(); + { initNewBuffer(tag); } rewind(); @@ -418,6 +419,8 @@ void ClumpletWriter::insertBytesLengthCheck(UCHAR tag, const void* bytes, const dynamic_buffer.insert(cur_offset++, tag); switch (lenSize) { + case 0: + break; case 1: dynamic_buffer.insert(cur_offset++, static_cast(length)); break; @@ -437,6 +440,9 @@ void ClumpletWriter::insertBytesLengthCheck(UCHAR tag, const void* bytes, const cur_offset += 4; } break; + default: + fb_assert(lenSize >= 0 && lenSize <= 2 || lenSize == 4); + return; } dynamic_buffer.insert(cur_offset, static_cast(bytes), length); const FB_SIZE_T new_offset = cur_offset + length; diff --git a/src/common/classes/ClumpletWriter.h b/src/common/classes/ClumpletWriter.h index 75dd9c3808e..1a50170e3c1 100644 --- a/src/common/classes/ClumpletWriter.h +++ b/src/common/classes/ClumpletWriter.h @@ -35,7 +35,7 @@ // This setting of maximum dpb size doesn't mean, that we // can't process larger DBPs! This is just recommended limit // cause it's hard to imagine sensefull DPB of even this size. -const FB_SIZE_T MAX_DPB_SIZE = 1024 * 1024; +constexpr FB_SIZE_T MAX_DPB_SIZE = 1024 * 1024; namespace Firebird { @@ -100,7 +100,7 @@ class ClumpletWriter : public ClumpletReader bool deleteWithTag(UCHAR tag); const UCHAR* getBuffer() const override; - bool hasOverflow() const + bool hasOverflow() const noexcept { return flag_overflow; } diff --git a/src/common/fb_exception.cpp b/src/common/fb_exception.cpp index 221e906a4e8..b2dc76074e8 100644 --- a/src/common/fb_exception.cpp +++ b/src/common/fb_exception.cpp @@ -126,19 +126,19 @@ const char* status_exception::what() const noexcept return "Firebird::status_exception"; } -void status_exception::raise(const ISC_STATUS *status_vector) +[[noreturn]] void status_exception::raise(const ISC_STATUS *status_vector) { throw status_exception(status_vector); } -void status_exception::raise(const IStatus* status) +[[noreturn]] void status_exception::raise(const IStatus* status) { StaticStatusVector status_vector; status_vector.mergeStatus(status); throw status_exception(status_vector.begin()); } -void status_exception::raise(const Arg::StatusVector& statusVector) +[[noreturn]] void status_exception::raise(const Arg::StatusVector& statusVector) { throw status_exception(statusVector.value()); } @@ -157,7 +157,7 @@ void status_exception::stuffByException(StaticStatusVector& status) const noexce // ********************************* BadAlloc **************************** -void BadAlloc::raise() +[[noreturn]] void BadAlloc::raise() { throw BadAlloc(); } @@ -174,14 +174,14 @@ const char* BadAlloc::what() const noexcept // ********************************* LongJump *************************** -void LongJump::raise() +[[noreturn]] void LongJump::raise() { throw LongJump(); } void LongJump::stuffByException(StaticStatusVector& status) const noexcept { - ISC_STATUS sv[] = {isc_arg_gds, isc_random, isc_arg_string, + const ISC_STATUS sv[] = {isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS)(IPTR) "Unexpected call to Firebird::LongJump::stuffException()", isc_arg_end}; try @@ -202,7 +202,7 @@ const char* LongJump::what() const noexcept // ********************************* system_error *************************** -system_error::system_error(const char* syscall, const char* arg, int error_code) : +system_error::system_error(const char* syscall, const char* arg, int error_code) noexcept : status_exception(), errorCode(error_code) { Arg::Gds temp(isc_sys_request); @@ -213,17 +213,17 @@ system_error::system_error(const char* syscall, const char* arg, int error_code) set_status(temp.value()); } -void system_error::raise(const char* syscall, int error_code) +[[noreturn]] void system_error::raise(const char* syscall, int error_code) { throw system_error(syscall, nullptr, error_code); } -void system_error::raise(const char* syscall) +[[noreturn]] void system_error::raise(const char* syscall) { throw system_error(syscall, nullptr, getSystemError()); } -int system_error::getSystemError() +int system_error::getSystemError() noexcept { #ifdef WIN_NT return GetLastError(); @@ -247,30 +247,29 @@ system_call_failed::system_call_failed(const char* syscall, const char* arg, int #endif } -void system_call_failed::raise(const char* syscall, int error_code) +[[noreturn]] void system_call_failed::raise(const char* syscall, int error_code) { throw system_call_failed(syscall, nullptr, error_code); } -void system_call_failed::raise(const char* syscall) +[[noreturn]] void system_call_failed::raise(const char* syscall) { throw system_call_failed(syscall, nullptr, getSystemError()); } - -void system_call_failed::raise(const char* syscall, const char* arg, int error_code) +[[noreturn]] void system_call_failed::raise(const char* syscall, const char* arg, int error_code) { throw system_call_failed(syscall, arg, error_code); } -void system_call_failed::raise(const char* syscall, const char* arg) +[[noreturn]] void system_call_failed::raise(const char* syscall, const char* arg) { raise(syscall, arg, getSystemError()); } // ********************************* fatal_exception ******************************* -fatal_exception::fatal_exception(const char* message) : +fatal_exception::fatal_exception(const char* message) noexcept : status_exception() { const ISC_STATUS temp[] = @@ -291,12 +290,12 @@ const char* fatal_exception::what() const noexcept return reinterpret_cast(value()[3]); } -void fatal_exception::raise(const char* message) +[[noreturn]] void fatal_exception::raise(const char* message) { throw fatal_exception(message); } -void fatal_exception::raiseFmt(const char* format, ...) +[[noreturn]] void fatal_exception::raiseFmt(const char* format, ...) { va_list args; va_start(args, format); diff --git a/src/include/fb_exception.h b/src/include/fb_exception.h index 988efafaff5..441d8512eb7 100644 --- a/src/include/fb_exception.h +++ b/src/include/fb_exception.h @@ -74,7 +74,7 @@ class LongJump : public Exception public: virtual void stuffByException(StaticStatusVector& status_vector) const noexcept; virtual const char* what() const noexcept; - static void raise(); + [[noreturn]] static void raise(); LongJump() noexcept : Exception() { } }; @@ -85,7 +85,7 @@ class BadAlloc : public std::bad_alloc, public Exception BadAlloc() noexcept : std::bad_alloc(), Exception() { } virtual void stuffByException(StaticStatusVector& status_vector) const noexcept; virtual const char* what() const noexcept; - static void raise(); + [[noreturn]] static void raise(); }; // Main exception class in firebird @@ -131,18 +131,18 @@ class system_error : public status_exception int errorCode; protected: - system_error(const char* syscall, const char* arg, int error_code); + system_error(const char* syscall, const char* arg, int error_code) noexcept; public: - static void raise(const char* syscall, int error_code); - static void raise(const char* syscall); + [[noreturn]] static void raise(const char* syscall, int error_code); + [[noreturn]] static void raise(const char* syscall); - int getErrorCode() const + int getErrorCode() const noexcept { return errorCode; } - static int getSystemError(); + static int getSystemError() noexcept; }; // use this class if exception can't be handled @@ -153,19 +153,19 @@ class system_call_failed : public system_error system_call_failed(const char* syscall, const char* arg, int error_code); public: - static void raise(const char* syscall, int error_code); - static void raise(const char* syscall); - static void raise(const char* syscall, const char* arg, int error_code); - static void raise(const char* syscall, const char* arg); + [[noreturn]] static void raise(const char* syscall, int error_code); + [[noreturn]] static void raise(const char* syscall); + [[noreturn]] static void raise(const char* syscall, const char* arg, int error_code); + [[noreturn]] static void raise(const char* syscall, const char* arg); }; class fatal_exception : public status_exception { public: - explicit fatal_exception(const char* message); - static void raiseFmt(const char* format, ...); + explicit fatal_exception(const char* message) noexcept; + [[noreturn]] static void raiseFmt(const char* format, ...); const char* what() const noexcept; - static void raise(const char* message); + [[noreturn]] static void raise(const char* message); };