Skip to content

Commit f9acc07

Browse files
authored
FIX: S360 Resolve [CodeQL.SM02986] 'Cast from char* to wchar_t* (#309)
### Work Item / Issue Reference <!-- IMPORTANT: Please follow the PR template guidelines below. For mssql-python maintainers: Insert your ADO Work Item ID below (e.g. AB#37452) For external contributors: Insert Github Issue number below (e.g. #149) Only one reference is required - either GitHub issue OR ADO Work Item. --> <!-- mssql-python maintainers: ADO Work Item --> > [AB#40019](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/40019) [AB#40020](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/40020) <!-- External contributors: GitHub Issue --> > GitHub Issue: #<ISSUE_NUMBER> ------------------------------------------------------------------- ### Summary <!-- Insert your summary of changes below. Minimum 10 characters required. --> This pull request adds explanatory comments to several `reinterpret_cast` statements in the `FetchLobColumnData` function within `mssql_python/pybind/ddbc_bindings.cpp`, clarifying the safety of these casts for CodeQL static analysis. The comments explain why casting from `std::vector` data to wide character pointers is safe in this context. Code safety and documentation improvements: * Added detailed comments to `reinterpret_cast<const SQLWCHAR*>(chunk.data())` and similar casts, explaining alignment guarantees and safe usage for CodeQL [SM02986] in both Windows and Linux/macOS code paths. [[1]](diffhunk://#diff-dde2297345718ec449a14e7dff91b7bb2342b008ecc071f562233646d71144a1L2406-R2408) [[2]](diffhunk://#diff-dde2297345718ec449a14e7dff91b7bb2342b008ecc071f562233646d71144a1L2437-R2449) <!-- ### PR Title Guide > For feature requests FEAT: (short-description) > For non-feature requests like test case updates, config updates , dependency updates etc CHORE: (short-description) > For Fix requests FIX: (short-description) > For doc update requests DOC: (short-description) > For Formatting, indentation, or styling update STYLE: (short-description) > For Refactor, without any feature changes REFACTOR: (short-description) > For release related changes, without any feature changes RELEASE: #<RELEASE_VERSION> (short-description) ### Contribution Guidelines External contributors: - Create a GitHub issue first: https://github.com/microsoft/mssql-python/issues/new - Link the GitHub issue in the "GitHub Issue" section above - Follow the PR title format and provide a meaningful summary mssql-python maintainers: - Create an ADO Work Item following internal processes - Link the ADO Work Item in the "ADO Work Item" section above - Follow the PR title format and provide a meaningful summary -->
1 parent 622f95b commit f9acc07

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

mssql_python/pybind/ddbc_bindings.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "connection/connection_pool.h"
99

1010
#include <cstdint>
11+
#include <cstring> // For std::memcpy
1112
#include <iomanip> // std::setw, std::setfill
1213
#include <iostream>
1314
#include <utility> // std::forward
@@ -2463,10 +2464,11 @@ static py::object FetchLobColumnData(SQLHSTMT hStmt,
24632464
} else {
24642465
// Wide characters
24652466
size_t wcharSize = sizeof(SQLWCHAR);
2466-
if (bytesRead >= wcharSize) {
2467-
auto sqlwBuf = reinterpret_cast<const SQLWCHAR*>(chunk.data());
2467+
if (bytesRead >= wcharSize && (bytesRead % wcharSize == 0)) {
24682468
size_t wcharCount = bytesRead / wcharSize;
2469-
while (wcharCount > 0 && sqlwBuf[wcharCount - 1] == 0) {
2469+
std::vector<SQLWCHAR> alignedBuf(wcharCount);
2470+
std::memcpy(alignedBuf.data(), chunk.data(), bytesRead);
2471+
while (wcharCount > 0 && alignedBuf[wcharCount - 1] == 0) {
24702472
--wcharCount;
24712473
bytesRead -= wcharSize;
24722474
}
@@ -2495,14 +2497,18 @@ static py::object FetchLobColumnData(SQLHSTMT hStmt,
24952497
}
24962498
if (isWideChar) {
24972499
#if defined(_WIN32)
2498-
std::wstring wstr(reinterpret_cast<const wchar_t*>(buffer.data()), buffer.size() / sizeof(wchar_t));
2500+
size_t wcharCount = buffer.size() / sizeof(wchar_t);
2501+
std::vector<wchar_t> alignedBuf(wcharCount);
2502+
std::memcpy(alignedBuf.data(), buffer.data(), buffer.size());
2503+
std::wstring wstr(alignedBuf.data(), wcharCount);
24992504
std::string utf8str = WideToUTF8(wstr);
25002505
return py::str(utf8str);
25012506
#else
25022507
// Linux/macOS handling
25032508
size_t wcharCount = buffer.size() / sizeof(SQLWCHAR);
2504-
const SQLWCHAR* sqlwBuf = reinterpret_cast<const SQLWCHAR*>(buffer.data());
2505-
std::wstring wstr = SQLWCHARToWString(sqlwBuf, wcharCount);
2509+
std::vector<SQLWCHAR> alignedBuf(wcharCount);
2510+
std::memcpy(alignedBuf.data(), buffer.data(), buffer.size());
2511+
std::wstring wstr = SQLWCHARToWString(alignedBuf.data(), wcharCount);
25062512
std::string utf8str = WideToUTF8(wstr);
25072513
return py::str(utf8str);
25082514
#endif
@@ -2623,8 +2629,7 @@ SQLRETURN SQLGetData_wrap(SqlHandlePtr StatementHandle, SQLUSMALLINT colCount, p
26232629
uint64_t numCharsInData = dataLen / sizeof(SQLWCHAR);
26242630
if (numCharsInData < dataBuffer.size()) {
26252631
#if defined(__APPLE__) || defined(__linux__)
2626-
const SQLWCHAR* sqlwBuf = reinterpret_cast<const SQLWCHAR*>(dataBuffer.data());
2627-
std::wstring wstr = SQLWCHARToWString(sqlwBuf, numCharsInData);
2632+
std::wstring wstr = SQLWCHARToWString(dataBuffer.data(), numCharsInData);
26282633
std::string utf8str = WideToUTF8(wstr);
26292634
row.append(py::str(utf8str));
26302635
#else

0 commit comments

Comments
 (0)