| 242 | } |
| 243 | |
| 244 | static bool json_escape_version(const char *value, char out[DAEMON_SERVICE_ESCAPED_VERSION_CAP]) { |
| 245 | static const char hex[] = "0123456789abcdef"; |
| 246 | size_t length = 0; |
| 247 | if (!version_valid(value) || !bounded_length(value, CBM_DAEMON_VERSION_TEXT_SIZE, &length)) { |
| 248 | return false; |
| 249 | } |
| 250 | size_t used = 0; |
| 251 | for (size_t i = 0; i < length; i++) { |
| 252 | unsigned char ch = (unsigned char)value[i]; |
| 253 | if (ch == '"' || ch == '\\') { |
| 254 | if (used + 2 >= DAEMON_SERVICE_ESCAPED_VERSION_CAP) { |
| 255 | return false; |
| 256 | } |
| 257 | out[used++] = '\\'; |
| 258 | out[used++] = (char)ch; |
| 259 | } else if (ch < 0x20) { |
| 260 | if (used + 6 >= DAEMON_SERVICE_ESCAPED_VERSION_CAP) { |
| 261 | return false; |
| 262 | } |
| 263 | out[used++] = '\\'; |
| 264 | out[used++] = 'u'; |
| 265 | out[used++] = '0'; |
| 266 | out[used++] = '0'; |
| 267 | out[used++] = hex[ch >> 4]; |
| 268 | out[used++] = hex[ch & 0x0f]; |
| 269 | } else { |
| 270 | if (used + 1 >= DAEMON_SERVICE_ESCAPED_VERSION_CAP) { |
| 271 | return false; |
| 272 | } |
| 273 | out[used++] = (char)ch; |
| 274 | } |
| 275 | } |
| 276 | out[used] = '\0'; |
| 277 | return true; |
| 278 | } |
| 279 | |
| 280 | static bool conflict_log_record(const cbm_daemon_conflict_t *conflict, |
| 281 | char out[DAEMON_SERVICE_LOG_RECORD_CAP], size_t *length_out) { |
no test coverage detected