Author: marius
Date: Wed May 10 20:29:33 2017
New Revision: 318153
URL: https://svnweb.freebsd.org/changeset/base/318153

Log:
  MFC: r310712
  
  - 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]

Modified:
  stable/11/usr.bin/sort/coll.c
  stable/11/usr.bin/sort/coll.h
  stable/11/usr.bin/sort/radixsort.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/usr.bin/sort/coll.c
==============================================================================
--- stable/11/usr.bin/sort/coll.c       Wed May 10 20:29:01 2017        
(r318152)
+++ stable/11/usr.bin/sort/coll.c       Wed May 10 20:29:33 2017        
(r318153)
@@ -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: stable/11/usr.bin/sort/coll.h
==============================================================================
--- stable/11/usr.bin/sort/coll.h       Wed May 10 20:29:01 2017        
(r318152)
+++ stable/11/usr.bin/sort/coll.h       Wed May 10 20:29:33 2017        
(r318153)
@@ -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: stable/11/usr.bin/sort/radixsort.c
==============================================================================
--- stable/11/usr.bin/sort/radixsort.c  Wed May 10 20:29:01 2017        
(r318152)
+++ stable/11/usr.bin/sort/radixsort.c  Wed May 10 20:29:33 2017        
(r318153)
@@ -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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to