diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90aec85d6..f7f8708d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,6 +152,8 @@ jobs: fi if [ "${{matrix.no_ubsan}}" = true ]; then set_env_var SOCI_NO_UBSAN 1 + else + set_env_var UBSAN_OPTIONS print_stacktrace=1:halt_on_error=1 fi - name: Setup tmate diff --git a/include/soci/oracle/soci-oracle.h b/include/soci/oracle/soci-oracle.h index 43cff3ec4..705751bd1 100644 --- a/include/soci/oracle/soci-oracle.h +++ b/include/soci/oracle/soci-oracle.h @@ -63,7 +63,7 @@ struct oracle_standard_into_type_backend : details::standard_into_type_backend OCIDefine *defnp_; sb2 indOCIHolder_; void *data_; - void *ociData_; + void *ociData_ = NULL; char *buf_; // generic buffer details::exchange_type type_; @@ -143,7 +143,7 @@ struct oracle_standard_use_type_backend : details::standard_use_type_backend OCIBind *bindp_; sb2 indOCIHolder_; void *data_; - void *ociData_; + void *ociData_ = NULL; bool readOnly_; char *buf_; // generic buffer details::exchange_type type_; diff --git a/src/backends/firebird/blob.cpp b/src/backends/firebird/blob.cpp index b4e401b7b..e0e5f8456 100644 --- a/src/backends/firebird/blob.cpp +++ b/src/backends/firebird/blob.cpp @@ -59,7 +59,8 @@ std::size_t firebird_blob_backend::read_from_start(void * buf, std::size_t toRea // Ensure we don't read more than we have toRead = std::min(toRead, size - offset); - std::memcpy(buf, &data_[offset], toRead); + if (toRead) + std::memcpy(buf, &data_[offset], toRead); return toRead; } @@ -121,7 +122,8 @@ void firebird_blob_backend::trim(std::size_t newLen) void firebird_blob_backend::writeBuffer(std::size_t offset, const void * buf, std::size_t toWrite) { - std::memcpy(data_.data() + offset, buf, toWrite); + if (toWrite) + std::memcpy(data_.data() + offset, buf, toWrite); } void firebird_blob_backend::open() diff --git a/src/backends/oracle/standard-into-type.cpp b/src/backends/oracle/standard-into-type.cpp index 89eb05936..5c0e78f19 100644 --- a/src/backends/oracle/standard-into-type.cpp +++ b/src/backends/oracle/standard-into-type.cpp @@ -391,15 +391,23 @@ void oracle_standard_into_type_backend::post_fetch( void oracle_standard_into_type_backend::clean_up() { - if (type_ == x_xmltype || type_ == x_longstring) + if (ociData_) { - free_temp_lob(statement_.session_, static_cast(ociData_)); - ociData_ = NULL; - } + switch (type_) + { + case x_xmltype: + case x_longstring: + free_temp_lob(statement_.session_, static_cast(ociData_)); + break; + + case x_blob: + OCIDescriptorFree(ociData_, OCI_DTYPE_LOB); + break; + + default: + throw soci_error("Internal error: OCI data used for unexpected type"); + } - if (type_ == x_blob) - { - OCIDescriptorFree(ociData_, OCI_DTYPE_LOB); ociData_ = NULL; } diff --git a/src/backends/oracle/standard-use-type.cpp b/src/backends/oracle/standard-use-type.cpp index c9adf4422..8a2b64b04 100644 --- a/src/backends/oracle/standard-use-type.cpp +++ b/src/backends/oracle/standard-use-type.cpp @@ -710,14 +710,23 @@ void oracle_standard_use_type_backend::post_use(bool gotData, indicator *ind) void oracle_standard_use_type_backend::clean_up() { - if (type_ == x_xmltype || type_ == x_longstring) - { - free_temp_lob(statement_.session_, static_cast(ociData_)); - ociData_ = NULL; - } - - if (type_ == x_blob) + if (ociData_) { + switch (type_) + { + case x_xmltype: + case x_longstring: + free_temp_lob(statement_.session_, static_cast(ociData_)); + break; + + case x_blob: + // We don't own the LOB locator, oracle_blob_backend does. + break; + + default: + throw soci_error("Internal error: OCI data used for unexpected type"); + } + ociData_ = NULL; }