Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Dec 2016 17:13:04 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r310712 - head/usr.bin/sort
Message-ID:  <201612281713.uBSHD4uJ008289@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Wed Dec 28 17:13:03 2016
New Revision: 310712
URL: https://svnweb.freebsd.org/changeset/base/310712

Log:
  - 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

Modified:
  head/usr.bin/sort/coll.c
  head/usr.bin/sort/coll.h
  head/usr.bin/sort/radixsort.c

Modified: head/usr.bin/sort/coll.c
==============================================================================
--- head/usr.bin/sort/coll.c	Wed Dec 28 16:34:49 2016	(r310711)
+++ head/usr.bin/sort/coll.c	Wed Dec 28 17:13:03 2016	(r310712)
@@ -105,14 +105,29 @@ clean_keys_array(const struct bwstring *
 {
 
 	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 
 	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_ite
 		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);
 }

Modified: head/usr.bin/sort/coll.h
==============================================================================
--- head/usr.bin/sort/coll.h	Wed Dec 28 16:34:49 2016	(r310711)
+++ head/usr.bin/sort/coll.h	Wed Dec 28 17:13:03 2016	(r310712)
@@ -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
 
 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);
 

Modified: head/usr.bin/sort/radixsort.c
==============================================================================
--- head/usr.bin/sort/radixsort.c	Wed Dec 28 16:34:49 2016	(r310711)
+++ head/usr.bin/sort/radixsort.c	Wed Dec 28 17:13:03 2016	(r310712)
@@ -243,9 +243,11 @@ add_leaf(struct sort_level *sl, struct s
 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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612281713.uBSHD4uJ008289>