/* * Copyright (C) 2023 Yubico AB - See COPYING */ #include #include #include #include #include "util.h" static int buf_write(uint8_t **dst, size_t *size, const void *src, size_t n) { if (*size < n) { return -1; } memcpy(*dst, src, n); *dst += n; *size -= n; return 0; } static int buf_write_byte(uint8_t **dst, size_t *size, uint8_t c) { return buf_write(dst, size, &c, sizeof(c)); } static const char *lookup(char var, const char *user) { switch (var) { case 'u': return user; case '%': return "%"; default: // Capture all unknown variables (incl. null byte). return NULL; } } char *expand_variables(const char *str, const char *user) { uint8_t *tail, *head; size_t size = PATH_MAX; int ok = -1; if (str == NULL || (tail = head = malloc(size)) == NULL) { return NULL; } for (; *str != '\0'; str++) { if (*str == '%') { str++; const char *value = lookup(*str, user); if (value == NULL || *value == '\0' || buf_write(&head, &size, value, strlen(value)) != 0) { goto fail; } } else if (buf_write_byte(&head, &size, (uint8_t)*str) != 0) { goto fail; } } ok = buf_write_byte(&head, &size, '\0'); fail: if (ok != 0) { free(tail); return NULL; } return (char *) tail; }