commit 3d89457cdeba5041aa6f0c1f8640b91bcbb6ec51 from: Thomas Adam date: Tue Jun 18 11:38:54 2024 UTC code: add wrappers for common failure cases Certain calls to well-known functions sometimes result in similar error handling across the code base. Sometimes there's a need to centralise the failure case. Achieve this for common wrappers to often-used functions. The transformation is achieved via coccinelle, commited with this patch. Note that coccinelle can be told to ignore code blocks with comment delimiters. This transformation applies just to telescope's code, and not any of the bundled depdencies in telescope (libgrapheme). commit - 416a28cd15d653debef9a718562becd08f146d77 commit + 3d89457cdeba5041aa6f0c1f8640b91bcbb6ec51 blob - 7147d48986f40aa0e63204363d6abd0b4eed8238 blob + 53f52a7e82ab528e0782e67d60d2c5fa23e50afe --- Makefile.am +++ Makefile.am @@ -65,7 +65,9 @@ telescope_SOURCES = bufio.c \ utf8.h \ utils.c \ utils.h \ - wrap.c + wrap.c \ + xwrapper.c \ + xwrapper.h telescope_identity_SOURCES = \ certs.c \ @@ -76,11 +78,33 @@ telescope_identity_SOURCES = \ hist.h \ identity.c \ parser.c \ - parser.h + parser.h \ + xwrapper.c \ + xwrapper.h noinst_PROGRAMS = pagebundler pagebundler_SOURCES = pagebundler.c +EXCLUDE_FROM_COCCI= bufio.c \ + certs.c \ + cmd-gen.c \ + emoji-matcher.c \ + ev.c \ + hist.c \ + pages.c \ + parse.c \ + xwrapper.c +EXTS= .c .y + +SPATCH_FILES = $(foreach ext,$(EXTS),$(filter %$(ext), \ + $(filter-out $(EXCLUDE_FROM_COCCI), \ + $(telescope_SOURCES), $(telescope_identity_SOURCES), \ + $(wilcard test/*.c)))) +.PHONY: cocci +cocci: + spatch --sp-file ./contrib/coccinelle/wrap.cocci \ + --in-place $(SPATCH_FILES) + # Override implicit rule since we have to use HOSTCC and not CC. pagebundler$(EXEEXT): pagebundler.c $(HOSTCC) $(HOSTCFLAGS) -o $@ $(srcdir)/pagebundler.c blob - 88f81d8d52882726aa57ecbd2c1d9830f48823c5 blob + 2a6b8e0443963f948448ef1a28bc8db64e6186d4 --- contrib/README.md +++ contrib/README.md @@ -9,3 +9,4 @@ `~/.config/telescope/config` - `xdg-migrate.sh` aids the migration from a monolithic `~/.telescope` directory to a XDG. + - `coccinelle/` contains cocci scripts used for code transformation. blob - /dev/null blob + 21485de092a0e80a152c18cefa57769a3a8c6be8 (mode 644) --- /dev/null +++ contrib/coccinelle/wrap.cocci @@ -0,0 +1,91 @@ +@@ +expression x, y; +statement S; +@@ +-if ((x = strdup(y)) == NULL) +- S ++x = xstrdup(y); + +@@ +expression x, y; +statement S; +@@ +-x = strdup(y); +-if (x == NULL) +- S ++x = xstrdup(y); + +@@ +expression x, y; +@@ +-x = strdup(y); ++x = xstrdup(y); + +@@ +expression x, y, z; +statement S; +@@ +-if ((x = strndup(y, z)) == NULL) +- S ++x = xstrndup(y, z); + +@@ +expression x, y; +statement S; +@@ +-if ((x = malloc(y)) == NULL) +- S ++x = xmalloc(y); + +@@ +expression x, y, z; +statement S; +@@ +-if ((x = calloc(y, z)) == NULL) +- S ++x = xcalloc(y, z); + +@@ +expression x, y, z; +statement S; +@@ +-if ((x = realloc(y, z)) == NULL) +- S ++x = xrealloc(y, z); + +@@ +expression x, y, z; +statement S; +@@ +-x = realloc(y, z); +- S ++x = xrealloc(y, z); + +@@ +expression w, x, y, z; +statement S; +@@ +-if ((x = reallocarray(w, y, z)) == NULL) +- S ++x = xreallocarray(w, y, z); + +@@ +expression w, x, y, z; +@@ +-x = reallocarray(w, y, z); ++x = xreallocarray(w, y, z); + +@@ +expression fmt; +expression list args; +statement S; +@@ +-if (asprintf(fmt, args) == -1) S ++xasprintf(fmt, args); + +@@ +expression x, fmt; +expression list args; +@@ +-x = asprintf(fmt, args); ++xasprintf(fmt, args); blob - 6522d2b5fb0a86b9ed02653d5fa1f959bae735d9 blob + 65a705971ea2f9a254dbf0dcbf208401bd9e2d2d --- control.c +++ control.c @@ -36,6 +36,7 @@ #include "telescope.h" #include "utils.h" #include "ui.h" +#include "xwrapper.h" #define CONTROL_BACKLOG 5 @@ -152,11 +153,7 @@ control_accept(int listenfd, int event, void *bula) return; } - if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) { - message("%s: calloc: %s", __func__, strerror(errno)); - close(connfd); - return; - } + c = xcalloc(1, sizeof(struct ctl_conn)); imsg_init(&c->iev.ibuf, connfd); c->iev.handler = control_dispatch_imsg; blob - b412c417343219fb305754e53997eaf01ec7e8ef blob + f25cda82fef17a6009033c6e81c165d48706e950 --- defaults.c +++ defaults.c @@ -28,6 +28,7 @@ #include "telescope.h" #include "ui.h" #include "utils.h" +#include "xwrapper.h" char *default_protocol = NULL; char *download_path = NULL; @@ -539,9 +540,7 @@ config_init(void) struct line_face *f; size_t i, len; - default_search_engine = strdup("gemini://kennedy.gemi.dev/search"); - if (default_search_engine == NULL) - err(1, "strdup"); + default_search_engine = xstrdup("gemini://kennedy.gemi.dev/search"); len = sizeof(line_faces)/sizeof(line_faces[0]); for (i = 0; i < len; ++i) { @@ -639,10 +638,7 @@ config_setvars(const char *var, char *val) sufx = "/"; free(download_path); - if (asprintf(&download_path, "%s%s%s", prfx, v, sufx) == -1) { - download_path = NULL; - return 0; - } + xasprintf(&download_path, "%s%s%s", prfx, v, sufx); free(val); return 1; blob - d170814554742461eb57783379f97b67f08ea61c blob + 55e409f587dd8e950bd3e92ff391b43de995028d --- downloads.c +++ downloads.c @@ -22,6 +22,7 @@ #include "telescope.h" #include "ui.h" +#include "xwrapper.h" struct downloads downloads = STAILQ_HEAD_INITIALIZER(downloads); @@ -30,11 +31,10 @@ no_downloads(void) { struct line *l; - if ((l = calloc(1, sizeof(*l))) == NULL) - abort(); + l = xcalloc(1, sizeof(*l)); l->type = LINE_DOWNLOAD_INFO; - l->line = strdup("No downloads"); + l->line = xstrdup("No downloads"); TAILQ_INSERT_TAIL(&downloadwin.head, l, lines); } @@ -55,8 +55,7 @@ recompute_downloads(void) } STAILQ_FOREACH(d, &downloads, entries) { - if ((l = calloc(1, sizeof(*l))) == NULL) - abort(); + l = xcalloc(1, sizeof(*l)); fmt_scaled(d->bytes, buf); @@ -64,8 +63,8 @@ recompute_downloads(void) if (d->fd == -1) l->type = LINE_DOWNLOAD_DONE; - l->line = strdup(buf); - l->alt = strdup(d->path); + l->line = xstrdup(buf); + l->alt = xstrdup(d->path); TAILQ_INSERT_TAIL(&downloadwin.head, l, lines); } @@ -85,13 +84,12 @@ enqueue_download(uint32_t id, const char *path, const { struct download *d; - if ((d = calloc(1, sizeof(*d))) == NULL) - abort(); + d = xcalloc(1, sizeof(*d)); d->id = id; d->fd = -1; - d->path = strdup(path); - d->mime_type = strdup(mime_type); + d->path = xstrdup(path); + d->mime_type = xstrdup(mime_type); STAILQ_INSERT_HEAD(&downloads, d, entries); blob - 0a13259a4b223644c7aacff979f4156a200fc534 blob + 0ea7d7de312b026d9dd4c0d4d5e123e001509732 --- fs.c +++ fs.c @@ -98,8 +98,7 @@ send_dir(struct tab *tab, const char *path) */ if (!has_suffix(path, "/")) { - if (asprintf(&s, "%s/", path) == -1) - die(); + xasprintf(&s, "%s/", path); send_hdr(peerid, 30, s); free(s); return; blob - 2d4a687fef96e329ef2414b0400715e5126f2124 blob + a71194801bebd6854ad8374b707c970a667e9e9d --- help.c +++ help.c @@ -25,6 +25,7 @@ #include "keymap.h" #include "telescope.h" #include "ui.h" +#include "xwrapper.h" static void emit_help_item(char *, interactivefn *); static void rec_compute_help(struct kmap *, char *, size_t); @@ -41,11 +42,10 @@ emit_help_item(char *prfx, interactivefn *fn) } assert(cmd != NULL); - if ((l = calloc(1, sizeof(*l))) == NULL) - abort(); + l = xcalloc(1, sizeof(*l)); l->type = LINE_HELP; - l->line = strdup(prfx); + l->line = xstrdup(prfx); l->alt = (char*)cmd->cmd; TAILQ_INSERT_TAIL(&helpwin.head, l, lines); blob - 15ee034088cb08ab0293ff28ce1fe11446b7a79b blob + 5e5b35885d969e33b0debd77d022a57a7b530393 --- keymap.c +++ keymap.c @@ -23,6 +23,7 @@ #include "keymap.h" #include "utils.h" +#include "xwrapper.h" #define CTRL(n) ((n)&0x1F) @@ -178,8 +179,7 @@ again: } } - if ((entry = calloc(1, sizeof(*entry))) == NULL) - return 0; + entry = xcalloc(1, sizeof(*entry)); entry->meta = meta; entry->key = k; blob - 9f549357ab7fcb8bbd7389b7855b688de9d95cfe blob + a44a7799d6e7bd0b97335f28cbc9bb96dfbe8dfe --- mailcap.c +++ mailcap.c @@ -30,6 +30,7 @@ #include "compat.h" #include "mailcap.h" +#include "xwrapper.h" #define DEFAULT_MAILCAP_ENTRY "*/*; xdg-open %s" @@ -93,7 +94,7 @@ str_append(char **buf, size_t *len, char add) if (al > SIZE_MAX - 1 || *len > SIZE_MAX - 1 - al) errx(1, "buffer is too big"); - *buf = realloc(*buf, (*len) + 1 + al); + *buf = xrealloc(*buf, (*len) + 1 + al); memcpy((*buf) + *len, &add, al); (*len) += al; } @@ -222,8 +223,7 @@ str_to_argv(char *str, int *ret_argc, char ***ret_argv return -1; free(sps.buf); - if ((sps.buf = strdup(str)) == NULL) - errx(1, "strdup"); + sps.buf = xstrdup(str); sps.len = strlen(sps.buf); for (;;) { @@ -253,9 +253,8 @@ str_to_argv(char *str, int *ret_argc, char ***ret_argv } /* Add to argv. */ - argv = reallocarray(argv, argc + 1, sizeof *argv); - if ((argv[argc++] = strdup(token)) == NULL) - errx(1, "strdup"); + argv = xreallocarray(argv, argc + 1, sizeof *argv); + argv[argc++] = xstrdup(token); } out: *ret_argv = argv; @@ -307,8 +306,7 @@ mailcap_new(void) { struct mailcap *mc = NULL; - if ((mc = calloc(1, sizeof *mc)) == NULL) - errx(1, "calloc failed"); + mc = xcalloc(1, sizeof *mc); return (mc); } @@ -327,13 +325,11 @@ parse_mailcap_line(char *input) switch (ms) { case MAILCAP_MIME: - if ((mc->mime_type = strdup(line)) == NULL) - errx(1, "strdup"); + mc->mime_type = xstrdup(line); ms++; break; case MAILCAP_CMD: - if ((mc->cmd = strdup(line)) == NULL) - errx(1, "strdup"); + mc->cmd = xstrdup(line); ms++; break; case MAILCAP_FLAGS: @@ -372,14 +368,12 @@ mailcap_expand_cmd(struct mailcap *mc, char *mt, char for (int z = 0; z < argc; z++) { if (strcmp(argv[z], "%s") == 0) { free(argv[z]); - if ((argv[z] = strdup(file)) == NULL) - errx(1, "strdup"); + argv[z] = xstrdup(file); } if (strcmp(argv[z], "%t") == 0) { free(argv[z]); - if ((argv[z] = strdup(mt)) == NULL) - errx(1, "strdup"); + argv[z] = xstrdup(mt); } } argv[argc++] = NULL; @@ -413,8 +407,7 @@ init_mailcap(void) fclose(f); } - if ((copy = strdup(DEFAULT_MAILCAP_ENTRY)) == NULL) - errx(1, "strdup"); + copy = xstrdup(DEFAULT_MAILCAP_ENTRY); /* Our own entry won't error. */ (void)parse_mailcap_line(copy); blob - 0e92a2adae57aa68d26f5f577c6b4cad5694191d blob + d9c0cc7214e6bf5baa918485f9df02e06318a20e --- mcache.c +++ mcache.c @@ -29,6 +29,7 @@ #include "parser.h" #include "telescope.h" #include "utils.h" +#include "xwrapper.h" static struct timeval tv = { 5 * 60, 0 }; static unsigned int timeout; @@ -106,8 +107,7 @@ mcache_tab(struct tab *tab) l = strlen(url); len = sizeof(*e) + l + 1; - if ((e = calloc(1, len)) == NULL) - return -1; + e = xcalloc(1, len); e->ts = time(NULL); e->parser = tab->buffer.parser; e->trust = tab->trust; blob - f830947eb8c2e60bd29e8fc8f7c293b003fc7d30 blob + 4b502acc02fdf47903bcbe1860135bc137a1753a --- minibuffer.c +++ minibuffer.c @@ -38,6 +38,7 @@ #include "ui.h" #include "utf8.h" #include "utils.h" +#include "xwrapper.h" #define nitems(x) (sizeof(x)/sizeof(x[0])) @@ -545,14 +546,12 @@ populate_compl_buffer(complfn *fn, void *data) linedata = NULL; descr = NULL; while ((s = fn(&data, &linedata, &descr)) != NULL) { - if ((l = calloc(1, sizeof(*l))) == NULL) - abort(); + l = xcalloc(1, sizeof(*l)); l->type = LINE_COMPL; l->data = linedata; l->alt = (char*)descr; - if ((l->line = strdup(s)) == NULL) - abort(); + l->line = xstrdup(s); TAILQ_INSERT_TAIL(&b->head, l, lines); blob - 33d2cb68fbca9577634f246cd3b7294d3c36ea86 blob + b4095c8a50f78adc731e74dcccb649ed864cd84b --- net.c +++ net.c @@ -42,6 +42,7 @@ #include "imsgev.h" #include "telescope.h" #include "utils.h" +#include "xwrapper.h" static struct imsgev *iev_ui; @@ -608,8 +609,7 @@ handle_dispatch_imsg(int fd, int event, void *d) r.proto != PROTO_GOPHER) die(); - if ((req = calloc(1, sizeof(*req))) == NULL) - die(); + req = xcalloc(1, sizeof(*req)); req->fd = -1; #if HAVE_ASR_RUN @@ -619,12 +619,9 @@ handle_dispatch_imsg(int fd, int event, void *d) req->id = imsg_get_id(&imsg); TAILQ_INSERT_HEAD(&reqhead, req, reqs); - if ((req->host = strdup(r.host)) == NULL) - die(); - if ((req->port = strdup(r.port)) == NULL) - die(); - if ((req->req = strdup(r.req)) == NULL) - die(); + req->host = xstrdup(r.host); + req->port = xstrdup(r.port); + req->req = xstrdup(r.req); if (load_cert(&imsg, req) == -1) die(); if (bufio_init(&req->bio) == -1) @@ -706,8 +703,7 @@ net_main(void) exit(1); /* Setup pipe and event handler to the main process */ - if ((iev_ui = malloc(sizeof(*iev_ui))) == NULL) - die(); + iev_ui = xmalloc(sizeof(*iev_ui)); imsg_init(&iev_ui->ibuf, 3); iev_ui->handler = handle_dispatch_imsg; iev_ui->events = EV_READ; blob - 74be21dae9822f167e4bd8b6ee67688c1f132f01 blob + bc4375d12afe4eed30c1e7f421e93f0c50da541c --- parse.y +++ parse.y @@ -37,6 +37,7 @@ #include "keymap.h" #include "telescope.h" #include "utils.h" +#include "xwrapper.h" typedef struct { union { @@ -318,8 +319,7 @@ eow: yyerror("number is %s: %s", errstr, buf); return NUMBER; } - if ((str = strdup(buf)) == NULL) - err(1, "%s", __func__); + str = xstrdup(buf); yylval.str = str; return STRING; @@ -453,8 +453,7 @@ attrname(const char *n) int ret, found; char *ap, *dup, *orig; - if ((dup = strdup(n)) == NULL) - err(1, "strdup"); + dup = xstrdup(n); orig = dup; @@ -518,17 +517,14 @@ add_proxy(char *proto, char *proxy) return; } - if ((p = calloc(1, sizeof(*p))) == NULL) - err(1, "calloc"); + p = xcalloc(1, sizeof(*p)); p->match_proto = proto; p->proto = PROTO_GEMINI; - if ((p->host = strdup(iri.iri_host)) == NULL) - err(1, "strdup"); + p->host = xstrdup(iri.iri_host); - if ((p->port = strdup(iri.iri_portstr)) == NULL) - err(1, "strdup"); + p->port = xstrdup(iri.iri_portstr); TAILQ_INSERT_HEAD(&proxies, p, proxies); } blob - 8378bc5ceea7d3569551817640f475a78fe5933a blob + c5a11cdd51c140436f42cccc2251130c80695868 --- parser.c +++ parser.c @@ -22,6 +22,7 @@ #include "hist.h" #include "parser.h" #include "telescope.h" +#include "xwrapper.h" static int parser_foreach_line(struct buffer *, const char *, size_t); @@ -137,8 +138,7 @@ parser_append(struct buffer *b, const char *buf, size_ char *t; newlen = len + b->len; - if ((t = calloc(1, newlen)) == NULL) - return 0; + t = xcalloc(1, newlen); memcpy(t, b->buf, b->len); memcpy(t + b->len, buf, len); free(b->buf); @@ -164,8 +164,7 @@ parser_set_buf(struct buffer *b, const char *buf, size * overlap! */ - if ((tmp = calloc(1, len)) == NULL) - return 0; + tmp = xcalloc(1, len); memcpy(tmp, buf, len); free(b->buf); b->buf = tmp; blob - d4b1532f36d28b1ffe6edab81972ea9a3fbfff2e blob + 8b325522712df1b842aa572e030a9b04e9fad200 --- parser_gemtext.c +++ parser_gemtext.c @@ -32,6 +32,7 @@ #include "parser.h" #include "telescope.h" #include "utf8.h" +#include "xwrapper.h" static int gemtext_parse_line(struct buffer *, const char *, size_t); static int gemtext_free(struct buffer *); @@ -53,8 +54,7 @@ emit_line(struct buffer *b, enum line_type type, char { struct line *l; - if ((l = calloc(1, sizeof(*l))) == NULL) - return 0; + l = xcalloc(1, sizeof(*l)); l->type = type; l->line = line; @@ -110,18 +110,15 @@ parse_link(struct buffer *b, const char *line, size_t while (len > 0 && !isspace((unsigned char)line[0])) line++, len--; - if ((url = strndup(start, line - start)) == NULL) - return 0; + url = xstrndup(start, line - start); while (len > 0 && isspace(line[0])) line++, len--; if (len == 0) { - if ((label = strdup(url)) == NULL) - return 0; + label = xstrdup(url); } else { - if ((label = strndup(line, len)) == NULL) - return 0; + label = xstrndup(line, len); } return emit_line(b, LINE_LINK, label, url); @@ -150,8 +147,7 @@ parse_title(struct buffer *b, const char *line, size_t if (t == LINE_TITLE_1 && *b->title == '\0') strncpy(b->title, line, MIN(sizeof(b->title)-1, len)); - if ((l = strndup(line, len)) == NULL) - return 0; + l = xstrndup(line, len); return emit_line(b, t, l, NULL); } @@ -168,8 +164,7 @@ gemtext_parse_line(struct buffer *b, const char *line, if (len == 0) return emit_line(b, LINE_PRE_CONTENT, NULL, NULL); - if ((l = strndup(line, len)) == NULL) - return 0; + l = xstrndup(line, len); return emit_line(b, LINE_PRE_CONTENT, l, NULL); } @@ -186,8 +181,7 @@ gemtext_parse_line(struct buffer *b, const char *line, line++, len--; if (len == 0) return emit_line(b, LINE_ITEM, NULL, NULL); - if ((l = strndup(line, len)) == NULL) - return 0; + l = xstrndup(line, len); return emit_line(b, LINE_ITEM, l, NULL); case '>': @@ -196,8 +190,7 @@ gemtext_parse_line(struct buffer *b, const char *line, line++, len--; if (len == 0) return emit_line(b, LINE_QUOTE, NULL, NULL); - if ((l = strndup(line, len)) == NULL) - return 0; + l = xstrndup(line, len); return emit_line(b, LINE_QUOTE, l, NULL); case '=': @@ -219,13 +212,11 @@ gemtext_parse_line(struct buffer *b, const char *line, if (len == 0) return emit_line(b, LINE_PRE_START, NULL, NULL); - if ((l = strndup(line, len)) == NULL) - return 0; + l = xstrndup(line, len); return emit_line(b, LINE_PRE_START, l, NULL); } - if ((l = strndup(line, len)) == NULL) - return 0; + l = xstrndup(line, len); return emit_line(b, LINE_TEXT, l, NULL); } blob - bff31442688fddc4f4b74b0f4385ff6b72ae4139 blob + 9e499812343f69722a0ffdabbc7467a06e8512dc --- parser_gophermap.c +++ parser_gophermap.c @@ -24,6 +24,7 @@ #include "parser.h" #include "telescope.h" #include "utils.h" +#include "xwrapper.h" #ifndef LINE_MAX #define LINE_MAX 2048 @@ -94,11 +95,9 @@ emit_line(struct buffer *b, enum line_type type, struc struct line *l; char buf[LINE_MAX]; - if ((l = calloc(1, sizeof(*l))) == NULL) - goto err; + l = xcalloc(1, sizeof(*l)); - if ((l->line = strdup(s->ds)) == NULL) - goto err; + l->line = xstrdup(s->ds); switch (l->type = type) { case LINE_LINK: @@ -107,8 +106,7 @@ emit_line(struct buffer *b, enum line_type type, struc } else if (selector2uri(s, buf, sizeof(buf)) == -1) goto err; - if ((l->alt = strdup(buf)) == NULL) - goto err; + l->alt = xstrdup(buf); break; default: blob - 1cedf3c9f52b03bbb663825a44462ef556f833d8 blob + 29cb6b61ad7bb608665cad2429315d84599c3cf2 --- parser_textpatch.c +++ parser_textpatch.c @@ -26,6 +26,7 @@ #include "parser.h" #include "telescope.h" #include "utils.h" +#include "xwrapper.h" static int tpatch_emit_line(struct buffer *, const char *, size_t); static int tpatch_parse_line(struct buffer *, const char *, size_t); @@ -41,8 +42,7 @@ tpatch_emit_line(struct buffer *b, const char *line, s { struct line *l; - if ((l = calloc(1, sizeof(*l))) == NULL) - return 0; + l = xcalloc(1, sizeof(*l)); if (b->parser_flags & PARSER_IN_PATCH_HDR) l->type = LINE_PATCH_HDR; @@ -50,10 +50,7 @@ tpatch_emit_line(struct buffer *b, const char *line, s l->type = LINE_PATCH; if (linelen != 0) { - if ((l->line = calloc(1, linelen+1)) == NULL) { - free(l); - return 0; - } + l->line = xcalloc(1, linelen + 1); memcpy(l->line, line, linelen); blob - 33645f01424e35748d8eb886bcfc083a71760df4 blob + 6f76ed17e48305e71f7f24617e0371b13030f468 --- parser_textplain.c +++ parser_textplain.c @@ -25,6 +25,7 @@ #include "parser.h" #include "telescope.h" +#include "xwrapper.h" static int textplain_parse_line(struct buffer *, const char *, size_t); @@ -38,16 +39,12 @@ emit_line(struct buffer *b, const char *line, size_t l { struct line *l; - if ((l = calloc(1, sizeof(*l))) == NULL) - return 0; + l = xcalloc(1, sizeof(*l)); l->type = LINE_TEXT; if (len != 0) { - if ((l->line = calloc(1, len+1)) == NULL) { - free(l); - return 0; - } + l->line = xcalloc(1, len + 1); memcpy(l->line, line, len); } blob - bed2d3e5578f38695e8bf6c97905898e363d76b5 blob + b775862464db1d3a1f5682d5436f33f36d8a12c3 --- session.c +++ session.c @@ -36,6 +36,7 @@ #include "session.h" #include "tofu.h" #include "ui.h" +#include "xwrapper.h" struct history history; @@ -68,10 +69,7 @@ new_tab(const char *url, const char *base, struct tab ui_schedule_redraw(); autosave_hook(); - if ((tab = calloc(1, sizeof(*tab))) == NULL) { - ev_break(); - return NULL; - } + tab = xcalloc(1, sizeof(*tab)); if ((tab->hist = hist_new(HIST_LINEAR)) == NULL) { free(tab); @@ -316,8 +314,7 @@ history_push(struct histitem *hi) return; } - if ((uri = strdup(hi->uri)) == NULL) - abort(); + uri = xstrdup(hi->uri); /* don't grow too much; replace the oldest */ if (history.len == HISTORY_CAP) { @@ -376,8 +373,7 @@ history_add(const char *uri) insert = i; } - if ((u = strdup(uri)) == NULL) - return; + u = xstrdup(uri); /* if history is full, replace the oldest one */ if (history.len == HISTORY_CAP) { @@ -464,10 +460,7 @@ load_certs(struct ohash *certs) if ((f = fopen(known_hosts_file, "r")) == NULL) return; - if ((e = calloc(1, sizeof(*e))) == NULL) { - fclose(f); - return; - } + e = xcalloc(1, sizeof(*e)); while ((linelen = getline(&line, &linesize, f)) != -1) { lineno++; blob - 317fa406cdd33452a6af50f2b4406942791fffcb blob + 07fb73cb5c8bef4e70ffe96a09e11a7868948b53 --- telescope.c +++ telescope.c @@ -51,6 +51,7 @@ #include "tofu.h" #include "ui.h" #include "utils.h" +#include "xwrapper.h" static const struct option longopts[] = { {"help", no_argument, NULL, 'h'}, @@ -207,8 +208,7 @@ handle_imsg_check_cert(struct imsg *imsg) abort(); tofu_res = 1; /* trust on first use */ - if ((e = calloc(1, sizeof(*e))) == NULL) - abort(); + e = xcalloc(1, sizeof(*e)); strlcpy(e->domain, host, sizeof(e->domain)); if (*port != '\0' && strcmp(port, "1965")) { strlcat(e->domain, ":", sizeof(e->domain)); @@ -232,8 +232,7 @@ handle_imsg_check_cert(struct imsg *imsg) } else { tab->trust = TS_UNTRUSTED; load_page_from_str(tab, "# Certificate mismatch\n"); - if ((tab->cert = strdup(hash)) == NULL) - die(); + tab->cert = xstrdup(hash); ui_yornp("Certificate mismatch. Proceed?", handle_check_cert_user_choice, tab); } @@ -289,8 +288,7 @@ handle_maybe_save_new_cert(int accept, struct tab *tab if (!accept) goto end; - if ((e = calloc(1, sizeof(*e))) == NULL) - die(); + e = xcalloc(1, sizeof(*e)); strlcpy(e->domain, host, sizeof(e->domain)); if (*port != '\0' && strcmp(port, "1965")) { @@ -349,9 +347,7 @@ handle_request_response(struct tab *tab) load_page_from_str(tab, err_pages[tab->code]); } else if (tab->code < 20) { /* 1x */ free(tab->last_input_url); - tab->last_input_url = strdup(hist_cur(tab->hist)); - if (tab->last_input_url == NULL) - die(); + tab->last_input_url = xstrdup(hist_cur(tab->hist)); load_page_from_str(tab, err_pages[tab->code]); ui_require_input(tab, tab->code == 11, ir_select_gemini); @@ -479,9 +475,8 @@ handle_dispatch_imsg(int fd, int event, void *data) if (imsg_get_ibuf(&imsg, &ibuf) == -1 || ibuf_borrow_str(&ibuf, &str) == -1) die(); - if (asprintf(&page, "# Error loading %s\n\n> %s\n", - hist_cur(tab->hist), str) == -1) - die(); + xasprintf(&page, "# Error loading %s\n\n> %s\n", + hist_cur(tab->hist), str); load_page_from_str(tab, page); free(page); break; @@ -681,9 +676,7 @@ load_gopher_url(struct tab *tab, const char *url) break; case '7': free(tab->last_input_url); - tab->last_input_url = strdup(url); - if (tab->last_input_url == NULL) - die(); + tab->last_input_url = xstrdup(url); ui_require_input(tab, 0, ir_select_gopher); load_page_from_str(tab, err_pages[10]); return; @@ -803,9 +796,8 @@ do_load_url(struct tab *tab, const char *url, const ch tab->trust = TS_UNKNOWN; if (iri_parse(base, url, &tab->iri) == -1) { - if (asprintf(&t, "# error loading %s\n>%s\n", - url, "Can't parse the IRI") == -1) - die(); + xasprintf(&t, "# error loading %s\n>%s\n", url, + "Can't parse the IRI"); hist_set_cur(tab->hist, url); load_page_from_str(tab, t); free(t); @@ -1153,8 +1145,7 @@ main(int argc, char * const *argv) if (argc != 0) { char *base; - if (asprintf(&base, "file://%s/", cwd) == -1) - err(1, "asprintf"); + xasprintf(&base, "file://%s/", cwd); has_url = 1; humanify_url(argv[0], base, url, sizeof(url)); blob - 1932608bb4c189d223d4c5c234139c1ef7753214 blob + b152463261527e4d480f4ec81277b9fa66ca1c53 --- test/Makefile.am +++ test/Makefile.am @@ -8,7 +8,9 @@ gmparser_SOURCES = gmparser.c \ $(top_srcdir)/iri.h \ $(top_srcdir)/parser.c \ $(top_srcdir)/parser.h \ - $(top_srcdir)/parser_gophermap.c + $(top_srcdir)/parser_gophermap.c \ + $(top_srcdir)/xwrapper.c \ + $(top_srcdir)/xwrapper.h gmiparser_SOURCES = gmiparser.c \ $(top_srcdir)/compat.h \ @@ -16,7 +18,9 @@ gmiparser_SOURCES = gmiparser.c \ $(top_srcdir)/hist.h \ $(top_srcdir)/parser.c \ $(top_srcdir)/parser.h \ - $(top_srcdir)/parser_gemtext.c + $(top_srcdir)/parser_gemtext.c \ + $(top_srcdir)/xwrapper.c \ + $(top_srcdir)/xwrapper.h iritest_SOURCES = iritest.c \ $(top_srcdir)/iri.c \ @@ -24,13 +28,17 @@ iritest_SOURCES = iritest.c \ evtest_SOURCES = evtest.c \ $(top_srcdir)/ev.c \ - $(top_srcdir)/ev.h + $(top_srcdir)/ev.h \ + $(top_srcdir)/xwrapper.c \ + $(top_srcdir)/xwrapper.h mailcap_SOURCES = $(top_srcdir)/test/mailcap.c \ $(top_srcdir)/mailcap.c \ - $(top_srcdir)/mailcap.h + $(top_srcdir)/mailcap.h \ + $(top_srcdir)/xwrapper.c \ + $(top_srcdir)/xwrapper.h -AM_CFLAGS = -I$(top_srcdir) +AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat LDADD = $(LIBOBJS) blob - ad8310d2c5dcc0005a0e4a875299a7f07bc15d1a blob + b71e434660f40cedf450a966815e949f53fb72f7 --- tofu.c +++ tofu.c @@ -25,6 +25,7 @@ #include "fs.h" #include "tofu.h" #include "utils.h" +#include "xwrapper.h" void tofu_init(struct ohash *h, unsigned int sz, ptrdiff_t ko) @@ -150,8 +151,7 @@ tofu_temp_trust(struct ohash *h, const char *host, con { struct tofu_entry *e; - if ((e = calloc(1, sizeof(*e))) == NULL) - abort(); + e = xcalloc(1, sizeof(*e)); strlcpy(e->domain, host, sizeof(e->domain)); if (*port != '\0' && strcmp(port, "1965")) { blob - 685c24e17b0846399656bb4517e1d93661093793 blob + 1ffdac26c249c206bbc450fd8168e412a92dbbf6 --- utils.c +++ utils.c @@ -22,6 +22,7 @@ #include #include "utils.h" +#include "xwrapper.h" int mark_nonblock_cloexec(int fd) @@ -54,16 +55,14 @@ has_suffix(const char *str, const char *sufx) void * hash_alloc(size_t len, void *d) { - if ((d = malloc(len)) == NULL) - abort(); + d = xmalloc(len); return d; } void * hash_calloc(size_t nmemb, size_t size, void *d) { - if ((d = calloc(nmemb, size)) == NULL) - abort(); + d = xcalloc(nmemb, size); return d; } blob - 2a58e03514ae257ca15008d70eedece728b428c0 blob + 3054f79000e3cbe7f8e905d1994cc436fccd7cf4 --- wrap.c +++ wrap.c @@ -26,6 +26,7 @@ #include "defaults.h" #include "telescope.h" #include "utf8.h" +#include "xwrapper.h" void erase_buffer(struct buffer *buffer) @@ -85,8 +86,7 @@ push_line(struct buffer *buffer, struct line *l, const if (!(l->flags & L_HIDDEN)) buffer->line_max++; - if ((vl = calloc(1, sizeof(*vl))) == NULL) - return 0; + vl = xcalloc(1, sizeof(*vl)); vl->parent = l; if (len != 0) { blob - /dev/null blob + 51a7e30021e353b87011b86e71a3398ba378818f (mode 644) --- /dev/null +++ xwrapper.c @@ -0,0 +1,163 @@ +/* $OpenBSD$ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Versions of malloc and friends that check their results, and never return + * failure (they call errx if they encounter an error). + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "compat.h" + +#include +#include +#include +#include +#include +#include + +#include "xwrapper.h" + +void * +xmalloc(size_t size) +{ + void *ptr; + + if (size == 0) + errx(1, "xmalloc: zero size"); + ptr = malloc(size); + if (ptr == NULL) + errx(1, "xmalloc: allocating %zu bytes: %s", + size, strerror(errno)); + return ptr; +} + +void * +xcalloc(size_t nmemb, size_t size) +{ + void *ptr; + + if (size == 0 || nmemb == 0) + errx(1, "xcalloc: zero size"); + ptr = calloc(nmemb, size); + if (ptr == NULL) + errx(1, "xcalloc: allocating %zu * %zu bytes: %s", + nmemb, size, strerror(errno)); + return ptr; +} + +void * +xrealloc(void *ptr, size_t size) +{ + return xreallocarray(ptr, 1, size); +} + +void * +xreallocarray(void *ptr, size_t nmemb, size_t size) +{ + void *new_ptr; + + if (nmemb == 0 || size == 0) + errx(1, "xreallocarray: zero size"); + new_ptr = reallocarray(ptr, nmemb, size); + if (new_ptr == NULL) + errx(1, "xreallocarray: allocating %zu * %zu bytes: %s", + nmemb, size, strerror(errno)); + return new_ptr; +} + +void * +xrecallocarray(void *ptr, size_t oldnmemb, size_t nmemb, size_t size) +{ + void *new_ptr; + + if (nmemb == 0 || size == 0) + errx(1, "xrecallocarray: zero size"); + new_ptr = recallocarray(ptr, oldnmemb, nmemb, size); + if (new_ptr == NULL) + errx(1, "xrecallocarray: allocating %zu * %zu bytes: %s", + nmemb, size, strerror(errno)); + return new_ptr; +} + +char * +xstrdup(const char *str) +{ + char *cp; + + if ((cp = strdup(str)) == NULL) + errx(1, "xstrdup: %s", strerror(errno)); + return cp; +} + +char * +xstrndup(const char *str, size_t maxlen) +{ + char *cp; + + if ((cp = strndup(str, maxlen)) == NULL) + errx(1, "xstrndup: %s", strerror(errno)); + return cp; +} + +int +xasprintf(char **ret, const char *fmt, ...) +{ + va_list ap; + int i; + + va_start(ap, fmt); + i = xvasprintf(ret, fmt, ap); + va_end(ap); + + return i; +} + +int +xvasprintf(char **ret, const char *fmt, va_list ap) +{ + int i; + + i = vasprintf(ret, fmt, ap); + + if (i == -1) + errx(1, "xasprintf: %s", strerror(errno)); + + return i; +} + +int +xsnprintf(char *str, size_t len, const char *fmt, ...) +{ + va_list ap; + int i; + + va_start(ap, fmt); + i = xvsnprintf(str, len, fmt, ap); + va_end(ap); + + return i; +} + +int +xvsnprintf(char *str, size_t len, const char *fmt, va_list ap) +{ + int i; + + if (len > INT_MAX) + errx(1, "xsnprintf: len > INT_MAX"); + + i = vsnprintf(str, len, fmt, ap); + + if (i < 0 || i >= (int)len) + errx(1, "xsnprintf: overflow"); + + return i; +} blob - /dev/null blob + 49ddac115ac2df9d4e7ea4aaf1443fc0a082f393 (mode 644) --- /dev/null +++ xwrapper.h @@ -0,0 +1,48 @@ +/* $OpenBSD$ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Mon Mar 20 22:09:17 1995 ylo + * + * Versions of malloc and friends that check their results, and never return + * failure (they call fatal if they encounter an error). + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef XWRAPPER_H +#define XWRAPPER_H + +#if !defined(__bounded__) +#define __bounded__(x, y, z) +#endif + +void *xmalloc(size_t); +void *xcalloc(size_t, size_t); +void *xrealloc(void *, size_t); +void *xreallocarray(void *, size_t, size_t); +void *xrecallocarray(void *, size_t, size_t, size_t); +char *xstrdup(const char *); +char *xstrndup(const char *, size_t); +int xasprintf(char **, const char *, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int xvasprintf(char **, const char *, va_list) + __attribute__((__format__ (printf, 2, 0))) + __attribute__((__nonnull__ (2))); +int xsnprintf(char *, size_t, const char *, ...) + __attribute__((__format__ (printf, 3, 4))) + __attribute__((__nonnull__ (3))) + __attribute__((__bounded__ (__string__, 1, 2))); +int xvsnprintf(char *, size_t, const char *, va_list) + __attribute__((__format__ (printf, 3, 0))) + __attribute__((__nonnull__ (3))) + __attribute__((__bounded__ (__string__, 1, 2))); + +#endif /* XWRAPPER_H */