Skip to content

Commit 94a2c47

Browse files
committed
Fix issue with escape_json
1 parent 899ad05 commit 94a2c47

File tree

5 files changed

+99
-28
lines changed

5 files changed

+99
-28
lines changed

binlog_json_parser/CMakeLists.txt

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,19 @@ project(binlog_json_parser)
55
set(CMAKE_CXX_STANDARD 23)
66
set(CMAKE_CXX_STANDARD_REQUIRED ON)
77

8+
include(CheckIPOSupported)
9+
include(CheckCSourceCompiles)
10+
check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_OUTPUT)
11+
12+
if(IPO_SUPPORTED)
13+
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
14+
message(STATUS "Interprocedural optimization (IPO/LTO) enabled globally.")
15+
else()
16+
message(STATUS "IPO/LTO is not supported: ${IPO_OUTPUT}")
17+
endif()
18+
819
# Check if the build type is Release
920
if(CMAKE_BUILD_TYPE STREQUAL "Release")
10-
1121
# Set optimization level to -O3 for release builds
1222
if(NOT CMAKE_CXX_FLAGS_RELEASE MATCHES "-O")
1323
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
@@ -32,24 +42,35 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release")
3242
message(WARNING "The -march option will not be set because the system is not x86 or x64.")
3343
endif()
3444

35-
# Check for LTO support
36-
include(CheckCXXCompilerFlag)
37-
38-
check_cxx_compiler_flag("-flto" COMPILER_SUPPORTS_LTO)
39-
40-
if(COMPILER_SUPPORTS_LTO)
41-
message(STATUS "Link Time Optimization (LTO) is supported by the compiler.")
42-
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto")
43-
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
44-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -flto")
45-
else()
46-
message(WARNING "Link Time Optimization (LTO) is not supported by the compiler.")
47-
endif()
48-
4945
# Export compile flags to a file
5046
file(WRITE "${CMAKE_BINARY_DIR}/compile_flags.txt" "CXXFLAGS: ${CMAKE_CXX_FLAGS_RELEASE}\n")
5147
file(APPEND "${CMAKE_BINARY_DIR}/compile_flags.txt" "LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}\n")
52-
5348
endif()
5449

55-
add_library(mysqljsonparse SHARED mysqljsonparse.cpp mysql_json_parser.cpp)
50+
check_c_source_compiles("
51+
#include <features.h>
52+
#if defined(__GLIBC__)
53+
#error \"This is glibc, not musl\"
54+
#endif
55+
#include <stdio.h>
56+
int main() { return 0; }
57+
" IS_MUSL)
58+
59+
option(ALPINE_STATIC "Force fully static build when using musl/Alpine" ${IS_MUSL})
60+
61+
if(ALPINE_STATIC)
62+
add_definitions(-D_FORTIFY_SOURCE=0)
63+
message(STATUS "musl detected → producing shared library with static musl linking")
64+
65+
add_library(mysqljsonparse SHARED mysqljsonparse.cpp mysql_json_parser.cpp)
66+
target_link_options(mysqljsonparse PRIVATE
67+
-static
68+
-static-libgcc
69+
-static-libstdc++
70+
-fPIC
71+
)
72+
target_compile_options(mysqljsonparse PRIVATE -fPIC)
73+
else()
74+
message(STATUS "musl not detected → building shared library with dynamic glibc")
75+
add_library(mysqljsonparse SHARED mysqljsonparse.cpp mysql_json_parser.cpp)
76+
endif()

binlog_json_parser/Dockerfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM alpine:3.22 AS build
2+
3+
RUN apk add --no-cache \
4+
build-base \
5+
clang \
6+
lld \
7+
cmake \
8+
ninja \
9+
musl-dev
10+
11+
WORKDIR /src
12+
13+
COPY . .
14+
15+
RUN cmake -S . -B build -G Ninja \
16+
-DCMAKE_BUILD_TYPE=Release \
17+
-DCMAKE_C_COMPILER=clang \
18+
-DCMAKE_CXX_COMPILER=clang++ \
19+
&& ninja -C build -v
20+
21+
FROM scratch AS artifact
22+
23+
COPY --from=build /src/build/libmysqljsonparse.so /
24+
25+
CMD [""]

binlog_json_parser/build_static.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
IMAGE_TAG=${1:-mysqljsonparse:alpine-static}
5+
ARTIFACT=${2:-libmysqljsonparse.so}
6+
7+
echo "[INFO] Building Docker image '${IMAGE_TAG}'..."
8+
docker build -t "${IMAGE_TAG}" .
9+
10+
echo "[INFO] Creating temporary container from image..."
11+
CID=$(docker create "${IMAGE_TAG}")
12+
trap 'docker rm -fv "$CID" >/dev/null' EXIT
13+
14+
echo "[INFO] Copying '${ARTIFACT}' from container to host..."
15+
# The Dockerfile puts the artifact in the image root (/)
16+
if docker cp "${CID}:/${ARTIFACT}" "./${ARTIFACT}"; then
17+
echo "[SUCCESS] Artifact '${ARTIFACT}' extracted to $(pwd)"
18+
else
19+
echo "[ERROR] Failed to find '${ARTIFACT}' inside the image." >&2
20+
exit 1
21+
fi

binlog_json_parser/mysql_json_parser.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,24 +120,28 @@ static bool read_variable_length(const char *data, size_t data_length,
120120

121121
std::string escape_json(const std::string &s) {
122122
std::ostringstream o;
123-
for (auto c = s.cbegin(); c != s.cend(); c++) {
124-
switch (*c) {
125-
case '"': o << "\\\""; break;
123+
124+
for (const unsigned char uc : s) {
125+
switch (uc) {
126+
case '"': o << "\\\""; break;
126127
case '\\': o << "\\\\"; break;
127-
case '\b': o << "\\b"; break;
128-
case '\f': o << "\\f"; break;
129-
case '\n': o << "\\n"; break;
130-
case '\r': o << "\\r"; break;
131-
case '\t': o << "\\t"; break;
128+
case '\b': o << "\\b"; break;
129+
case '\f': o << "\\f"; break;
130+
case '\n': o << "\\n"; break;
131+
case '\r': o << "\\r"; break;
132+
case '\t': o << "\\t"; break;
133+
132134
default:
133-
if (*c <= '\x1f') {
135+
if (uc <= 0x1F) {
134136
o << "\\u"
135-
<< std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(*c);
137+
<< std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(uc)
138+
<< std::dec;
136139
} else {
137-
o << *c;
140+
o << static_cast<char>(uc);
138141
}
139142
}
140143
}
144+
141145
return o.str();
142146
}
143147

Binary file not shown.

0 commit comments

Comments
 (0)