diff options
author | Jason King <jason.king@joyent.com> | 2020-01-09 10:59:44 -0600 |
---|---|---|
committer | Jason King <jason.king@joyent.com> | 2020-01-14 09:36:41 -0600 |
commit | 356ce177517a15babb8fd801d490f239298643b7 (patch) | |
tree | 5832178e3712a2bc6981458d9c1e5f13345b04f7 /usr/src | |
parent | 9554f7e18d034b915acbd51b3c4e3261c88e166d (diff) | |
download | illumos-joyent-356ce177517a15babb8fd801d490f239298643b7.tar.gz |
12178 Allow bytes to be removed from a custr
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Approved by: Gordon Ross <gwr@nexenta.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/libcustr/common/custr.c | 77 | ||||
-rw-r--r-- | usr/src/lib/libcustr/common/libcustr.h | 48 | ||||
-rw-r--r-- | usr/src/lib/libcustr/common/mapfile-vers | 6 | ||||
-rw-r--r-- | usr/src/pkg/manifests/system-test-utiltest.mf | 6 | ||||
-rw-r--r-- | usr/src/test/util-tests/runfiles/default.run | 3 | ||||
-rw-r--r-- | usr/src/test/util-tests/tests/Makefile | 3 | ||||
-rw-r--r-- | usr/src/test/util-tests/tests/libcustr/Makefile | 50 | ||||
-rw-r--r-- | usr/src/test/util-tests/tests/libcustr/custr_remove.c | 73 | ||||
-rw-r--r-- | usr/src/test/util-tests/tests/libcustr/custr_trunc.c | 64 |
9 files changed, 324 insertions, 6 deletions
diff --git a/usr/src/lib/libcustr/common/custr.c b/usr/src/lib/libcustr/common/custr.c index 8c8288ab7d..3ff67cac71 100644 --- a/usr/src/lib/libcustr/common/custr.c +++ b/usr/src/lib/libcustr/common/custr.c @@ -14,7 +14,7 @@ */ /* - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ #include <stdlib.h> @@ -85,6 +85,81 @@ custr_reset(custr_t *cus) cus->cus_data[0] = '\0'; } +int +custr_remove(custr_t *cus, size_t idx, size_t len) +{ + size_t endidx = idx + len; + + /* + * Once gcc4 is dropped as a shadow compiler, we can migrate to + * using builtins for the overflow check. + */ + if (endidx < idx || endidx < len) { + errno = EINVAL; + return (-1); + } + + if (idx >= cus->cus_strlen || endidx > cus->cus_strlen) { + errno = EINVAL; + return (-1); + } + + if (len == 0) + return (0); + + /* The +1 will include the terminating NUL in the move */ + (void) memmove(cus->cus_data + idx, cus->cus_data + endidx, + cus->cus_strlen - endidx + 1); + cus->cus_strlen -= len; + + /* The result should be NUL */ + VERIFY0(cus->cus_data[cus->cus_strlen]); + return (0); +} + +int +custr_rremove(custr_t *cus, size_t ridx, size_t len) +{ + size_t idx; + + if (ridx >= cus->cus_strlen) { + errno = EINVAL; + return (-1); + } + + idx = cus->cus_strlen - ridx - 1; + return (custr_remove(cus, idx, len)); +} + +int +custr_trunc(custr_t *cus, size_t idx) +{ + if (idx >= cus->cus_strlen) { + errno = EINVAL; + return (-1); + } + + cus->cus_data[idx] = '\0'; + cus->cus_strlen = idx; + return (0); +} + +int +custr_rtrunc(custr_t *cus, size_t ridx) +{ + size_t idx; + + if (ridx >= cus->cus_strlen) { + errno = EINVAL; + return (-1); + } + + idx = cus->cus_strlen - ridx - 1; + cus->cus_data[idx] = '\0'; + cus->cus_strlen = idx; + return (0); +} + size_t custr_len(custr_t *cus) { diff --git a/usr/src/lib/libcustr/common/libcustr.h b/usr/src/lib/libcustr/common/libcustr.h index 8fe5fee1b7..f8f15db07b 100644 --- a/usr/src/lib/libcustr/common/libcustr.h +++ b/usr/src/lib/libcustr/common/libcustr.h @@ -10,7 +10,7 @@ */ /* - * Copyright 2019, Joyent, Inc. + * Copyright 2019 Joyent, Inc. */ #ifndef _LIBCUSTR_H @@ -142,6 +142,52 @@ size_t custr_len(custr_t *); void custr_reset(custr_t *); /* + * custr_remove(cus, idx, len) + * + * Remove len bytes from cus, starting at idx. + * + * Returns 0 on success or -1 on failure. On failure, errno will be set to: + * EINVAL Either the idx or len parameter is invalid + * + */ +int custr_remove(custr_t *, size_t, size_t); + +/* + * custr_rremove(cus, idx, len) + * + * Remove len bytes from cus, starting at idx relative to the end of cus. + * That is, 0 = last byte of cus, 1 = second to last byte of cus, ...). + * The direction of removal is always towards the end of the string. I.e. + * 'custr_rremove(cus, 1, 2)' removes the last two bytes of cus. + * + * Returns 0 on success or -1 on failure. On failure, errno will be set to: + * EINVAL Either the idx or len parameter is invalid + * + */ +int custr_rremove(custr_t *, size_t, size_t); + +/* + * custr_trunc(cus, idx) + * + * Truncate cus starting at idx. + * + * Returns 0 on success or -1 on failure. On failure, errno is set to: + * EINVAL The idx value was invalid. + */ +int custr_trunc(custr_t *, size_t); + +/* + * custr_rtrunc(cus, idx) + * + * Truncate cus starting at idx relative to the end of cus (similar to how + * the idx paramter is treated with custr_rremove()). + * + * Returns 0 on success or -1 on failure. On failure, errno is set to: + * EINVAL The idx value was invalid. + */ +int custr_rtrunc(custr_t *, size_t); + +/* * Retrieve a const pointer to a NUL-terminated string version of the contents * of the dynamic string. Storage for this string should not be freed, and * the pointer will be invalidated by any mutations to the dynamic string. diff --git a/usr/src/lib/libcustr/common/mapfile-vers b/usr/src/lib/libcustr/common/mapfile-vers index f94636b6f5..53b94164ad 100644 --- a/usr/src/lib/libcustr/common/mapfile-vers +++ b/usr/src/lib/libcustr/common/mapfile-vers @@ -10,7 +10,7 @@ # # -# Copyright 2019, Joyent, Inc. +# Copyright 2019 Joyent, Inc. # # @@ -42,7 +42,11 @@ SYMBOL_VERSION ILLUMOSprivate { custr_cstr; custr_free; custr_len; + custr_remove; custr_reset; + custr_rremove; + custr_rtrunc; + custr_trunc; custr_xalloc; custr_xalloc_buf; local: diff --git a/usr/src/pkg/manifests/system-test-utiltest.mf b/usr/src/pkg/manifests/system-test-utiltest.mf index cd3f4f89a0..7ebc02a0b1 100644 --- a/usr/src/pkg/manifests/system-test-utiltest.mf +++ b/usr/src/pkg/manifests/system-test-utiltest.mf @@ -13,9 +13,8 @@ # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2014 Nexenta Systems, Inc. All rights reserved. -# Copyright 2019, Joyent, Inc. +# Copyright 2020 Joyent, Inc. # Copyright 2017 Jason King. -# Copyright 2018, Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # @@ -56,6 +55,7 @@ dir path=opt/util-tests/tests/files/make_a/a dir path=opt/util-tests/tests/files/make_a/b dir path=opt/util-tests/tests/files/make_a/c dir path=opt/util-tests/tests/files/make_l +dir path=opt/util-tests/tests/libcustr dir path=opt/util-tests/tests/libnvpair_json dir path=opt/util-tests/tests/libsff dir path=opt/util-tests/tests/mergeq @@ -1423,6 +1423,8 @@ file path=opt/util-tests/tests/files/test7 mode=0444 file path=opt/util-tests/tests/files/testnl mode=0444 file path=opt/util-tests/tests/grep_test mode=0555 file path=opt/util-tests/tests/iconv_test mode=0555 +file path=opt/util-tests/tests/libcustr/custr_remove mode=0555 +file path=opt/util-tests/tests/libcustr/custr_trunc mode=0555 file path=opt/util-tests/tests/libjedec_test mode=0555 file path=opt/util-tests/tests/libnvpair_json/json_00_blank mode=0555 file path=opt/util-tests/tests/libnvpair_json/json_01_boolean mode=0555 diff --git a/usr/src/test/util-tests/runfiles/default.run b/usr/src/test/util-tests/runfiles/default.run index cac238c045..04f59f9ab4 100644 --- a/usr/src/test/util-tests/runfiles/default.run +++ b/usr/src/test/util-tests/runfiles/default.run @@ -70,3 +70,6 @@ tests = ['afl-fast', 'gcc-libstdc++', 'llvm-stdcxxabi'] [/opt/util-tests/tests/ctf] pre = precheck tests = [ 'ctftest' ] + +[/opt/util-tests/tests/libcustr] +tests = ['custr_remove', 'custr_trunc'] diff --git a/usr/src/test/util-tests/tests/Makefile b/usr/src/test/util-tests/tests/Makefile index 53200f2fa0..35fd953518 100644 --- a/usr/src/test/util-tests/tests/Makefile +++ b/usr/src/test/util-tests/tests/Makefile @@ -14,11 +14,12 @@ # Copyright 2014 Garrett D'Amore <garrett@damore.org> # Copyright 2014 Nexenta Systems, Inc. All rights reserved. # Copyright 2017 Jason King -# Copyright 2019 Joyent, Inc. +# Copyright 2020 Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # SUBDIRS = date dis dladm iconv libnvpair_json libsff printf xargs grep_xpg4 SUBDIRS += demangle mergeq workq chown ctf smbios libjedec awk make sleep +SUBDIRS += libcustr include $(SRC)/test/Makefile.com diff --git a/usr/src/test/util-tests/tests/libcustr/Makefile b/usr/src/test/util-tests/tests/libcustr/Makefile new file mode 100644 index 0000000000..3aa4c5c76a --- /dev/null +++ b/usr/src/test/util-tests/tests/libcustr/Makefile @@ -0,0 +1,50 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2019 Joyent, Inc. +# + +include $(SRC)/Makefile.master + +ROOTOPTPKG = $(ROOT)/opt/util-tests +TESTDIR = $(ROOTOPTPKG)/tests/libcustr + +PROGS = custr_remove custr_trunc + +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com + +CMDS = $(PROGS:%=$(TESTDIR)/%) +$(CMDS) := FILEMODE = 0555 + +LDLIBS += -lcustr + +all: $(PROGS) + +install: all $(CMDS) $(OUTFILES) + +clobber: clean + -$(RM) $(PROGS) + +clean: + +$(CMDS): $(TESTDIR) $(PROG) + +$(TESTDIR): + $(INS.dir) + +$(TESTDIR)/%: % + $(INS.file) + +%: %.c + $(LINK.c) -o $@ $< $(LDLIBS) + $(POST_PROCESS) diff --git a/usr/src/test/util-tests/tests/libcustr/custr_remove.c b/usr/src/test/util-tests/tests/libcustr/custr_remove.c new file mode 100644 index 0000000000..c542ccaef4 --- /dev/null +++ b/usr/src/test/util-tests/tests/libcustr/custr_remove.c @@ -0,0 +1,73 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +#include <errno.h> +#include <libcustr.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> +#include <sys/debug.h> + +static void +expect(const char *var, custr_t *cu, const char *str, const char *file, + size_t line) +{ + if (strcmp(custr_cstr(cu), str) == 0) + return; + + char msgbuf[256]; + + (void) snprintf(msgbuf, sizeof (msgbuf), "%s == '%s' ('%s' == '%s')", + var, str, custr_cstr(cu), str); + + (void) assfail(msgbuf, file, line); +} + +#define EXPECT(_cu, _str) expect(#_cu, _cu, _str, __FILE__, __LINE__) +#define FAIL(_expr, _ev) \ + VERIFY3S(_expr, ==, -1); \ + VERIFY3S(errno, ==, (_ev)) + +int +main(void) +{ + custr_t *cu; + + VERIFY0(custr_alloc(&cu)); + + VERIFY0(custr_append(cu, "12345")); + EXPECT(cu, "12345"); + + FAIL(custr_remove(cu, 6, 2), EINVAL); + FAIL(custr_remove(cu, 2, 10), EINVAL); + FAIL(custr_rremove(cu, 6, 2), EINVAL); + FAIL(custr_rremove(cu, 2, 10), EINVAL); + + VERIFY0(custr_remove(cu, 0, 1)); + EXPECT(cu, "2345"); + VERIFY0(custr_rremove(cu, 1, 2)); + EXPECT(cu, "23"); + + VERIFY0(custr_append(cu, "456")); + EXPECT(cu, "23456"); + + VERIFY0(custr_remove(cu, 1, 2)); + EXPECT(cu, "256"); + + VERIFY0(custr_rremove(cu, 1, 2)); + EXPECT(cu, "2"); + + return (0); +} diff --git a/usr/src/test/util-tests/tests/libcustr/custr_trunc.c b/usr/src/test/util-tests/tests/libcustr/custr_trunc.c new file mode 100644 index 0000000000..6cd3ca4832 --- /dev/null +++ b/usr/src/test/util-tests/tests/libcustr/custr_trunc.c @@ -0,0 +1,64 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +#include <errno.h> +#include <libcustr.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/debug.h> + +static void +expect(const char *var, custr_t *cu, const char *str, const char *file, + size_t line) +{ + if (strcmp(custr_cstr(cu), str) == 0) + return; + + char msgbuf[256]; + + (void) snprintf(msgbuf, sizeof (msgbuf), "%s == '%s' ('%s' == '%s')", + var, str, custr_cstr(cu), str); + + (void) assfail(msgbuf, file, line); +} + +#define EXPECT(_cu, _str) expect(#_cu, _cu, _str, __FILE__, __LINE__) +#define FAIL(_expr, _ev) \ + VERIFY3S(_expr, ==, -1); \ + VERIFY3S(errno, ==, (_ev)) + +int +main(void) +{ + custr_t *cu; + + VERIFY0(custr_alloc(&cu)); + + VERIFY0(custr_append(cu, "12345")); + EXPECT(cu, "12345"); + + FAIL(custr_trunc(cu, 6), EINVAL); + FAIL(custr_rtrunc(cu, 10), EINVAL); + + VERIFY0(custr_trunc(cu, 3)); + EXPECT(cu, "123"); + + VERIFY0(custr_rtrunc(cu, 1)); + EXPECT(cu, "1"); + + return (0); +} |