Safe API Framework 0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
String Module - User Guide

What is the String Module?

The String module provides bounded string operations to prevent buffer overflows. All operations specify maximum lengths and return status codes instead of silently truncating or crashing.

Key idea:** Strings with known boundaries. No overflows, no truncation surprises.

Quick Start

1. Include Header

#include "rte/string/rte_string.h"

2. Safe Copy

// ✗ BAD: Unbounded
strcpy(dest, src); // What if src is longer than dest?
// ✓ GOOD: Bounded with status code
rte_status_t rc = rte_strncpy(dest, src, 32);
if (rc != RTE_STATUS_OK) {
log_error("String copy failed: %s", rte_status_to_string(rc));
}
const char * rte_status_to_string(rte_status_t status)
Returns a short, static, human-readable string for a status code. Intended for diagnostics/logging on...
Definition rte_status.c:22
rte_status_t
Common result/status codes.
Definition rte_status.h:27
@ RTE_STATUS_OK
Definition rte_status.h:28

3. Safe Concatenation

char path[256];
strcpy(path, "/home/");
rte_status_t rc = rte_strncat(path, username, 256);
log_error("Path too long");
return rc;
}
@ RTE_STATUS_RESOURCE_EXHAUSTED
Definition rte_status.h:33

4. Safe String Length

size_t len = rte_strnlen(str, 256);
if (len == 256) {
log_error("String not null-terminated within 256 bytes");
}

Operations

// Copy: Bounded strcpy
rte_status_t rte_strncpy(char *dest, const char *src, size_t max_len);
// Concatenate: Bounded strcat
rte_status_t rte_strncat(char *dest, const char *src, size_t max_len);
// Length: With maximum limit
size_t rte_strnlen(const char *str, size_t max_len);
// Comparison: Bounded strcmp
int rte_strncmp(const char *a, const char *b, size_t max_len);
// Format: Bounded sprintf
rte_status_t rte_snprintf(char *buf, size_t max_len, const char *fmt, ...);

Practical Examples

Example 1: Command Parsing

void parse_command(const char *input) {
char cmd[32];
char arg[64];
// Parse safely
if (sscanf(input, "%31s %63s", cmd, arg) != 2) {
log_error("Invalid command format");
return;
}
// Process command
if (rte_strncmp(cmd, "status", 32) == 0) {
handle_status(arg);
} else if (rte_strncmp(cmd, "reset", 32) == 0) {
handle_reset(arg);
}
}

Example 2: Log Message Formatting

void log_event(const char *event, int code, const char *detail) {
char buffer[256];
rte_status_t rc = rte_snprintf(buffer, sizeof(buffer),
"[%u] EVENT: %s (code=%d) - %s",
get_timestamp(), event, code, detail);
if (rc != RTE_STATUS_OK) {
// Message too long, truncated or failed
log_error("Log message formatting failed");
return;
}
write_to_log(buffer);
}

Best Practices

  1. Always Specify Maximum Length
    • No open-ended operations
    • Always know buffer size
    • Use sizeof(buffer) when possible
  2. Check Return Codes
    • RTE_STATUS_OK: Success, string complete
    • RTE_STATUS_RESOURCE_EXHAUSTED: String truncated/overflow
    • RTE_STATUS_INVALID_PARAM: Bad input
  3. Use Fixed-Size Buffers
    • Never dynamically sized strings
    • Allocate statically
    • Know max length at compile-time
  4. Prefer snprintf Over sprintf
    • snprintf has length limit
    • sprintf doesn't (buffer overflow risk)
    • Always use rte_snprintf()

See Also