aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2016-12-28 17:13:03 +0000
committerMarius Strobl <marius@FreeBSD.org>2016-12-28 17:13:03 +0000
commited7aec1e4566c0084f2c8009e91336994530113a (patch)
tree29bbde1b778e3e37d448e69628b2fb9f82830943 /usr.bin
parent53c167f98f7236ee3d353bd9c91877ad166753da (diff)
downloadsrc-ed7aec1e4566c0084f2c8009e91336994530113a.tar.gz
src-ed7aec1e4566c0084f2c8009e91336994530113a.zip
- Use correct offsets into the keys set array. As the elements of this
zero-length array are dynamically sized at run-time based on the use of hints, compilers can't be expected to figure out these offsets on their own. [1] - Fix incorrect comparison in cmp_nans(). [2] PR: 204571 [1], 202301 [2] Submitted by: David Binderman [2] MFC after: 3 days
Notes
Notes: svn path=/head/; revision=310712
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/sort/coll.c36
-rw-r--r--usr.bin/sort/coll.h3
-rw-r--r--usr.bin/sort/radixsort.c4
3 files changed, 32 insertions, 11 deletions
diff --git a/usr.bin/sort/coll.c b/usr.bin/sort/coll.c
index 7b4ad1067810..6372f3d8aa7a 100644
--- a/usr.bin/sort/coll.c
+++ b/usr.bin/sort/coll.c
@@ -105,14 +105,29 @@ clean_keys_array(const struct bwstring *s, struct keys_array *ka)
{
if (ka) {
- for (size_t i = 0; i < keys_num; ++i)
- if (ka->key[i].k && ka->key[i].k != s)
- bwsfree(ka->key[i].k);
+ for (size_t i = 0; i < keys_num; ++i) {
+ const struct key_value *kv;
+
+ kv = get_key_from_keys_array(ka, i);
+ if (kv->k && kv->k != s)
+ bwsfree(kv->k);
+ }
memset(ka, 0, keys_array_size());
}
}
/*
+ * Get pointer to a key value in the keys set
+ */
+struct key_value *
+get_key_from_keys_array(struct keys_array *ka, size_t ind)
+{
+
+ return ((struct key_value *)((caddr_t)ka->key +
+ ind * (sizeof(struct key_value) + key_hint_size())));
+}
+
+/*
* Set value of a key in the keys set
*/
void
@@ -122,7 +137,7 @@ set_key_on_keys_array(struct keys_array *ka, struct bwstring *s, size_t ind)
if (ka && keys_num > ind) {
struct key_value *kv;
- kv = &(ka->key[ind]);
+ kv = get_key_from_keys_array(ka, ind);
if (kv->k && kv->k != s)
bwsfree(kv->k);
@@ -156,9 +171,9 @@ sort_list_item_size(struct sort_list_item *si)
if (si->str)
ret += bws_memsize(si->str);
for (size_t i = 0; i < keys_num; ++i) {
- struct key_value *kv;
+ const struct key_value *kv;
- kv = &(si->ka.key[i]);
+ kv = get_key_from_keys_array(&si->ka, i);
if (kv->k != si->str)
ret += bws_memsize(kv->k);
@@ -475,16 +490,19 @@ get_sort_func(struct sort_mods *sm)
int
key_coll(struct keys_array *ps1, struct keys_array *ps2, size_t offset)
{
+ struct key_value *kv1, *kv2;
struct sort_mods *sm;
int res = 0;
for (size_t i = 0; i < keys_num; ++i) {
+ kv1 = get_key_from_keys_array(ps1, i);
+ kv2 = get_key_from_keys_array(ps2, i);
sm = &(keys[i].sm);
if (sm->rflag)
- res = sm->func(&(ps2->key[i]), &(ps1->key[i]), offset);
+ res = sm->func(kv2, kv1, offset);
else
- res = sm->func(&(ps1->key[i]), &(ps2->key[i]), offset);
+ res = sm->func(kv1, kv2, offset);
if (res)
break;
@@ -1087,7 +1105,7 @@ cmp_nans(double d1, double d2)
if (d1 < d2)
return (-1);
- if (d2 > d2)
+ if (d1 > d2)
return (+1);
return (0);
}
diff --git a/usr.bin/sort/coll.h b/usr.bin/sort/coll.h
index 9a70b8eaaba9..6e3f9b45b79a 100644
--- a/usr.bin/sort/coll.h
+++ b/usr.bin/sort/coll.h
@@ -91,7 +91,7 @@ struct key_value
{
struct bwstring *k; /* key string */
struct key_hint hint[0]; /* key sort hint */
-};
+} __packed;
/*
* Set of keys container object.
@@ -146,6 +146,7 @@ cmpcoll_t get_sort_func(struct sort_mods *sm);
struct keys_array *keys_array_alloc(void);
size_t keys_array_size(void);
+struct key_value *get_key_from_keys_array(struct keys_array *ka, size_t ind);
void set_key_on_keys_array(struct keys_array *ka, struct bwstring *s, size_t ind);
void clean_keys_array(const struct bwstring *s, struct keys_array *ka);
diff --git a/usr.bin/sort/radixsort.c b/usr.bin/sort/radixsort.c
index 1fa260b7cc04..79f4346eb3ec 100644
--- a/usr.bin/sort/radixsort.c
+++ b/usr.bin/sort/radixsort.c
@@ -243,9 +243,11 @@ add_leaf(struct sort_level *sl, struct sort_list_item *item)
static inline int
get_wc_index(struct sort_list_item *sli, size_t level)
{
+ const struct key_value *kv;
const struct bwstring *bws;
- bws = sli->ka.key[0].k;
+ kv = get_key_from_keys_array(&sli->ka, 0);
+ bws = kv->k;
if ((BWSLEN(bws) > level))
return (unsigned char) BWS_GET(bws,level);