Skip to content

Commit 91921e4

Browse files
fix: use printf to safely inject secrets into development_config.cpp
- Remove indentation from heredocs - Use printf instead of echo to avoid newline issues - Strip newlines/carriage returns from secret values - Fixes build failure due to broken string literals
1 parent 360e457 commit 91921e4

File tree

1 file changed

+145
-123
lines changed

1 file changed

+145
-123
lines changed

.github/workflows/commons-release.yml

Lines changed: 145 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -75,70 +75,81 @@ jobs:
7575
BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }}
7676
run: |
7777
# Generate development_config.cpp with real credentials from secrets
78-
cat > src/infrastructure/network/development_config.cpp << 'DEVCONFIG_EOF'
79-
/**
80-
* @file development_config.cpp
81-
* @brief Development mode configuration with credentials from CI secrets
82-
*/
83-
84-
#include <cstring>
85-
86-
#include "rac/core/rac_logger.h"
87-
#include "rac/infrastructure/network/rac_dev_config.h"
88-
89-
namespace {
90-
91-
DEVCONFIG_EOF
92-
93-
# Inject secrets (avoiding heredoc variable expansion issues)
94-
echo "constexpr const char* SUPABASE_URL = \"${SUPABASE_URL}\";" >> src/infrastructure/network/development_config.cpp
95-
echo "constexpr const char* SUPABASE_ANON_KEY = \"${SUPABASE_ANON_KEY}\";" >> src/infrastructure/network/development_config.cpp
96-
echo "constexpr const char* BUILD_TOKEN = \"${BUILD_TOKEN:-bt_release_build}\";" >> src/infrastructure/network/development_config.cpp
97-
echo "constexpr const char* SENTRY_DSN = nullptr;" >> src/infrastructure/network/development_config.cpp
98-
99-
cat >> src/infrastructure/network/development_config.cpp << 'DEVCONFIG_EOF'
100-
101-
} // anonymous namespace
102-
103-
extern "C" {
104-
105-
bool rac_dev_config_is_available(void) {
106-
if (SUPABASE_URL == nullptr || SUPABASE_ANON_KEY == nullptr) return false;
107-
if (std::strlen(SUPABASE_URL) == 0 || std::strlen(SUPABASE_ANON_KEY) == 0) return false;
108-
if (std::strstr(SUPABASE_URL, "YOUR_") != nullptr) return false;
109-
if (std::strstr(SUPABASE_ANON_KEY, "YOUR_") != nullptr) return false;
110-
return true;
111-
}
112-
113-
const char* rac_dev_config_get_supabase_url(void) {
114-
return SUPABASE_URL;
115-
}
116-
117-
const char* rac_dev_config_get_supabase_key(void) {
118-
return SUPABASE_ANON_KEY;
119-
}
120-
121-
const char* rac_dev_config_get_build_token(void) {
122-
return BUILD_TOKEN;
123-
}
124-
125-
const char* rac_dev_config_get_sentry_dsn(void) {
126-
return SENTRY_DSN;
127-
}
128-
129-
bool rac_dev_config_has_supabase(void) {
130-
return rac_dev_config_is_available();
131-
}
132-
133-
bool rac_dev_config_has_build_token(void) {
134-
return BUILD_TOKEN != nullptr && std::strlen(BUILD_TOKEN) > 0;
135-
}
136-
137-
} // extern "C"
138-
DEVCONFIG_EOF
78+
# Use printf with %s to safely handle secret values (no newline interpretation)
79+
80+
CONFIG_FILE="src/infrastructure/network/development_config.cpp"
81+
82+
# Write the file header and includes
83+
cat > "$CONFIG_FILE" << 'EOF'
84+
/**
85+
* @file development_config.cpp
86+
* @brief Development mode configuration with credentials from CI secrets
87+
*/
88+
89+
#include <cstring>
90+
91+
#include "rac/core/rac_logger.h"
92+
#include "rac/infrastructure/network/rac_dev_config.h"
93+
94+
namespace {
95+
96+
EOF
97+
98+
# Inject secrets using printf (safer than echo for special chars)
99+
# Remove any trailing newlines/whitespace from secrets
100+
CLEAN_URL=$(printf '%s' "$SUPABASE_URL" | tr -d '\n\r')
101+
CLEAN_KEY=$(printf '%s' "$SUPABASE_ANON_KEY" | tr -d '\n\r')
102+
CLEAN_TOKEN=$(printf '%s' "${BUILD_TOKEN:-bt_release_build}" | tr -d '\n\r')
103+
104+
printf 'constexpr const char* SUPABASE_URL = "%s";\n' "$CLEAN_URL" >> "$CONFIG_FILE"
105+
printf 'constexpr const char* SUPABASE_ANON_KEY = "%s";\n' "$CLEAN_KEY" >> "$CONFIG_FILE"
106+
printf 'constexpr const char* BUILD_TOKEN = "%s";\n' "$CLEAN_TOKEN" >> "$CONFIG_FILE"
107+
printf 'constexpr const char* SENTRY_DSN = nullptr;\n' >> "$CONFIG_FILE"
108+
109+
# Write the rest of the file
110+
cat >> "$CONFIG_FILE" << 'EOF'
111+
112+
} // anonymous namespace
113+
114+
extern "C" {
115+
116+
bool rac_dev_config_is_available(void) {
117+
if (SUPABASE_URL == nullptr || SUPABASE_ANON_KEY == nullptr) return false;
118+
if (std::strlen(SUPABASE_URL) == 0 || std::strlen(SUPABASE_ANON_KEY) == 0) return false;
119+
if (std::strstr(SUPABASE_URL, "YOUR_") != nullptr) return false;
120+
if (std::strstr(SUPABASE_ANON_KEY, "YOUR_") != nullptr) return false;
121+
return true;
122+
}
123+
124+
const char* rac_dev_config_get_supabase_url(void) {
125+
return SUPABASE_URL;
126+
}
127+
128+
const char* rac_dev_config_get_supabase_key(void) {
129+
return SUPABASE_ANON_KEY;
130+
}
131+
132+
const char* rac_dev_config_get_build_token(void) {
133+
return BUILD_TOKEN;
134+
}
135+
136+
const char* rac_dev_config_get_sentry_dsn(void) {
137+
return SENTRY_DSN;
138+
}
139+
140+
bool rac_dev_config_has_supabase(void) {
141+
return rac_dev_config_is_available();
142+
}
143+
144+
bool rac_dev_config_has_build_token(void) {
145+
return BUILD_TOKEN != nullptr && std::strlen(BUILD_TOKEN) > 0;
146+
}
147+
148+
} // extern "C"
149+
EOF
139150

140151
echo "=== Generated development_config.cpp ==="
141-
head -30 src/infrastructure/network/development_config.cpp
152+
head -30 "$CONFIG_FILE"
142153
echo "..."
143154
echo "(credentials redacted)"
144155

@@ -219,67 +230,78 @@ jobs:
219230
BUILD_TOKEN: ${{ secrets.BUILD_TOKEN }}
220231
run: |
221232
# Generate development_config.cpp with real credentials from secrets
222-
cat > src/infrastructure/network/development_config.cpp << 'DEVCONFIG_EOF'
223-
/**
224-
* @file development_config.cpp
225-
* @brief Development mode configuration with credentials from CI secrets
226-
*/
227-
228-
#include <cstring>
229-
230-
#include "rac/core/rac_logger.h"
231-
#include "rac/infrastructure/network/rac_dev_config.h"
232-
233-
namespace {
234-
235-
DEVCONFIG_EOF
236-
237-
# Inject secrets
238-
echo "constexpr const char* SUPABASE_URL = \"${SUPABASE_URL}\";" >> src/infrastructure/network/development_config.cpp
239-
echo "constexpr const char* SUPABASE_ANON_KEY = \"${SUPABASE_ANON_KEY}\";" >> src/infrastructure/network/development_config.cpp
240-
echo "constexpr const char* BUILD_TOKEN = \"${BUILD_TOKEN:-bt_release_build}\";" >> src/infrastructure/network/development_config.cpp
241-
echo "constexpr const char* SENTRY_DSN = nullptr;" >> src/infrastructure/network/development_config.cpp
242-
243-
cat >> src/infrastructure/network/development_config.cpp << 'DEVCONFIG_EOF'
244-
245-
} // anonymous namespace
246-
247-
extern "C" {
248-
249-
bool rac_dev_config_is_available(void) {
250-
if (SUPABASE_URL == nullptr || SUPABASE_ANON_KEY == nullptr) return false;
251-
if (std::strlen(SUPABASE_URL) == 0 || std::strlen(SUPABASE_ANON_KEY) == 0) return false;
252-
if (std::strstr(SUPABASE_URL, "YOUR_") != nullptr) return false;
253-
if (std::strstr(SUPABASE_ANON_KEY, "YOUR_") != nullptr) return false;
254-
return true;
255-
}
256-
257-
const char* rac_dev_config_get_supabase_url(void) {
258-
return SUPABASE_URL;
259-
}
260-
261-
const char* rac_dev_config_get_supabase_key(void) {
262-
return SUPABASE_ANON_KEY;
263-
}
264-
265-
const char* rac_dev_config_get_build_token(void) {
266-
return BUILD_TOKEN;
267-
}
268-
269-
const char* rac_dev_config_get_sentry_dsn(void) {
270-
return SENTRY_DSN;
271-
}
272-
273-
bool rac_dev_config_has_supabase(void) {
274-
return rac_dev_config_is_available();
275-
}
276-
277-
bool rac_dev_config_has_build_token(void) {
278-
return BUILD_TOKEN != nullptr && std::strlen(BUILD_TOKEN) > 0;
279-
}
280-
281-
} // extern "C"
282-
DEVCONFIG_EOF
233+
# Use printf with %s to safely handle secret values (no newline interpretation)
234+
235+
CONFIG_FILE="src/infrastructure/network/development_config.cpp"
236+
237+
# Write the file header and includes
238+
cat > "$CONFIG_FILE" << 'EOF'
239+
/**
240+
* @file development_config.cpp
241+
* @brief Development mode configuration with credentials from CI secrets
242+
*/
243+
244+
#include <cstring>
245+
246+
#include "rac/core/rac_logger.h"
247+
#include "rac/infrastructure/network/rac_dev_config.h"
248+
249+
namespace {
250+
251+
EOF
252+
253+
# Inject secrets using printf (safer than echo for special chars)
254+
# Remove any trailing newlines/whitespace from secrets
255+
CLEAN_URL=$(printf '%s' "$SUPABASE_URL" | tr -d '\n\r')
256+
CLEAN_KEY=$(printf '%s' "$SUPABASE_ANON_KEY" | tr -d '\n\r')
257+
CLEAN_TOKEN=$(printf '%s' "${BUILD_TOKEN:-bt_release_build}" | tr -d '\n\r')
258+
259+
printf 'constexpr const char* SUPABASE_URL = "%s";\n' "$CLEAN_URL" >> "$CONFIG_FILE"
260+
printf 'constexpr const char* SUPABASE_ANON_KEY = "%s";\n' "$CLEAN_KEY" >> "$CONFIG_FILE"
261+
printf 'constexpr const char* BUILD_TOKEN = "%s";\n' "$CLEAN_TOKEN" >> "$CONFIG_FILE"
262+
printf 'constexpr const char* SENTRY_DSN = nullptr;\n' >> "$CONFIG_FILE"
263+
264+
# Write the rest of the file
265+
cat >> "$CONFIG_FILE" << 'EOF'
266+
267+
} // anonymous namespace
268+
269+
extern "C" {
270+
271+
bool rac_dev_config_is_available(void) {
272+
if (SUPABASE_URL == nullptr || SUPABASE_ANON_KEY == nullptr) return false;
273+
if (std::strlen(SUPABASE_URL) == 0 || std::strlen(SUPABASE_ANON_KEY) == 0) return false;
274+
if (std::strstr(SUPABASE_URL, "YOUR_") != nullptr) return false;
275+
if (std::strstr(SUPABASE_ANON_KEY, "YOUR_") != nullptr) return false;
276+
return true;
277+
}
278+
279+
const char* rac_dev_config_get_supabase_url(void) {
280+
return SUPABASE_URL;
281+
}
282+
283+
const char* rac_dev_config_get_supabase_key(void) {
284+
return SUPABASE_ANON_KEY;
285+
}
286+
287+
const char* rac_dev_config_get_build_token(void) {
288+
return BUILD_TOKEN;
289+
}
290+
291+
const char* rac_dev_config_get_sentry_dsn(void) {
292+
return SENTRY_DSN;
293+
}
294+
295+
bool rac_dev_config_has_supabase(void) {
296+
return rac_dev_config_is_available();
297+
}
298+
299+
bool rac_dev_config_has_build_token(void) {
300+
return BUILD_TOKEN != nullptr && std::strlen(BUILD_TOKEN) > 0;
301+
}
302+
303+
} // extern "C"
304+
EOF
283305

284306
echo "=== Generated development_config.cpp for Android ==="
285307

0 commit comments

Comments
 (0)