diff options
author | Noah Misch <noah@leadboat.com> | 2020-01-04 11:31:42 -0800 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2020-01-04 11:31:42 -0800 |
commit | 5b630501e9fa58c5069b36247d63fc460d912c7f (patch) | |
tree | e727c0d91f301e3eb06c73e6d55b52dc8e821a71 | |
parent | fac1c04feca6d01f2d324088c5899485f55b6217 (diff) | |
download | postgresql-5b630501e9fa58c5069b36247d63fc460d912c7f.tar.gz postgresql-5b630501e9fa58c5069b36247d63fc460d912c7f.zip |
Skip memcpy(x, x) in qunique().
It has undefined behavior. Follow the precedent of commit
9a9473f3cce1a21c25d6cc7569710e832d2b180b. No back-patch, since the
master branch alone has this function.
Discussion: https://postgr.es/m/20191229070221.GA13873@gust.leadboat.com
-rw-r--r-- | src/include/lib/qunique.h | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/src/include/lib/qunique.h b/src/include/lib/qunique.h index 73aa10f1659..95d9fef637a 100644 --- a/src/include/lib/qunique.h +++ b/src/include/lib/qunique.h @@ -30,8 +30,9 @@ qunique(void *array, size_t elements, size_t width, for (i = 1, j = 0; i < elements; ++i) { - if (compare(bytes + i * width, bytes + j * width) != 0) - memcpy(bytes + ++j * width, bytes + i * width, width); + if (compare(bytes + i * width, bytes + j * width) != 0 && + ++j != i) + memcpy(bytes + j * width, bytes + i * width, width); } return j + 1; @@ -55,8 +56,9 @@ qunique_arg(void *array, size_t elements, size_t width, for (i = 1, j = 0; i < elements; ++i) { - if (compare(bytes + i * width, bytes + j * width, arg) != 0) - memcpy(bytes + ++j * width, bytes + i * width, width); + if (compare(bytes + i * width, bytes + j * width, arg) != 0 && + ++j != i) + memcpy(bytes + j * width, bytes + i * width, width); } return j + 1; |