aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2024-06-09 08:12:02 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2024-06-09 08:12:02 -0400
commite4f615faf36e0163a5b550df9916a1e6198770b9 (patch)
tree13c54155e33b228a5a3661a0aea859bfd2de4616 /src
parent3357f87a5efe478be2433787c29de640dc21b33d (diff)
downloadstasis-e4f615faf36e0163a5b550df9916a1e6198770b9.tar.gz
Address shortcomings and bugs flushed out by unit tests
Diffstat (limited to 'src')
-rw-r--r--src/docker.c4
-rw-r--r--src/str.c150
-rw-r--r--src/strlist.c232
-rw-r--r--src/system.c54
-rw-r--r--src/template.c54
-rw-r--r--src/utils.c34
6 files changed, 351 insertions, 177 deletions
diff --git a/src/docker.c b/src/docker.c
index f8c9c11..308fbc7 100644
--- a/src/docker.c
+++ b/src/docker.c
@@ -28,7 +28,7 @@ int docker_script(const char *image, char *data, unsigned flags) {
char buffer[OMC_BUFSIZ];
memset(cmd, 0, sizeof(cmd));
- snprintf(cmd, sizeof(cmd) - 1, "docker run --rm -i %s /bin/bash -", image);
+ snprintf(cmd, sizeof(cmd) - 1, "docker run --rm -i %s /bin/sh -", image);
outfile = popen(cmd, "w");
if (!outfile) {
@@ -103,7 +103,7 @@ static int docker_exists() {
return false;
}
-char *docker_ident() {
+static char *docker_ident() {
FILE *fp = NULL;
char *tempfile = NULL;
char line[PATH_MAX];
diff --git a/src/str.c b/src/str.c
index a5d42a6..f27e946 100644
--- a/src/str.c
+++ b/src/str.c
@@ -26,7 +26,6 @@ int startswith(const char *sptr, const char *pattern) {
return 1;
}
-
int endswith(const char *sptr, const char *pattern) {
if (!sptr || !pattern) {
return -1;
@@ -61,64 +60,10 @@ void strchrdel(char *sptr, const char *chars) {
return;
}
- while (*sptr != '\0') {
- for (int i = 0; chars[i] != '\0'; i++) {
- if (*sptr == chars[i]) {
- memmove(sptr, sptr + 1, strlen(sptr));
- }
- }
- sptr++;
- }
-}
-
-
-long int strchroff(const char *sptr, int ch) {
- char *orig = strdup(sptr);
- char *tmp = orig;
- long int result = 0;
-
- int found = 0;
- size_t i = 0;
-
- while (*tmp != '\0') {
- if (*tmp == ch) {
- found = 1;
- break;
- }
- tmp++;
- i++;
- }
-
- if (found == 0 && i == strlen(sptr)) {
- return -1;
- }
-
- result = tmp - orig;
- guard_free(orig);
-
- return result;
-}
-
-void strdelsuffix(char *sptr, const char *suffix) {
- if (!sptr || !suffix) {
- return;
- }
- size_t sptr_len = strlen(sptr);
- size_t suffix_len = strlen(suffix);
- intptr_t target_offset = sptr_len - suffix_len;
-
- // Prevent access to memory below input string
- if (target_offset < 0) {
- return;
- }
-
- // Create a pointer to
- char *target = sptr + target_offset;
- if (!strcmp(target, suffix)) {
- // Purge the suffix
- memset(target, '\0', suffix_len);
- // Recursive call continues removing suffix until it is gone
- strip(sptr);
+ for (size_t i = 0; i < strlen(chars); i++) {
+ char ch[2] = {0};
+ strncpy(ch, &chars[i], 1);
+ replace_text(sptr, ch, "", 0);
}
}
@@ -141,7 +86,7 @@ char** split(char *_sptr, const char* delim, size_t max)
if (max && i > max) {
break;
}
- split_alloc = num_chars(sptr, delim[i]);
+ split_alloc += num_chars(sptr, delim[i]);
}
// Preallocate enough records based on the number of delimiters
@@ -158,27 +103,35 @@ char** split(char *_sptr, const char* delim, size_t max)
}
// Separate the string into individual parts and store them in the result array
- int i = 0;
- size_t x = max;
char *token = NULL;
char *sptr_tmp = sptr;
- while((token = strsep(&sptr_tmp, delim)) != NULL) {
- result[i] = calloc(OMC_BUFSIZ, sizeof(char));
- if (x < max) {
- strcat(result[i], strstr(orig, delim) + 1);
+ size_t pos = 0;
+ size_t i;
+ for (i = 0; (token = strsep(&sptr_tmp, delim)) != NULL; i++) {
+ // When max is zero, record all tokens
+ if (max > 0 && i == max) {
+ // Maximum number of splits occurred.
+ // Record position in string
+ pos = token - sptr;
break;
- } else {
- if (!result[i]) {
- return NULL;
- }
- strcpy(result[i], token);
}
- i++;
- if (x > 0) {
- --x;
+ result[i] = calloc(OMC_BUFSIZ, sizeof(char));
+ if (!result[i]) {
+ return NULL;
}
- //memcpy(result[i], token, strlen(token) + 1); // copy the string contents into the record
+ strcpy(result[i], token);
}
+
+ // pos is non-zero when maximum split is reached
+ if (pos) {
+ // append the remaining string contents to array
+ result[i] = calloc(OMC_BUFSIZ, sizeof(char));
+ if (!result[i]) {
+ return NULL;
+ }
+ strcpy(result[i], &orig[pos]);
+ }
+
guard_free(sptr);
return result;
}
@@ -244,8 +197,9 @@ char *join_ex(char *separator, ...) {
if (tmp == NULL) {
perror("join_ex realloc failed");
return NULL;
+ } else if (tmp != argv) {
+ argv = tmp;
}
- argv = tmp;
size += strlen(current) + separator_len;
argv[argc] = strdup(current);
}
@@ -275,43 +229,37 @@ char *substring_between(char *sptr, const char *delims) {
// Ensure we have enough delimiters to continue
size_t delim_count = strlen(delims);
- if (delim_count != 2) {
+ if (delim_count < 2 || delim_count % 2) {
return NULL;
}
+ char delim_open[255] = {0};
+ strncpy(delim_open, delims, delim_count / 2);
+
+ char delim_close[255] = {0};
+ strcpy(delim_close, &delims[delim_count / 2]);
+
// Create pointers to the delimiters
- char *start = strchr(sptr, delims[0]);
+ char *start = strstr(sptr, delim_open);
if (start == NULL || strlen(start) == 0) {
return NULL;
}
- char *end = strchr(start + 1, delims[1]);
+ char *end = strstr(start + 1, delim_close);
if (end == NULL) {
return NULL;
}
- start++; // ignore leading delimiter
+ start += delim_count / 2; // ignore leading delimiter
// Get length of the substring
- size_t length = strlen(start);
+ size_t length = strlen(start) - strlen(end);
if (!length) {
return NULL;
}
- char *result = (char *)calloc(length + 1, sizeof(char));
- if (!result) {
- return NULL;
- }
-
- // Copy the contents of the substring to the result
- char *tmp = result;
- while (start != end) {
- *tmp = *start;
- tmp++;
- start++;
- }
-
- return result;
+ // Return the contents of the substring
+ return strndup(start, length);
}
/*
@@ -476,19 +424,16 @@ char *strip(char *sptr) {
size_t len = strlen(sptr);
if (len == 0) {
return sptr;
- }
- else if (len == 1 && (isblank(*sptr) || isspace(*sptr))) {
+ } else if (len == 1 && (isblank(*sptr) || isspace(*sptr))) {
*sptr = '\0';
return sptr;
- }
- for (size_t i = len; i != 0; --i) {
+ } for (size_t i = len; i != 0; --i) {
if (sptr[i] == '\0') {
continue;
}
if (isspace(sptr[i]) || isblank(sptr[i])) {
sptr[i] = '\0';
- }
- else {
+ } else {
break;
}
}
@@ -665,6 +610,9 @@ int strcmp_array(const char **a, const char **b) {
}
int isdigit_s(const char *s) {
+ if (!s || !strlen(s)) {
+ return 0; // nothing to do, fail
+ }
for (size_t i = 0; s[i] != '\0'; i++) {
if (isdigit(s[i]) == 0) {
return 0; // non-digit found, fail
diff --git a/src/strlist.c b/src/strlist.c
index d54ed06..bd88c46 100644
--- a/src/strlist.c
+++ b/src/strlist.c
@@ -3,7 +3,6 @@
* @file strlist.c
*/
#include "strlist.h"
-//#include "url.h"
#include "utils.h"
/**
@@ -71,6 +70,7 @@ int strlist_append_file(struct StrList *pStrList, char *_path, ReaderFn *readerF
char *path = NULL;
char *filename = NULL;
char **data = NULL;
+ int is_url = strstr(_path, "://") != NULL;
if (readerFn == NULL) {
readerFn = reader_strlist_append_file;
@@ -78,17 +78,32 @@ int strlist_append_file(struct StrList *pStrList, char *_path, ReaderFn *readerF
path = strdup(_path);
if (path == NULL) {
-
retval = -1;
goto fatal;
}
- filename = expandpath(path);
-
- if (filename == NULL) {
+ if (is_url) {
+ int fd;
+ char tempfile[PATH_MAX] = {0};
+ strcpy(tempfile, "/tmp/.remote_file.XXXXXX");
+ if ((fd = mkstemp(tempfile)) < 0) {
+ retval = -1;
+ goto fatal;
+ }
+ close(fd);
+ filename = tempfile;
+ long http_code = download(path, filename, NULL);
+ if (HTTP_ERROR(http_code)) {
+ retval = -1;
+ goto fatal;
+ }
- retval = -1;
- goto fatal;
+ } else {
+ filename = expandpath(path);
+ if (filename == NULL) {
+ retval = -1;
+ goto fatal;
+ }
}
data = file_readlines(filename, 0, 0, readerFn);
@@ -96,15 +111,18 @@ int strlist_append_file(struct StrList *pStrList, char *_path, ReaderFn *readerF
retval = 1;
goto fatal;
}
-
for (size_t record = 0; data[record] != NULL; record++) {
strlist_append(&pStrList, data[record]);
guard_free(data[record]);
}
+ if (is_url) {
+ // remove temporary data
+ remove(filename);
+ }
guard_free(data);
fatal:
- if (filename != NULL) {
+ if (!is_url && filename != NULL) {
guard_free(filename);
}
if (path != NULL) {
@@ -115,7 +133,7 @@ fatal:
}
/**
- * Append the contents of a `StrList` to another `StrList`
+ * Append the contents of `pStrList2` to `pStrList1`
* @param pStrList1 `StrList`
* @param pStrList2 `StrList`
*/
@@ -203,13 +221,17 @@ void strlist_remove(struct StrList *pStrList, size_t index) {
for (size_t i = index; i < count; i++) {
char *next = pStrList->data[i + 1];
- pStrList->data[i] = next;
if (next == NULL) {
break;
}
+ pStrList->data[i] = next;
+ count = strlist_count(pStrList);
+ pStrList->data[count - 1] = NULL;
+ }
+ if (pStrList->num_inuse) {
+ guard_free(pStrList->data[pStrList->num_inuse]);
+ pStrList->num_inuse--;
}
-
- pStrList->num_inuse--;
}
/**
@@ -227,13 +249,10 @@ int strlist_cmp(struct StrList *a, struct StrList *b) {
return -2;
}
- if (a->num_alloc != b->num_alloc) {
+ if (a->num_alloc != b->num_alloc || a->num_inuse != b->num_inuse) {
return 1;
}
- if (a->num_inuse != b->num_inuse) {
- return 1;
- }
for (size_t i = 0; i < strlist_count(a); i++) {
if (strcmp(strlist_item(a, i), strlist_item(b, i)) != 0) {
@@ -321,6 +340,29 @@ void strlist_set(struct StrList **pStrList, size_t index, char *value) {
}
}
+const char *strlist_error_msgs[] = {
+ "success",
+ "index out of range",
+ "invalid value for type",
+ "unknown error",
+};
+int strlist_errno = 0;
+
+void strlist_set_error(int flag) {
+ strlist_errno = flag;
+}
+
+const char *strlist_get_error(int flag) {
+ if (flag < STRLIST_E_SUCCESS || flag > STRLIST_E_UNKNOWN) {
+ return strlist_error_msgs[STRLIST_E_UNKNOWN];
+ }
+ return strlist_error_msgs[flag];
+}
+
+void strlist_clear_error() {
+ strlist_errno = STRLIST_E_SUCCESS;
+}
+
/**
* Retrieve data from a `StrList`
* @param pStrList
@@ -351,7 +393,17 @@ char *strlist_item_as_str(struct StrList *pStrList, size_t index) {
* @return `char`
*/
char strlist_item_as_char(struct StrList *pStrList, size_t index) {
- return (char) strtol(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ char result;
+
+ strlist_clear_error();
+ result = (char) strtol(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -361,7 +413,17 @@ char strlist_item_as_char(struct StrList *pStrList, size_t index) {
* @return `unsigned char`
*/
unsigned char strlist_item_as_uchar(struct StrList *pStrList, size_t index) {
- return (unsigned char) strtol(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ unsigned char result;
+
+ strlist_clear_error();
+ result = (unsigned char) strtoul(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -371,7 +433,17 @@ unsigned char strlist_item_as_uchar(struct StrList *pStrList, size_t index) {
* @return `short`
*/
short strlist_item_as_short(struct StrList *pStrList, size_t index) {
- return (short)strtol(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ short result;
+
+ strlist_clear_error();
+ result = (short) strtol(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -381,7 +453,17 @@ short strlist_item_as_short(struct StrList *pStrList, size_t index) {
* @return `unsigned short`
*/
unsigned short strlist_item_as_ushort(struct StrList *pStrList, size_t index) {
- return (unsigned short)strtoul(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ unsigned short result;
+
+ strlist_clear_error();
+ result = (unsigned short) strtoul(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -391,7 +473,17 @@ unsigned short strlist_item_as_ushort(struct StrList *pStrList, size_t index) {
* @return `int`
*/
int strlist_item_as_int(struct StrList *pStrList, size_t index) {
- return (int)strtol(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ int result;
+
+ strlist_clear_error();
+ result = (int) strtol(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -401,7 +493,17 @@ int strlist_item_as_int(struct StrList *pStrList, size_t index) {
* @return `unsigned int`
*/
unsigned int strlist_item_as_uint(struct StrList *pStrList, size_t index) {
- return (unsigned int)strtoul(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ unsigned int result;
+
+ strlist_clear_error();
+ result = (unsigned int) strtoul(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -411,7 +513,17 @@ unsigned int strlist_item_as_uint(struct StrList *pStrList, size_t index) {
* @return `long`
*/
long strlist_item_as_long(struct StrList *pStrList, size_t index) {
- return strtol(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ long result;
+
+ strlist_clear_error();
+ result = (long) strtol(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -421,7 +533,17 @@ long strlist_item_as_long(struct StrList *pStrList, size_t index) {
* @return `unsigned long`
*/
unsigned long strlist_item_as_ulong(struct StrList *pStrList, size_t index) {
- return strtoul(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ unsigned long result;
+
+ strlist_clear_error();
+ result = (unsigned long) strtoul(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -431,7 +553,17 @@ unsigned long strlist_item_as_ulong(struct StrList *pStrList, size_t index) {
* @return `long long`
*/
long long strlist_item_as_long_long(struct StrList *pStrList, size_t index) {
- return strtoll(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ long long result;
+
+ strlist_clear_error();
+ result = (long long) strtoll(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -441,7 +573,17 @@ long long strlist_item_as_long_long(struct StrList *pStrList, size_t index) {
* @return `unsigned long long`
*/
unsigned long long strlist_item_as_ulong_long(struct StrList *pStrList, size_t index) {
- return strtoull(strlist_item(pStrList, index), NULL, 10);
+ char *error_p;
+ unsigned long long result;
+
+ strlist_clear_error();
+ result = (unsigned long long) strtol(strlist_item(pStrList, index), &error_p, 10);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -451,7 +593,17 @@ unsigned long long strlist_item_as_ulong_long(struct StrList *pStrList, size_t i
* @return `float`
*/
float strlist_item_as_float(struct StrList *pStrList, size_t index) {
- return (float)atof(strlist_item(pStrList, index));
+ char *error_p;
+ float result;
+
+ strlist_clear_error();
+ result = (float) strtof(strlist_item(pStrList, index), &error_p);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -461,7 +613,17 @@ float strlist_item_as_float(struct StrList *pStrList, size_t index) {
* @return `double`
*/
double strlist_item_as_double(struct StrList *pStrList, size_t index) {
- return atof(strlist_item(pStrList, index));
+ char *error_p;
+ double result;
+
+ strlist_clear_error();
+ result = (double) strtod(strlist_item(pStrList, index), &error_p);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
@@ -471,7 +633,17 @@ double strlist_item_as_double(struct StrList *pStrList, size_t index) {
* @return `long double`
*/
long double strlist_item_as_long_double(struct StrList *pStrList, size_t index) {
- return (long double)atof(strlist_item(pStrList, index));
+ char *error_p;
+ long double result;
+
+ strlist_clear_error();
+ result = (long double) strtold(strlist_item(pStrList, index), &error_p);
+ if (!result && error_p && *error_p != 0) {
+ strlist_set_error(STRLIST_E_INVALID_VALUE);
+ return 0;
+ }
+ error_p = NULL;
+ return result;
}
/**
diff --git a/src/system.c b/src/system.c
index ca2da97..d5e77ce 100644
--- a/src/system.c
+++ b/src/system.c
@@ -1,11 +1,8 @@
-//
-// Created by jhunk on 10/4/23.
-//
-
#include "system.h"
#include "omc.h"
int shell(struct Process *proc, char *args) {
+ struct Process selfproc;
FILE *fp_out = NULL;
FILE *fp_err = NULL;
pid_t pid;
@@ -13,6 +10,18 @@ int shell(struct Process *proc, char *args) {
status = 0;
errno = 0;
+ if (!proc) {
+ // provide our own proc structure
+ // albeit not accessible to the user
+ memset(&selfproc, 0, sizeof(selfproc));
+ proc = &selfproc;
+ }
+
+ if (!args) {
+ proc->returncode = -1;
+ return -1;
+ }
+
FILE *tp = NULL;
char *t_name;
t_name = xmkstemp(&tp, "w");
@@ -31,22 +40,20 @@ int shell(struct Process *proc, char *args) {
exit(1);
} else if (pid == 0) {
int retval;
- if (proc != NULL) {
- if (strlen(proc->f_stdout)) {
- fp_out = freopen(proc->f_stdout, "w+", stdout);
- }
+ if (strlen(proc->f_stdout)) {
+ fp_out = freopen(proc->f_stdout, "w+", stdout);
+ }
- if (strlen(proc->f_stderr)) {
- fp_err = freopen(proc->f_stderr, "w+", stderr);
- }
+ if (strlen(proc->f_stderr)) {
+ fp_err = freopen(proc->f_stderr, "w+", stderr);
+ }
- if (proc->redirect_stderr) {
- if (fp_err) {
- fclose(fp_err);
- fclose(stderr);
- }
- dup2(fileno(stdout), fileno(stderr));
+ if (proc->redirect_stderr) {
+ if (fp_err) {
+ fclose(fp_err);
+ fclose(stderr);
}
+ dup2(fileno(stdout), fileno(stderr));
}
retval = execl("/bin/bash", "bash", "-c", t_name, (char *) NULL);
@@ -54,7 +61,7 @@ int shell(struct Process *proc, char *args) {
remove(t_name);
}
- if (proc != NULL && strlen(proc->f_stdout)) {
+ if (strlen(proc->f_stdout)) {
if (fp_out != NULL) {
fflush(fp_out);
fclose(fp_out);
@@ -62,7 +69,7 @@ int shell(struct Process *proc, char *args) {
fflush(stdout);
fclose(stdout);
}
- if (proc != NULL && strlen(proc->f_stderr)) {
+ if (strlen(proc->f_stderr)) {
if (fp_err) {
fflush(fp_err);
fclose(fp_err);
@@ -89,10 +96,7 @@ int shell(struct Process *proc, char *args) {
remove(t_name);
}
- if (proc != NULL) {
- proc->returncode = status;
- }
-
+ proc->returncode = status;
guard_free(t_name);
return WEXITSTATUS(status);
}
@@ -102,7 +106,7 @@ int shell_safe(struct Process *proc, char *args) {
char buf[1024] = {0};
int result;
- char *invalid_ch = strpbrk(args, ";&|()");
+ char *invalid_ch = strpbrk(args, OMC_SHELL_SAFE_RESTRICT);
if (invalid_ch) {
args = NULL;
}
@@ -168,6 +172,6 @@ char *shell_output(const char *command, int *status) {
strcat(result, line);
memset(line, 0, sizeof(line));
}
- pclose(pp);
+ *status = pclose(pp);
return result;
} \ No newline at end of file
diff --git a/src/template.c b/src/template.c
index 6101338..0a57232 100644
--- a/src/template.c
+++ b/src/template.c
@@ -16,9 +16,14 @@ struct tpl_item {
};
struct tpl_item *tpl_pool[1024] = {0};
unsigned tpl_pool_used = 0;
+struct tplfunc_frame *tpl_pool_func[1024] = {0};
unsigned tpl_pool_func_used = 0;
-struct tplfunc_frame *tpl_pool_func[1024] = {0};
+extern void tpl_reset() {
+ tpl_free();
+ tpl_pool_used = 0;
+ tpl_pool_func_used = 0;
+}
void tpl_register_func(char *key, struct tplfunc_frame *frame) {
(void) key; // TODO: placeholder
@@ -86,6 +91,10 @@ void tpl_free() {
}
guard_free(item);
}
+ for (unsigned i = 0; i < tpl_pool_func_used; i++) {
+ struct tplfunc_frame *item = tpl_pool_func[i];
+ guard_free(item);
+ }
}
char *tpl_getval(char *key) {
@@ -167,7 +176,9 @@ char *tpl_render(char *str) {
size_t key_len = 0;
while (isalnum(pos[off]) || pos[off] != '}') {
if (isspace(pos[off]) || isblank(pos[off])) {
- break;
+ // skip whitespace in key
+ off++;
+ continue;
}
key[key_len] = pos[off];
key_len++;
@@ -205,7 +216,44 @@ char *tpl_render(char *str) {
char *env_val = getenv(key);
value = strdup(env_val ? env_val : "");
} else if (do_func) { // {{ func:NAME(a, ...) }}
- // TODO
+ char func_name_temp[OMC_NAME_MAX] = {0};
+ strcpy(func_name_temp, type_stop + 1);
+ char *param_begin = strchr(func_name_temp, '(');
+ if (!param_begin) {
+ fprintf(stderr, "offset %zu: function name must be followed by a '('\n", off);
+ guard_free(output);
+ return NULL;
+ }
+ *param_begin = 0;
+ param_begin++;
+ char *param_end = strrchr(param_begin, ')');
+ if (!param_end) {
+ fprintf(stderr, "offset %zu: function arguments must be closed with a ')'\n", off);
+ guard_free(output);
+ return NULL;
+ }
+ *param_end = 0;
+ char *k = func_name_temp;
+ char **params = split(param_begin, ",", 0);
+ int params_count;
+ for (params_count = 0; params[params_count] != NULL; params_count++);
+
+ struct tplfunc_frame *frame = tpl_getfunc(k);
+ if (params_count > frame->argc) {
+ fprintf(stderr, "offset %zu: Too many arguments for function: %s()\n", off, frame->key);
+ value = strdup("");
+ } else {
+ for (size_t p = 0; p < sizeof(frame->argv) / sizeof(*frame->argv) && params[p] != NULL; p++) {
+ lstrip(params[p]);
+ strip(params[p]);
+ frame->argv[p].t_char_ptr = params[p];
+ }
+ char func_result[100];
+ char *fres = func_result;
+ frame->func(frame, fres);
+ value = strdup(fres);
+ }
+ GENERIC_ARRAY_FREE(params);
} else {
// Read replacement value
value = strdup(tpl_getval(key) ? tpl_getval(key) : "");
diff --git a/src/utils.c b/src/utils.c
index 7cc3e6e..7b77020 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -6,9 +6,15 @@ const ssize_t dirstack_max = sizeof(dirstack) / sizeof(dirstack[0]);
ssize_t dirstack_len = 0;
int pushd(const char *path) {
+ if (access(path, F_OK)) {
+ // the requested path doesn't exist.
+ return -1;
+ }
if (dirstack_len + 1 > dirstack_max) {
+ // the stack is full
return -1;
}
+
dirstack[dirstack_len] = realpath(".", NULL);
dirstack_len++;
return chdir(path);
@@ -151,7 +157,7 @@ char *path_dirname(char *path) {
if (!pos) {
return ".";
}
- *path = '\0';
+ *pos = '\0';
return path;
}
@@ -702,29 +708,25 @@ char *collapse_whitespace(char **s) {
* @return 0 on success, -1 on error
*/
int redact_sensitive(const char **to_redact, char *src, char *dest, size_t maxlen) {
- char **parts = split(src, " ", 0);
- if (!parts) {
- fprintf(stderr, "Unable to split source string\n");
+ const char *redacted = "***REDACTED***";
+
+ char *tmp = calloc(strlen(redacted) + strlen(src) + 1, sizeof(*tmp));
+ if (!tmp) {
return -1;
}
+ strcpy(tmp, src);
for (size_t i = 0; to_redact[i] != NULL; i++) {
- for (size_t p = 0; parts[p] != NULL; p++) {
- if (strstr(parts[p], to_redact[i])) {
- replace_text(parts[p], to_redact[i], "***REDACTED***", REPLACE_TRUNCATE_AFTER_MATCH);
- }
+ if (strstr(tmp, to_redact[i])) {
+ replace_text(tmp, to_redact[i], redacted, 0);
+ break;
}
}
- char *dest_tmp = join(parts, " ");
- if (!dest_tmp) {
- fprintf(stderr, "Unable to join message array\n");
- return -1;
- }
- strncpy(dest, dest_tmp, maxlen);
+ memset(dest, 0, maxlen);
+ strncpy(dest, tmp, maxlen - 1);
+ guard_free(tmp);
- GENERIC_ARRAY_FREE(parts);
- guard_free(dest_tmp);
return 0;
}