Skip to content

Commit b15cc59

Browse files
committed
#31: Single quotes in the expanded args should be escaped
1 parent 665d5b5 commit b15cc59

File tree

3 files changed

+88
-1
lines changed

3 files changed

+88
-1
lines changed

slurm_drmaa/job.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ slurmdrmaa_job_create(
612612
fsd_free(temp_script);
613613
}
614614
/* add too script */
615-
temp_script = fsd_asprintf("%s '%s'", temp_script_old, arg_expanded);
615+
temp_script = fsd_asprintf("%s '%s'", temp_script_old, repl_str(arg_expanded, "\'", "\'\"\'\"\'"));
616616
fsd_free(temp_script_old);
617617
fsd_free(arg_expanded);
618618
}

slurm_drmaa/util.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <drmaa_utils/exception.h>
2222
#include <slurm_drmaa/util.h>
2323
#include <string.h>
24+
#include <stdlib.h>
25+
#include <stddef.h>
2426

2527
#include <time.h>
2628
#include <drmaa_utils/datetime.h>
@@ -723,3 +725,87 @@ slurmdrmaa_set_cluster(const char * value)
723725

724726
fsd_log_return(( "" ));
725727
}
728+
729+
// https://creativeandcritical.net/str-replace-c
730+
char *repl_str(const char *str, const char *from, const char *to) {
731+
732+
/* Adjust each of the below values to suit your needs. */
733+
734+
/* Increment positions cache size initially by this number. */
735+
size_t cache_sz_inc = 16;
736+
/* Thereafter, each time capacity needs to be increased,
737+
* multiply the increment by this factor. */
738+
const size_t cache_sz_inc_factor = 3;
739+
/* But never increment capacity by more than this number. */
740+
const size_t cache_sz_inc_max = 1048576;
741+
742+
char *pret, *ret = NULL;
743+
const char *pstr2, *pstr = str;
744+
size_t i, count = 0;
745+
#if (__STDC_VERSION__ >= 199901L)
746+
uintptr_t *pos_cache_tmp, *pos_cache = NULL;
747+
#else
748+
ptrdiff_t *pos_cache_tmp, *pos_cache = NULL;
749+
#endif
750+
size_t cache_sz = 0;
751+
size_t cpylen, orglen, retlen, tolen, fromlen = strlen(from);
752+
753+
/* Find all matches and cache their positions. */
754+
while ((pstr2 = strstr(pstr, from)) != NULL) {
755+
count++;
756+
757+
/* Increase the cache size when necessary. */
758+
if (cache_sz < count) {
759+
cache_sz += cache_sz_inc;
760+
pos_cache_tmp = realloc(pos_cache, sizeof(*pos_cache) * cache_sz);
761+
if (pos_cache_tmp == NULL) {
762+
goto end_repl_str;
763+
} else pos_cache = pos_cache_tmp;
764+
cache_sz_inc *= cache_sz_inc_factor;
765+
if (cache_sz_inc > cache_sz_inc_max) {
766+
cache_sz_inc = cache_sz_inc_max;
767+
}
768+
}
769+
770+
pos_cache[count-1] = pstr2 - str;
771+
pstr = pstr2 + fromlen;
772+
}
773+
774+
orglen = pstr - str + strlen(pstr);
775+
776+
/* Allocate memory for the post-replacement string. */
777+
if (count > 0) {
778+
tolen = strlen(to);
779+
retlen = orglen + (tolen - fromlen) * count;
780+
} else retlen = orglen;
781+
ret = malloc(retlen + 1);
782+
if (ret == NULL) {
783+
goto end_repl_str;
784+
}
785+
786+
if (count == 0) {
787+
/* If no matches, then just duplicate the string. */
788+
strcpy(ret, str);
789+
} else {
790+
/* Otherwise, duplicate the string whilst performing
791+
* the replacements using the position cache. */
792+
pret = ret;
793+
memcpy(pret, str, pos_cache[0]);
794+
pret += pos_cache[0];
795+
for (i = 0; i < count; i++) {
796+
memcpy(pret, to, tolen);
797+
pret += tolen;
798+
pstr = str + pos_cache[i] + fromlen;
799+
cpylen = (i == count-1 ? orglen : pos_cache[i+1]) - pos_cache[i] - fromlen;
800+
memcpy(pret, pstr, cpylen);
801+
pret += cpylen;
802+
}
803+
ret[retlen] = '\0';
804+
}
805+
806+
end_repl_str:
807+
/* Free the cache and return the post-replacement string,
808+
* which will be NULL in the event of an error. */
809+
free(pos_cache);
810+
return ret;
811+
}

slurm_drmaa/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ void slurmdrmaa_parse_native(job_desc_msg_t *job_desc, const char * value);
3737
char * slurmdrmaa_set_job_id(job_id_spec_t *job_id_spec);
3838
char * slurmdrmaa_unset_job_id(job_id_spec_t *job_id_spec);
3939
void slurmdrmaa_set_cluster(const char * value);
40+
char * repl_str(const char *str, const char *from, const char *to);
4041

4142
#endif /* __SLURM_DRMAA__UTIL_H */

0 commit comments

Comments
 (0)