diff options
| author | Michael Forney <mforney@mforney.org> | 2016-05-18 23:34:21 -0700 |
|---|---|---|
| committer | Michael Forney <mforney@mforney.org> | 2016-05-18 23:34:21 -0700 |
| commit | addcd3fe22424b1803bf04b4ddc170192a0a0fc8 (patch) | |
| tree | 559e0ddea363a19afaa401d179fabed85d686d17 /core/sbase/patch | |
| parent | 905528027b4b2e4837ff49070d46fcd297aa9e02 (diff) | |
sbase: Various bug fixes
Diffstat (limited to 'core/sbase/patch')
6 files changed, 346 insertions, 0 deletions
diff --git a/core/sbase/patch/0001-Revert-Fix-showing-directories-when-R-flag-is-set-in.patch b/core/sbase/patch/0001-Revert-Fix-showing-directories-when-R-flag-is-set-in.patch new file mode 100644 index 00000000..07f405b1 --- /dev/null +++ b/core/sbase/patch/0001-Revert-Fix-showing-directories-when-R-flag-is-set-in.patch @@ -0,0 +1,30 @@ +From 9a9c3e05e66f1a1fde22f95d70ff2810a580d49d Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Sat, 14 May 2016 16:31:40 -0700 +Subject: [PATCH] Revert "Fix showing directories when -R flag is set in ls(1)" + +This reverts commit bb83eade399e7d6f3642ae3a5e2cdebab6f222a1. + +This commit causes the loop through dents at the end of main to +continue past the end of the dents array, causing a crash when +called with multiple directory arguments. +--- + ls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ls.c b/ls.c +index 8cc285b..a59cc0a 100644 +--- a/ls.c ++++ b/ls.c +@@ -278,7 +278,7 @@ lsdir(const char *path, const struct entry *dir) + if (!Uflag) + qsort(ents, n, sizeof(*ents), entcmp); + +- if (ds++) ++ if (ds > 1 && (path[0] || dir->name[0] != '.')) + printf("%s:\n", dir->name); + for (i = 0; i < n; i++) + output(&ents[i]); +-- +2.8.1 + diff --git a/core/sbase/patch/0002-Revert-ls-only-display-directory-headers-when-more-t.patch b/core/sbase/patch/0002-Revert-ls-only-display-directory-headers-when-more-t.patch new file mode 100644 index 00000000..2d2427b0 --- /dev/null +++ b/core/sbase/patch/0002-Revert-ls-only-display-directory-headers-when-more-t.patch @@ -0,0 +1,44 @@ +From 6ce4e756d6cf5a4cc5539a57b93fcacbfb7654a6 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Sat, 14 May 2016 16:54:32 -0700 +Subject: [PATCH] Revert "ls: only display directory headers when more than one + directory is specified" + +This reverts commit b107489bf2cda579ca53551206270b9eee80c059. +--- + ls.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/ls.c b/ls.c +index a59cc0a..55dfe40 100644 +--- a/ls.c ++++ b/ls.c +@@ -53,7 +53,6 @@ static int Uflag = 0; + static int uflag = 0; + static int first = 1; + static char sort = 0; +-static size_t ds = 0; + + static void ls(const char *, const struct entry *, int); + +@@ -278,7 +277,7 @@ lsdir(const char *path, const struct entry *dir) + if (!Uflag) + qsort(ents, n, sizeof(*ents), entcmp); + +- if (ds > 1 && (path[0] || dir->name[0] != '.')) ++ if (path[0] || dir->name[0] != '.') + printf("%s:\n", dir->name); + for (i = 0; i < n; i++) + output(&ents[i]); +@@ -369,7 +368,7 @@ int + main(int argc, char *argv[]) + { + struct entry ent, *dents, *fents; +- size_t i, fs; ++ size_t i, ds, fs; + + ARGBEGIN { + case '1': +-- +2.8.1 + diff --git a/core/sbase/patch/0003-ls-Don-t-show-directory-name-with-single-directory-o.patch b/core/sbase/patch/0003-ls-Don-t-show-directory-name-with-single-directory-o.patch new file mode 100644 index 00000000..5bc0b615 --- /dev/null +++ b/core/sbase/patch/0003-ls-Don-t-show-directory-name-with-single-directory-o.patch @@ -0,0 +1,45 @@ +From ec8d61a6fd614ee6742cd46bf7ffc6b67391c766 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Sat, 14 May 2016 18:13:22 -0700 +Subject: [PATCH] ls: Don't show directory name with single directory operand + +This fixes the issue b107489bf2cda579ca53551206270b9eee80c059 tried +to fix, but doesn't break -R (which +bb83eade399e7d6f3642ae3a5e2cdebab6f222a1 tried to fix). +--- + ls.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/ls.c b/ls.c +index 55dfe40..42811c5 100644 +--- a/ls.c ++++ b/ls.c +@@ -53,6 +53,7 @@ static int Uflag = 0; + static int uflag = 0; + static int first = 1; + static char sort = 0; ++static int showdirs; + + static void ls(const char *, const struct entry *, int); + +@@ -277,7 +278,7 @@ lsdir(const char *path, const struct entry *dir) + if (!Uflag) + qsort(ents, n, sizeof(*ents), entcmp); + +- if (path[0] || dir->name[0] != '.') ++ if (path[0] || showdirs) + printf("%s:\n", dir->name); + for (i = 0; i < n; i++) + output(&ents[i]); +@@ -469,6 +470,8 @@ main(int argc, char *argv[]) + } + } + ++ showdirs = ds > 1 || (ds && fs); ++ + qsort(fents, fs, sizeof(ent), entcmp); + qsort(dents, ds, sizeof(ent), entcmp); + +-- +2.8.1 + diff --git a/core/sbase/patch/0004-ls-Simplify-some-logic.patch b/core/sbase/patch/0004-ls-Simplify-some-logic.patch new file mode 100644 index 00000000..0ad6a1af --- /dev/null +++ b/core/sbase/patch/0004-ls-Simplify-some-logic.patch @@ -0,0 +1,74 @@ +From 19d79dc27a724fd9553e8a99511854fb1dbc3c58 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Sat, 14 May 2016 18:25:11 -0700 +Subject: [PATCH] ls: Simplify some logic + +- After first iteration, set first to 0 instead of !first. +- If Hflag || Lflag, then mkent used stat instead of lstat, so the + entity cannot be a symlink. +- Print path prefix along with directory name. +- In the 'if (Rflag)' block, just use 1 instead of Rflag. +--- + ls.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/ls.c b/ls.c +index 42811c5..b5c4b00 100644 +--- a/ls.c ++++ b/ls.c +@@ -279,7 +279,7 @@ lsdir(const char *path, const struct entry *dir) + qsort(ents, n, sizeof(*ents), entcmp); + + if (path[0] || showdirs) +- printf("%s:\n", dir->name); ++ printf("%s%s:\n", path, dir->name); + for (i = 0; i < n; i++) + output(&ents[i]); + +@@ -296,7 +296,7 @@ lsdir(const char *path, const struct entry *dir) + if (S_ISLNK(ent->mode) && S_ISDIR(ent->tmode) && !Lflag) + continue; + +- ls(prefix, ent, Rflag); ++ ls(prefix, ent, 1); + } + } + +@@ -346,11 +346,10 @@ ls(const char *path, const struct entry *ent, int listdir) + eprintf("getcwd:"); + + if (first) +- first = !first; ++ first = 0; + else + putchar('\n'); + +- fputs(path, stdout); + lsdir(path, ent); + tree[treeind].ino = 0; + +@@ -451,8 +450,8 @@ main(int argc, char *argv[]) + case 1: + mkent(&ent, argv[0], 1, Hflag || Lflag); + ls("", &ent, (!dflag && S_ISDIR(ent.mode)) || +- ((S_ISLNK(ent.mode) && S_ISDIR(ent.tmode)) && +- ((Hflag || Lflag) || !(dflag || Fflag || lflag)))); ++ (S_ISLNK(ent.mode) && S_ISDIR(ent.tmode) && ++ !(dflag || Fflag || lflag))); + + break; + default: +@@ -460,8 +459,8 @@ main(int argc, char *argv[]) + mkent(&ent, argv[i], 1, Hflag || Lflag); + + if ((!dflag && S_ISDIR(ent.mode)) || +- ((S_ISLNK(ent.mode) && S_ISDIR(ent.tmode)) && +- ((Hflag || Lflag) || !(dflag || Fflag || lflag)))) { ++ (S_ISLNK(ent.mode) && S_ISDIR(ent.tmode) && ++ !(dflag || Fflag || lflag))) { + dents = ereallocarray(dents, ++ds, sizeof(*dents)); + memcpy(&dents[ds - 1], &ent, sizeof(ent)); + } else { +-- +2.8.1 + diff --git a/core/sbase/patch/0005-sort-Fix-line-comparison-when-col-buffer-contains-da.patch b/core/sbase/patch/0005-sort-Fix-line-comparison-when-col-buffer-contains-da.patch new file mode 100644 index 00000000..dce7e9b9 --- /dev/null +++ b/core/sbase/patch/0005-sort-Fix-line-comparison-when-col-buffer-contains-da.patch @@ -0,0 +1,112 @@ +From da15434afe0c4b133961328cfff3a230741d7150 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Sat, 14 May 2016 15:16:16 -0700 +Subject: [PATCH] sort: Fix line comparison when col buffer contains data from + longer line + +I'm not sure if there are other implications of this or not, but +the issue is that columns() uses len to store the allocated buffer +size, but linecmp() compares up to len bytes. If those trailing +bytes do not match, the line is considered not matching, even though +the relevant parts of the buffer do match. + +To resolve this, also keep track of column capacity. Additionally, +since there is no reason to keep the existing data when resizing, +just use free and emalloc rather than erealloc. + +The simplest case I could reduce it to is this: + +if [ "$(printf '%s\n' a a xxb xxc | ./sort -u)" = "$(printf '%s\n' a xxb xxc)" ] ; then + echo pass +else + echo fail +fi +--- + sort.c | 37 ++++++++++++++++++++----------------- + 1 file changed, 20 insertions(+), 17 deletions(-) + +diff --git a/sort.c b/sort.c +index 90ee911..623b81e 100644 +--- a/sort.c ++++ b/sort.c +@@ -18,6 +18,11 @@ struct keydef { + TAILQ_ENTRY(keydef) entry; + }; + ++struct column { ++ struct line line; ++ size_t cap; ++}; ++ + enum { + MOD_N = 1 << 0, + MOD_STARTB = 1 << 1, +@@ -33,7 +38,7 @@ static TAILQ_HEAD(kdhead, keydef) kdhead = TAILQ_HEAD_INITIALIZER(kdhead); + static int Cflag = 0, cflag = 0, uflag = 0; + static char *fieldsep = NULL; + static size_t fieldseplen = 0; +-static struct line col1, col2; ++static struct column col1, col2; + + static void + skipblank(struct line *a) +@@ -76,12 +81,12 @@ skipcolumn(struct line *a, int skip_to_next_col) + } + } + +-static size_t +-columns(struct line *line, const struct keydef *kd, struct line *col) ++static void ++columns(struct line *line, const struct keydef *kd, struct column *col) + { + Rune r; + struct line start, end; +- size_t len, utflen, rlen; ++ size_t utflen, rlen; + int i; + + start.data = line->data; +@@ -118,15 +123,13 @@ columns(struct line *line, const struct keydef *kd, struct line *col) + end.data += end.len - 1; + end.len = 1; + } +- len = MAX(0, end.data - start.data); +- if (!(col->data) || col->len < len) +- col->data = erealloc(col->data, len + 1); +- memcpy(col->data, start.data, len); +- col->data[len] = '\0'; +- if (col->len < len) +- col->len = len; +- +- return len; ++ col->line.len = MAX(0, end.data - start.data); ++ if (!(col->line.data) || col->cap < col->line.len + 1) { ++ free(col->line.data); ++ col->line.data = emalloc(col->line.len + 1); ++ } ++ memcpy(col->line.data, start.data, col->line.len); ++ col->line.data[col->line.len] = '\0'; + } + + static int +@@ -187,13 +190,13 @@ slinecmp(struct line *a, struct line *b) + TAILQ_LAST(&kdhead, kdhead) != TAILQ_FIRST(&kdhead)) { + res = 0; + } else if (kd->flags & MOD_N) { +- x = strtold(col1.data, NULL); +- y = strtold(col2.data, NULL); ++ x = strtold(col1.line.data, NULL); ++ y = strtold(col2.line.data, NULL); + res = (x < y) ? -1 : (x > y); + } else if (kd->flags & (MOD_D | MOD_F | MOD_I)) { +- res = skipmodcmp(&col1, &col2, kd->flags); ++ res = skipmodcmp(&col1.line, &col2.line, kd->flags); + } else { +- res = linecmp(&col1, &col2); ++ res = linecmp(&col1.line, &col2.line); + } + + if (kd->flags & MOD_R) +-- +2.8.1 + diff --git a/core/sbase/patch/0006-linecmp-Handle-NUL-bytes-properly.patch b/core/sbase/patch/0006-linecmp-Handle-NUL-bytes-properly.patch new file mode 100644 index 00000000..a2a1f8d2 --- /dev/null +++ b/core/sbase/patch/0006-linecmp-Handle-NUL-bytes-properly.patch @@ -0,0 +1,41 @@ +From 3ad1087dc420ded3cb279fd0c2039b12994328a8 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Sat, 14 May 2016 15:27:31 -0700 +Subject: [PATCH] linecmp: Handle NUL bytes properly + +Test case: + +if [ "$(printf 'a\na\0b' | ./sort -u)" = "$(printf 'a\na\0b')" ] ; then + echo pass +else + echo fail +fi +--- + libutil/linecmp.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/libutil/linecmp.c b/libutil/linecmp.c +index f5a6cf9..08fc0e3 100644 +--- a/libutil/linecmp.c ++++ b/libutil/linecmp.c +@@ -10,15 +10,8 @@ linecmp(struct line *a, struct line *b) + { + int res = 0; + +- if (!(res = memcmp(a->data, b->data, MIN(a->len, b->len)))) { +- if (a->len > b->len) { +- res = a->data[b->len]; +- } else if (b->len > a->len) { +- res = -b->data[a->len]; +- } else { +- res = 0; +- } +- } ++ if (!(res = memcmp(a->data, b->data, MIN(a->len, b->len)))) ++ res = a->len - b->len; + + return res; + } +-- +2.8.1 + |
