Skip to content

Update and Clean Up Project Files#11

Merged
WJiangzhi merged 9 commits into
masterfrom
fix/wrong-type-at-arm-char-unsigned
Mar 29, 2026
Merged

Update and Clean Up Project Files#11
WJiangzhi merged 9 commits into
masterfrom
fix/wrong-type-at-arm-char-unsigned

Conversation

@WJiangzhi
Copy link
Copy Markdown
Member

@WJiangzhi WJiangzhi commented Mar 6, 2026

  • Update CMakeLists.txt to support NDK, Make, and VS modules
  • Remove non-cross-platform examples
  • Deprecate single-header version
  • Fix incorrect unsigned char judgment
  • Restore ZAC_SV C++17 std::string compatibility
  • Apply minor fixes

Fixes #9

@WJiangzhi WJiangzhi self-assigned this Mar 6, 2026
@WJiangzhi WJiangzhi added bug Something isn't working enhancement New feature or request labels Mar 6, 2026
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the project's build system flexibility and cross-platform compatibility. It introduces dedicated build configurations for Android NDK, Make, and Visual Studio, while simultaneously removing platform-specific examples that hindered portability. A major refactoring of the ZAC_SV type ensures better integration with C++17 std::string_view and addresses character type handling, contributing to a more robust and maintainable codebase.

Highlights

  • Enhanced Build System Support: Added dedicated build configurations for Android NDK (Android.mk), Make (Makefile), and Visual Studio (ZACLib.vcxproj) to improve cross-platform compatibility and build flexibility.
  • Refactored ZAC_SV for C++17 Compatibility and Character Handling: The ZAC_SV type was significantly refactored in ZACLib_Types.hpp to better integrate with C++17's std::string_view and to correctly handle unsigned char types, ensuring more robust string manipulation.
  • Removed Platform-Specific Examples and Deprecated Single-Header: Eliminated non-cross-platform example files located in examples/windows and removed the ZACLib_single.hpp file, streamlining the project structure.
  • Code Cleanup and Minor Fixes: Applied various minor code improvements, including removing ReSharper directives, refining static_cast usage, and updating CMakeLists.txt settings.
Changelog
  • .gitignore
    • Added an ignore rule for **/localtest*/ directories.
    • Adjusted the .idea ignore rule to be more specific.
  • .idea/misc.xml
    • Updated the CMakeWorkspace project directory from examples/windows to localtest.
  • ZACLib/Android.mk
    • Added a new Android NDK build file for ZACLib.
  • ZACLib/CMakeLists.txt
    • Removed CMAKE_CXX_STANDARD global setting.
    • Added a comment indicating C++11 or higher for CXX_STANDARD property.
  • ZACLib/Makefile
    • Added a new Makefile for building ZACLib.
  • ZACLib/ZACLib.cpp
    • Removed ReSharper disable CppClassNeverUsed comment.
    • Updated AddRule methods to use ZAC_SV("") instead of ZAC_SV("", 0).
    • Changed loop variable type from char to ZAC_CHAR.
    • Applied static_cast<Node::value_type> for trie.size() assignments.
    • Used ArmCastChar for outputs.emplace_back and result.append calls.
    • Made f in Build method const.
    • Changed invalid_output to constexpr.
    • Added NOLINT comment to emit_until lambda.
    • Corrected static_cast<unsigned char> for input character processing.
  • ZACLib/ZACLib.hpp
    • Removed ReSharper disable CppNonExplicitConvertingConstructor comment.
  • ZACLib/ZACLib.vcxproj
    • Added a new Visual Studio project file for ZACLib.
  • ZACLib/ZACLib_Types.hpp
    • Introduced HAS_STRING_VIEW macro for C++17 detection.
    • Defined CHAR_UNSIGNED macro based on compiler definitions.
    • Introduced ZAC_CHAR type (either char or unsigned char) and ArmCastChar macro for casting.
    • Refactored ZAC_SV class to inherit from std::basic_string_view<ZAC_CHAR> when C++17 is available, providing improved std::string compatibility.
    • Updated ZAC_SV constructors and data() method to use ZAC_CHAR and ArmCastChar.
    • Modified Node struct to use value_type, next_type, size_type aliases and constexpr kInvalidOutput.
    • Added ReSharper enable CppNonExplicitConvertingConstructor comment.
  • ZACLib/ZACLib_single.hpp
    • Removed the single-header version of the library.
  • examples/windows/CMakeLists.txt
    • Removed the Windows-specific CMake configuration.
  • examples/windows/main.cpp
    • Removed the Windows-specific main example.
  • examples/windows/test.cpp
    • Removed the Windows-specific test example.
Activity
  • No specific activity was recorded for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a number of valuable updates, including improved build system support for NDK, Make, and Visual Studio, and refactoring to handle character types more robustly. However, a security vulnerability was identified in the Replace::AddRule function due to an explicit narrowing cast from size_t to int. This cast can lead to an integer overflow if a large number of rules are added, potentially resulting in out-of-bounds memory access. Additionally, other critical and high-severity issues include an incorrect Makefile configuration attempting to build an executable instead of a static library, and further instances of incorrect casting between char* and unsigned char* which affects portability. Detailed comments and suggestions have been provided for each issue.

Comment thread ZACLib/Makefile Outdated
Comment on lines +12 to +13
$(TARGET): $(OBJ)
$(CXX) $(OBJ) -o $(TARGET)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

The current Makefile configuration attempts to create an executable from the object files. This will fail during linking because there is no main function. Since this is a library, you should create a static archive (.a file) using ar instead.

$(TARGET): $(OBJ)
	ar rcs $@ $(OBJ)

Comment thread ZACLib/ZACLib.cpp Outdated
const auto c = static_cast<unsigned char>(i);
if (trie[node].next[c] == -1) {
trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions)
trie[node].next[c] = static_cast<Node::value_type>(trie.size());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Casting trie.size() (a size_t) to Node::value_type (an int) can lead to an overflow if the number of nodes in the trie exceeds INT_MAX. This could cause incorrect behavior. You should consider changing Node::value_type to size_t or adding a runtime check to prevent overflow.

Comment thread ZACLib/ZACLib.cpp Outdated
trie[node].output_id = static_cast<Node::value_type>(outputs.size());
trie[node].match_len = from.size();
outputs.emplace_back(to.data(), to.size());
outputs.emplace_back(ArmCastChar(to.data()), to.size());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The ArmCastChar macro is being used incorrectly here. outputs is a std::vector<std::string>, and std::string's constructor expects a const char*, not a const ZAC_CHAR* (which can be const unsigned char*). This can lead to non-portable behavior. You should reinterpret_cast to const char* when constructing the std::string.

Suggested change
outputs.emplace_back(ArmCastChar(to.data()), to.size());
outputs.emplace_back(reinterpret_cast<const char*>(to.data()), to.size());

Comment thread ZACLib/ZACLib.cpp Outdated
if (input.empty()) return result;
if (max_rule_len == 0) {
result.append(input.data(), input.size());
result.append(ArmCastChar(input.data()), input.size());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The ArmCastChar macro is used incorrectly here. std::string::append expects a const char*, but ArmCastChar(input.data()) may resolve to const unsigned char*, which is not portable. You should reinterpret_cast to const char*.

Suggested change
result.append(ArmCastChar(input.data()), input.size());
result.append(reinterpret_cast<const char*>(input.data()), input.size());

Comment thread ZACLib/ZACLib.cpp Outdated
}

result.append(input.data() + last_pos, cursor - last_pos);
result.append(ArmCastChar(input.data() + last_pos), cursor - last_pos);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The ArmCastChar macro is used incorrectly here. std::string::append expects a const char*, but ArmCastChar(input.data() + last_pos) may resolve to const unsigned char*, which is not portable. You should reinterpret_cast to const char*.

Suggested change
result.append(ArmCastChar(input.data() + last_pos), cursor - last_pos);
result.append(reinterpret_cast<const char*>(input.data() + last_pos), cursor - last_pos);

Comment thread ZACLib/ZACLib.cpp Outdated
trie[node].output_id = outputs.size();
trie[node].match_len = from.size();
outputs.emplace_back(from.data(), from.size());
outputs.emplace_back(ArmCastChar(from.data()), from.size());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The ArmCastChar macro is being used incorrectly here. outputs is a std::vector<std::string>, and std::string's constructor expects a const char*, not a const ZAC_CHAR* (which can be const unsigned char*). This can lead to non-portable behavior. You should reinterpret_cast to const char* when constructing the std::string.

Suggested change
outputs.emplace_back(ArmCastChar(from.data()), from.size());
outputs.emplace_back(reinterpret_cast<const char*>(from.data()), from.size());

Comment thread ZACLib/ZACLib.cpp Outdated
for (const unsigned char c : from) {
if (trie[node].next[c] == -1) {
trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions)
trie[node].next[c] = static_cast<Node::value_type>(trie.size());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Casting trie.size() (a size_t) to Node::value_type (an int) can lead to an overflow if the number of nodes in the trie exceeds INT_MAX. This could cause incorrect behavior. You should consider changing Node::value_type to size_t or adding a runtime check to prevent overflow.

Comment thread ZACLib/ZACLib_Types.hpp Outdated
ZAC_SV(const std::string& s) : m_data(s.c_str()),
m_size(s.size()) {} // 模仿std::string_view,不禁止隐式构造
ZAC_SV(const ZAC_CHAR* d) : m_data(d),
m_size(d ? std::strlen(ArmCastChar(d)) : 0) {}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The strlen function expects a const char* argument, but you are passing it ArmCastChar(d). When CHAR_UNSIGNED is defined, d is a const unsigned char* and ArmCastChar is a no-op, resulting in non-portable code. You should cast d to const char* before passing it to strlen.

                                    m_size(d ? std::strlen(reinterpret_cast<const char*>(d)) : 0) {}

Comment thread ZACLib/ZACLib.cpp Outdated

if (from.size() > trie[node].match_len) {
trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions)
trie[node].output_id = static_cast<Node::value_type>(outputs.size());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

In Replace::AddRule (ZACLib/ZACLib.cpp), a critical security vulnerability exists due to an explicit narrowing cast from outputs.size() (type std::size_t) to Node::value_type (which is int) when assigning to trie[node].output_id. This cast can lead to an integer overflow if the number of rules exceeds INT_MAX, potentially causing out-of-bounds memory access when indexing the outputs vector later in Replace::Do. This is inconsistent with other parts of the code like Search::AddRule where no such cast is performed. Removing this unnecessary cast will ensure correctness and safety.

Suggested change
trie[node].output_id = static_cast<Node::value_type>(outputs.size());
trie[node].output_id = outputs.size();

Comment thread ZACLib/Makefile Outdated

SRC := ZACLib.cpp
OBJ := $(SRC:.cpp=.o)
TARGET := ZACLib
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

For convention, static library targets are usually prefixed with lib and have a .a extension. This should be changed to libZACLib.a to align with standard practices and the required change to the build rule.

TARGET := libZACLib.a

@WJiangzhi
Copy link
Copy Markdown
Member Author

/gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a number of valuable updates and cleanups. It enhances build system support for NDK, Make, and Visual Studio, removes non-cross-platform examples, and deprecates the single-header version. Key improvements include fixing incorrect unsigned char handling for better cross-platform compatibility and restoring C++17 std::string compatibility for ZAC_SV. I have one suggestion regarding the Visual Studio project file for improved robustness.

Comment thread ZACLib/ZACLib.vcxproj
Comment on lines +14 to +16
<ItemGroup>
<ClInclude Include=".\**\*.h*" />
</ItemGroup>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using a broad wildcard .\**\*.h* can be fragile and might unintentionally include temporary or unrelated header files. It's generally safer and more explicit to list the header files directly.

  <ItemGroup>
    <ClInclude Include="ZACLib.hpp" />
    <ClInclude Include="ZACLib_Types.hpp" />
  </ItemGroup>

@WJiangzhi WJiangzhi merged commit 3fad7d7 into master Mar 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android平台部分情况下无法正确匹配

1 participant