LCOV - code coverage report
Current view: top level - src/core - json_util.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.0 % 25 23
Test Date: 2026-04-20 19:54:22 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-3.0-or-later */
       2              : /* Copyright 2026 Peter Csaszar */
       3              : 
       4              : /**
       5              :  * @file core/json_util.c
       6              :  * @brief Minimal JSON string escaping — see json_util.h.
       7              :  */
       8              : 
       9              : #include "json_util.h"
      10              : 
      11              : #include <stddef.h>
      12              : #include <stdint.h>
      13              : #include <stdio.h>
      14              : 
      15            7 : size_t json_escape_str(char *dst, size_t cap, const char *src)
      16              : {
      17            7 :     if (!dst || cap == 0) return 0;
      18            7 :     if (!src) src = "";
      19              : 
      20            7 :     size_t out = 0;   /* bytes written so far (excl. NUL) */
      21              : 
      22              : #define PUSH(c)  do { if (out + 1 < cap) dst[out++] = (char)(c); else out++; } while (0)
      23              : #define PUSH2(a,b) do { PUSH(a); PUSH(b); } while (0)
      24              : 
      25           50 :     for (const unsigned char *p = (const unsigned char *)src; *p; p++) {
      26           43 :         unsigned char c = *p;
      27           43 :         switch (c) {
      28            2 :         case '"':  PUSH2('\\', '"');  break;
      29            1 :         case '\\': PUSH2('\\', '\\'); break;
      30            0 :         case '\b': PUSH2('\\', 'b');  break;
      31            0 :         case '\f': PUSH2('\\', 'f');  break;
      32            1 :         case '\n': PUSH2('\\', 'n');  break;
      33            1 :         case '\r': PUSH2('\\', 'r');  break;
      34            1 :         case '\t': PUSH2('\\', 't');  break;
      35           37 :         default:
      36           37 :             if (c < 0x20u) {
      37              :                 /* Other C0 controls: \uXXXX */
      38              :                 char seq[7];
      39            2 :                 int n = snprintf(seq, sizeof(seq), "\\u%04x", (unsigned)c);
      40           14 :                 for (int i = 0; i < n; i++) PUSH(seq[i]);
      41              :             } else {
      42              :                 /* ASCII printable or high byte (UTF-8 pass-through) */
      43           35 :                 PUSH(c);
      44              :             }
      45           37 :             break;
      46              :         }
      47              :     }
      48              : 
      49              : #undef PUSH2
      50              : #undef PUSH
      51              : 
      52              :     /* Always NUL-terminate within the buffer. */
      53            7 :     if (out < cap)
      54            6 :         dst[out] = '\0';
      55            1 :     else if (cap > 0)
      56            1 :         dst[cap - 1] = '\0';
      57              : 
      58            7 :     return out;
      59              : }
        

Generated by: LCOV version 2.0-1