Skip to content

Use .data() instead of const_cast(.c_str()) to fix undefined behavior - #1073

Merged
BYVoid merged 8 commits into
masterfrom
claude/fix-security-issue-14-O1DjX
Mar 27, 2026
Merged

BYVoid merged 8 commits into
masterfrom
claude/fix-security-issue-14-O1DjX

Conversation

@BYVoid

@BYVoid BYVoid commented Mar 27, 2026 •

Copy link
Copy Markdown
Owner

Summary

Replace const_cast(str.c_str()) with C++17 non-const str.data() to eliminate undefined behavior when writing into std::string buffers. Also use .data() consistently for copy source operands, and cache by-value return results in local const std::string& to avoid redundant temporaries.

Why .data() instead of const_cast(.c_str())

In standard C++, std::string::c_str() returns a const char*. Writing through a const_cast-ed pointer obtained from .c_str() is undefined behavior — the implementation is not required to allow mutation through that pointer, and compilers may optimize assuming the pointed-to data is not modified.

C++17 added a non-const overload of std::string::data() that returns char*, specifically designed for cases where you need writable access to the internal buffer after resize(). This is the correct, well-defined way to obtain a mutable pointer to a std::string's storage.

Changes

File Change
src/BinaryDict.cpp const_cast(keyBuf.c_str()) / valueBuf.c_str() → .data() for writable buffers; cache Key()/Value() in const std::string&; use .data() in offset calculations and asserts
src/SerializedValues.cpp const_cast(valueBuffer->c_str()) → valueBuffer->data(); use .data() consistently
src/UTF8Util.hpp Replace strncpy(const_cast(newStr.c_str()), ...) with std::string(str, length) constructor
src/Converter.cpp Use .data() instead of .c_str() for copy source
src/SimpleConverter.cpp Use .data() instead of .c_str() for copy source
src/tools/CommandLine.cpp Use .data() instead of .c_str() for copy source; add explicit #include

Test plan

  • All 16 existing unit tests pass
  • Build succeeds with no new warnings

https://claude.ai/code/session_01TeWHUg4WeAWkaumW2jWgzJ

…ties (CWE-120/CWE-676)

Replace all uses of strcpy and strncpy with bounds-aware memcpy calls
to eliminate potential buffer overflow vulnerabilities flagged by CodeQL.
All call sites already know the exact copy length, so memcpy with
explicit size is both safe and equivalent. Also simplify
UTF8Util::FromSubstr to use the std::string(ptr, len) constructor
instead of strncpy with const_cast (which was undefined behavior).

https://claude.ai/code/session_01TeWHUg4WeAWkaumW2jWgzJ
@BYVoid BYVoid changed the title Replace unsafe string functions with memcpy for buffer safety Replace strcpy/strncpy with memcpy to fix buffer overflow vulnerabilities Mar 27, 2026
@BYVoid
BYVoid requested a review from Copilot March 27, 2026 02:40
@BYVoid BYVoid self-assigned this Mar 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to remove unsafe C string copy APIs (strcpy/strncpy) by switching call sites to explicit-length copies (memcpy) and by simplifying UTF8Util::FromSubstr to a safer/cleaner std::string(ptr, len) construction.

Changes:

  • Replace strcpy/strncpy with memcpy using explicit byte counts in multiple conversion/buffer-building paths.
  • Simplify UTF8Util::FromSubstr implementation to avoid const_cast + strncpy.
  • Add include where needed for memcpy usage (partially; one TU still appears to rely on transitive headers).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/tools/CommandLine.cpp Uses memcpy to restore UTF-8 remainder bytes between chunked reads.
src/UTF8Util.hpp Simplifies substring creation to std::string(str, length).
src/SimpleConverter.cpp Copies converted output into newly allocated C buffer via memcpy(len+1).
src/SerializedValues.cpp Uses memcpy(len+1) when constructing serialized value buffer.
src/Converter.cpp Switches from strcpy to memcpy(len+1) for caller-provided output buffer.
src/BinaryDict.cpp Uses memcpy(len+1) when constructing key/value buffers for binary dict serialization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/SerializedValues.cpp Outdated
Comment thread src/BinaryDict.cpp Outdated
Comment thread src/BinaryDict.cpp Outdated
Comment thread src/tools/CommandLine.cpp Outdated
Comment thread src/UTF8Util.hpp Outdated
claude added 2 commits March 27, 2026 03:04
…r access

Address review comments: replace undefined behavior of writing through
const_cast(str.c_str()) with C++17 non-const .data() accessor.
Also cache Key()/Value() return values in BinaryDict::ConstructBuffer
to avoid redundant by-value copies.

https://claude.ai/code/session_01TeWHUg4WeAWkaumW2jWgzJ
Consistently use .data() for all memcpy calls to match the intent of
raw byte copying rather than C-string access.

https://claude.ai/code/session_01TeWHUg4WeAWkaumW2jWgzJ
Comment thread src/BinaryDict.cpp Outdated
claude added 2 commits March 27, 2026 03:36
Bind return-by-value results to const std::string& to extend temporary
lifetime without copying, per review feedback.

https://claude.ai/code/session_01TeWHUg4WeAWkaumW2jWgzJ
Revert the strcpy→memcpy and strncpy→memcpy replacements. The PR now
focuses solely on replacing undefined behavior from
const_cast(.c_str()) with C++17 non-const .data() for writable
buffer access, and using .data() consistently for copy sources.

https://claude.ai/code/session_01TeWHUg4WeAWkaumW2jWgzJ
@BYVoid BYVoid changed the title Replace strcpy/strncpy with memcpy to fix buffer overflow vulnerabilities Use .data() instead of const_cast<char*>(.c_str()) to fix undefined behavior Mar 27, 2026
@frankslin frankslin changed the title Use .data() instead of const_cast<char*>(.c_str()) to fix undefined behavior Use .data() instead of const_cast(.c_str()) to fix undefined behavior Mar 27, 2026
claude added 2 commits March 27, 2026 05:05
Use .data() only for writable destination buffers where it replaces
const_cast(.c_str()). Keep .c_str() for read-only source
operands of strcpy/strncpy since it better conveys intent.

https://claude.ai/code/session_01TeWHUg4WeAWkaumW2jWgzJ
Restore the original strncpy-based implementation of FromSubstr but
use .data() instead of const_cast(.c_str()) for writable access.

https://claude.ai/code/session_01TeWHUg4WeAWkaumW2jWgzJ
@BYVoid
BYVoid merged commit 1b74ee8 into master Mar 27, 2026
32 checks passed
@frankslin
frankslin deleted the claude/fix-security-issue-14-O1DjX branch March 27, 2026 05:48
Copilot AI mentioned this pull request Apr 17, 2026
3 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants