diff options
author | Alexander Korotkov <akorotkov@postgresql.org> | 2019-08-12 06:19:19 +0300 |
---|---|---|
committer | Alexander Korotkov <akorotkov@postgresql.org> | 2019-08-12 06:26:13 +0300 |
commit | 251c8e39bc6b0a3ff1620d9ac10888a7660e6b88 (patch) | |
tree | 4287b390ac6289cb44b3dfefd0fc2096974ca2fd /src/backend/utils/adt/jsonpath_exec.c | |
parent | b43f7c117e667fb51df36ca62e6c86054b0f8d03 (diff) | |
download | postgresql-251c8e39bc6b0a3ff1620d9ac10888a7660e6b88.tar.gz postgresql-251c8e39bc6b0a3ff1620d9ac10888a7660e6b88.zip |
Fix string comparison in jsonpath
Take into account pg_server_to_any() may return input string "as is".
Reported-by: Andrew Dunstan, Thomas Munro
Discussion: https://postgr.es/m/0ed83a33-d900-466a-880a-70ef456c721f%402ndQuadrant.com
Author: Alexander Korotkov, Thomas Munro
Backpatch-through: 12
Diffstat (limited to 'src/backend/utils/adt/jsonpath_exec.c')
-rw-r--r-- | src/backend/utils/adt/jsonpath_exec.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c index 4a0de4fe95a..72bc5eab6cb 100644 --- a/src/backend/utils/adt/jsonpath_exec.c +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -2020,16 +2020,37 @@ compareStrings(const char *mbstr1, int mblen1, } else { - /* We have to convert other encodings to UTF-8 first, then compare. */ - char *utf8str1 = pg_server_to_any(mbstr1, mblen1, PG_UTF8), - *utf8str2 = pg_server_to_any(mbstr2, mblen2, PG_UTF8); - int cmp; + char *utf8str1, + *utf8str2; + int cmp, + utf8len1, + utf8len2; - cmp = binaryCompareStrings(utf8str1, strlen(utf8str1), - utf8str2, strlen(utf8str2)); + /* + * We have to convert other encodings to UTF-8 first, then compare. + * Input strings may be not null-terminated and pg_server_to_any() may + * return them "as is". So, use strlen() only if there is real + * conversion. + */ + utf8str1 = pg_server_to_any(mbstr1, mblen1, PG_UTF8); + utf8str2 = pg_server_to_any(mbstr2, mblen2, PG_UTF8); + utf8len1 = (mbstr1 == utf8str1) ? mblen1 : strlen(utf8str1); + utf8len2 = (mbstr2 == utf8str2) ? mblen2 : strlen(utf8str2); + + cmp = binaryCompareStrings(utf8str1, utf8len1, utf8str2, utf8len2); + + /* + * If pg_server_to_any() did no real conversion, then we actually + * compared original strings. So, we already done. + */ + if (mbstr1 == utf8str1 && mbstr2 == utf8str2) + return cmp; - pfree(utf8str1); - pfree(utf8str2); + /* Free memory if needed */ + if (mbstr1 != utf8str1) + pfree(utf8str1); + if (mbstr2 != utf8str2) + pfree(utf8str2); /* * When all Unicode codepoints are equal, return result of binary |