1/*-------------------------------------------------------------------------
4 * various support functions
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
10 * src/backend/tsearch/ts_utils.c
12 *-------------------------------------------------------------------------
19#include "catalog/pg_collation_d.h"
26 * Given the base name and extension of a tsearch config file, return
27 * its full path name. The base name is assumed to be user-supplied,
28 * and is checked to prevent pathname attacks. The extension is assumed
31 * The result is a palloc'd string.
35 const char *extension)
41 * We limit the basename to contain a-z, 0-9, and underscores. This may
42 * be overly restrictive, but we don't want to allow access to anything
43 * outside the tsearch_data directory, so for instance '/' *must* be
44 * rejected, and on some platforms '\' and ':' are risky as well. Allowing
45 * uppercase might result in incompatible behavior between case-sensitive
46 * and case-insensitive filesystems, and non-ASCII characters create other
47 * interesting risks, so on the whole a tight policy seems best.
49 if (strspn(basename,
"abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(basename))
51 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
52 errmsg(
"invalid text search configuration file name \"%s\"",
58 sharepath, basename, extension);
64 * Reads a stop-word file. Each word is run through 'wordop'
65 * function, if given. wordop may either modify the input in-place,
66 * or palloc a new version.
83 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
84 errmsg(
"could not open stop-word file \"%s\": %m",
91 /* Trim trailing space */
92 while (*pbuf && !isspace((
unsigned char) *pbuf))
96 /* Skip empty lines */
103 if (s->
len >= reallen)
108 stop = (
char **)
palloc(
sizeof(
char *) * reallen);
113 stop = (
char **)
repalloc(stop,
sizeof(
char *) * reallen);
119 stop[s->
len] = wordop(line, strlen(line), DEFAULT_COLLATION_OID);
120 if (stop[s->
len] != line)
135 /* Sort to allow binary searching */
143 return (s->
stop && s->
len > 0 &&
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
char my_exec_path[MAXPGPATH]
int pg_mblen(const char *mbstr)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void get_share_path(const char *my_exec_path, char *ret_path)
int pg_qsort_strcmp(const void *a, const void *b)
#define qsort(a, b, c, d)
bool tsearch_readline_begin(tsearch_readline_state *stp, const char *filename)
char * tsearch_readline(tsearch_readline_state *stp)
void tsearch_readline_end(tsearch_readline_state *stp)
void readstoplist(const char *fname, StopList *s, char *(*wordop)(const char *, size_t, Oid))
bool searchstoplist(StopList *s, char *key)
char * get_tsearch_config_filename(const char *basename, const char *extension)