Refactor logic to check for ASCII-only characters in string
authorMichael Paquier <[email protected]>
Mon, 21 Dec 2020 00:37:11 +0000 (09:37 +0900)
committerMichael Paquier <[email protected]>
Mon, 21 Dec 2020 00:37:11 +0000 (09:37 +0900)
The same logic was present for collation commands, SASLprep and
pgcrypto, so this removes some code.

Author: Michael Paquier
Reviewed-by: Stephen Frost, Heikki Linnakangas
Discussion: https://postgr.es/m/[email protected]

contrib/pgcrypto/pgp-pgsql.c
src/backend/commands/collationcmds.c
src/common/saslprep.c
src/common/string.c
src/include/common/string.h

index 62a2f351e43b93527e6670da94de8dab7de8abf4..0536bfb8921c9b371991056f7d5e425b450ad945 100644 (file)
@@ -32,6 +32,7 @@
 #include "postgres.h"
 
 #include "catalog/pg_type.h"
+#include "common/string.h"
 #include "funcapi.h"
 #include "lib/stringinfo.h"
 #include "mb/pg_wchar.h"
@@ -92,19 +93,6 @@ convert_to_utf8(text *src)
    return convert_charset(src, GetDatabaseEncoding(), PG_UTF8);
 }
 
-static bool
-string_is_ascii(const char *str)
-{
-   const char *p;
-
-   for (p = str; *p; p++)
-   {
-       if (IS_HIGHBIT_SET(*p))
-           return false;
-   }
-   return true;
-}
-
 static void
 clear_and_pfree(text *p)
 {
@@ -814,7 +802,7 @@ parse_key_value_arrays(ArrayType *key_array, ArrayType *val_array,
 
        v = TextDatumGetCString(key_datums[i]);
 
-       if (!string_is_ascii(v))
+       if (!pg_is_ascii(v))
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("header key must not contain non-ASCII characters")));
@@ -836,7 +824,7 @@ parse_key_value_arrays(ArrayType *key_array, ArrayType *val_array,
 
        v = TextDatumGetCString(val_datums[i]);
 
-       if (!string_is_ascii(v))
+       if (!pg_is_ascii(v))
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("header value must not contain non-ASCII characters")));
index 32b2183598d8feb5fa9731d1712851e64955c55d..d62c8defbabc946c12eb471175e827af0a9030e4 100644 (file)
@@ -27,6 +27,7 @@
 #include "commands/comment.h"
 #include "commands/dbcommands.h"
 #include "commands/defrem.h"
+#include "common/string.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
 #include "utils/acl.h"
@@ -286,23 +287,6 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
 #define READ_LOCALE_A_OUTPUT
 #endif
 
-#if defined(READ_LOCALE_A_OUTPUT) || defined(USE_ICU)
-/*
- * Check a string to see if it is pure ASCII
- */
-static bool
-is_all_ascii(const char *str)
-{
-   while (*str)
-   {
-       if (IS_HIGHBIT_SET(*str))
-           return false;
-       str++;
-   }
-   return true;
-}
-#endif                         /* READ_LOCALE_A_OUTPUT || USE_ICU */
-
 #ifdef READ_LOCALE_A_OUTPUT
 /*
  * "Normalize" a libc locale name, stripping off encoding tags such as
@@ -396,7 +380,7 @@ get_icu_locale_comment(const char *localename)
    if (U_FAILURE(status))
        return NULL;            /* no good reason to raise an error */
 
-   /* Check for non-ASCII comment (can't use is_all_ascii for this) */
+   /* Check for non-ASCII comment (can't use pg_is_ascii for this) */
    for (i = 0; i < len_uchar; i++)
    {
        if (displayname[i] > 127)
@@ -477,7 +461,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
             * interpret the non-ASCII characters. We can't do much with
             * those, so we filter them out.
             */
-           if (!is_all_ascii(localebuf))
+           if (!pg_is_ascii(localebuf))
            {
                elog(DEBUG1, "locale name has non-ASCII characters, skipped: \"%s\"", localebuf);
                continue;
@@ -623,7 +607,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
             * Be paranoid about not allowing any non-ASCII strings into
             * pg_collation
             */
-           if (!is_all_ascii(langtag) || !is_all_ascii(collcollate))
+           if (!pg_is_ascii(langtag) || !pg_is_ascii(collcollate))
                continue;
 
            collid = CollationCreate(psprintf("%s-x-icu", langtag),
index d60452f75f288472be5198d6544e4bb691b906f9..48eb1ee9bb987af82f0e6c584aec3aa419583d0e 100644 (file)
@@ -26,6 +26,7 @@
 #endif
 
 #include "common/saslprep.h"
+#include "common/string.h"
 #include "common/unicode_norm.h"
 #include "mb/pg_wchar.h"
 
@@ -47,7 +48,6 @@
 static int codepoint_range_cmp(const void *a, const void *b);
 static bool is_code_in_table(pg_wchar code, const pg_wchar *map, int mapsize);
 static int pg_utf8_string_len(const char *source);
-static bool pg_is_ascii_string(const char *p);
 
 /*
  * Stringprep Mapping Tables.
@@ -1019,21 +1019,6 @@ pg_utf8_string_len(const char *source)
    return num_chars;
 }
 
-/*
- * Returns true if the input string is pure ASCII.
- */
-static bool
-pg_is_ascii_string(const char *p)
-{
-   while (*p)
-   {
-       if (IS_HIGHBIT_SET(*p))
-           return false;
-       p++;
-   }
-   return true;
-}
-
 
 /*
  * pg_saslprep - Normalize a password with SASLprep.
@@ -1076,7 +1061,7 @@ pg_saslprep(const char *input, char **output)
     * Quick check if the input is pure ASCII.  An ASCII string requires no
     * further processing.
     */
-   if (pg_is_ascii_string(input))
+   if (pg_is_ascii(input))
    {
        *output = STRDUP(input);
        if (!(*output))
index bcbbfb813db3d08e49780d831d509d64e9bfe3f5..3e76e2c59fb84aa3c2e61806dfd47adbc6868531 100644 (file)
@@ -92,6 +92,22 @@ pg_clean_ascii(char *str)
 }
 
 
+/*
+ * pg_is_ascii -- Check if string is made only of ASCII characters
+ */
+bool
+pg_is_ascii(const char *str)
+{
+   while (*str)
+   {
+       if (IS_HIGHBIT_SET(*str))
+           return false;
+       str++;
+   }
+   return true;
+}
+
+
 /*
  * pg_strip_crlf -- Remove any trailing newline and carriage return
  *
index 6a4baa6f3590031b3c6a2240fb62c5f705a90639..655ccc0570818d97f443a3e176f8994417c0aa1b 100644 (file)
@@ -18,6 +18,7 @@ extern int    strtoint(const char *pg_restrict str, char **pg_restrict endptr,
                     int base);
 extern void pg_clean_ascii(char *str);
 extern int pg_strip_crlf(char *str);
+extern bool pg_is_ascii(const char *str);
 
 /* functions in src/common/pg_get_line.c */
 extern char *pg_get_line(FILE *stream);