PostgreSQL Source Code git master
Loading...
Searching...
No Matches
test_saslprep.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "common/saslprep.h"
#include "fmgr.h"
#include "funcapi.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "utils/builtins.h"
Include dependency graph for test_saslprep.c:

Go to the source code of this file.

Data Structures

struct  pg_saslprep_test_context
 
struct  pg_utf8_codepoint_range
 

Macros

#define PG_UTF8_TEST_RANGES_LEN    (sizeof(pg_utf8_test_ranges) / sizeof(pg_utf8_test_ranges[0]))
 

Functions

static const charsaslprep_status_to_text (pg_saslprep_rc rc)
 
 PG_FUNCTION_INFO_V1 (test_saslprep)
 
Datum test_saslprep (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (test_saslprep_ranges)
 
Datum test_saslprep_ranges (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 
static const pg_utf8_codepoint_range pg_utf8_test_ranges []
 

Macro Definition Documentation

◆ PG_UTF8_TEST_RANGES_LEN

#define PG_UTF8_TEST_RANGES_LEN    (sizeof(pg_utf8_test_ranges) / sizeof(pg_utf8_test_ranges[0]))

Definition at line 138 of file test_saslprep.c.

149{
152 HeapTuple tuple;
153 Datum result;
154
155 /* First call setup */
156 if (SRF_IS_FIRSTCALL())
157 {
158 MemoryContext oldcontext;
159 TupleDesc tupdesc;
160
162 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
163
164 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
165 elog(ERROR, "return type must be a row type");
166 funcctx->tuple_desc = tupdesc;
167
168 /* Allocate context with range setup */
170 ctx->current_range = 0;
172 funcctx->user_fctx = ctx;
173
174 MemoryContextSwitchTo(oldcontext);
175 }
176
178 ctx = (pg_saslprep_test_context *) funcctx->user_fctx;
179
181 {
182 char32_t codepoint = ctx->current_codepoint;
183 unsigned char utf8_buf[5];
184 char input_str[6];
185 char *output = NULL;
187 int utf8_len;
188 const char *status;
191 char codepoint_str[16];
192 Datum values[4] = {0};
193 bool nulls[4] = {0};
196
198
199 /* Switch to next range if finished with the previous one */
200 if (ctx->current_codepoint > range->end_codepoint)
201 {
202 ctx->current_range++;
204 ctx->current_codepoint =
206 continue;
207 }
208
209 codepoint = ctx->current_codepoint;
210
211 /* Convert code point to UTF-8 */
212 utf8_len = unicode_utf8len(codepoint);
213 if (utf8_len == 0)
214 {
215 ctx->current_codepoint++;
216 continue;
217 }
218 unicode_to_utf8(codepoint, utf8_buf);
219
220 /* Create null-terminated string */
222 input_str[utf8_len] = '\0';
223
224 /* Test with pg_saslprep */
226
227 /* Prepare output values */
228 memset(nulls, false, sizeof(nulls));
229
230 /* codepoint as text U+XXXX format */
231 if (codepoint <= 0xFFFF)
232 snprintf(codepoint_str, sizeof(codepoint_str), "U+%04X", codepoint);
233 else
234 snprintf(codepoint_str, sizeof(codepoint_str), "U+%06X", codepoint);
236
237 /* status */
238 status = saslprep_status_to_text(rc);
239 values[1] = CStringGetTextDatum(status);
240
241 /* input_bytes */
246
247 /* output_bytes */
248 if (output != NULL)
249 {
250 int output_len = strlen(output);
251
256 pfree(output);
257 }
258 else
259 {
260 nulls[3] = true;
261 values[3] = (Datum) 0;
262 }
263
264 /* Build and return tuple */
265 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
266 result = HeapTupleGetDatum(tuple);
267
268 /* Move to next code point */
269 ctx->current_codepoint++;
270
271 SRF_RETURN_NEXT(funcctx, result);
272 }
273
274 /* All done */
276}
static Datum values[MAXATTR]
Definition bootstrap.c:188
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define VARHDRSZ
Definition c.h:783
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:276
#define SRF_IS_FIRSTCALL()
Definition funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition funcapi.h:308
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition funcapi.h:306
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
#define SRF_RETURN_DONE(_funcctx)
Definition funcapi.h:328
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1037
FILE * output
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
static unsigned char * unicode_to_utf8(char32_t c, unsigned char *utf8string)
Definition pg_wchar.h:575
static int unicode_utf8len(char32_t c)
Definition pg_wchar.h:607
#define snprintf
Definition port.h:260
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
pg_saslprep_rc pg_saslprep(const char *input, char **output)
Definition saslprep.c:1047
pg_saslprep_rc
Definition saslprep.h:21
Definition c.h:778
static const char * saslprep_status_to_text(pg_saslprep_rc rc)
#define PG_UTF8_TEST_RANGES_LEN
static const pg_utf8_codepoint_range pg_utf8_test_ranges[]
static char * VARDATA(const void *PTR)
Definition varatt.h:305
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

Function Documentation

◆ PG_FUNCTION_INFO_V1() [1/2]

PG_FUNCTION_INFO_V1 ( test_saslprep  )

◆ PG_FUNCTION_INFO_V1() [2/2]

PG_FUNCTION_INFO_V1 ( test_saslprep_ranges  )

◆ saslprep_status_to_text()

static const char * saslprep_status_to_text ( pg_saslprep_rc  rc)
static

Definition at line 27 of file test_saslprep.c.

28{
29 const char *status = "???";
30
31 switch (rc)
32 {
33 case SASLPREP_OOM:
34 status = "OOM";
35 break;
37 status = "SUCCESS";
38 break;
40 status = "INVALID_UTF8";
41 break;
43 status = "PROHIBITED";
44 break;
45 }
46
47 return status;
48}
@ SASLPREP_INVALID_UTF8
Definition saslprep.h:24
@ SASLPREP_PROHIBITED
Definition saslprep.h:25
@ SASLPREP_OOM
Definition saslprep.h:23
@ SASLPREP_SUCCESS
Definition saslprep.h:22

References SASLPREP_INVALID_UTF8, SASLPREP_OOM, SASLPREP_PROHIBITED, and SASLPREP_SUCCESS.

Referenced by test_saslprep(), and test_saslprep_ranges().

◆ test_saslprep()

Datum test_saslprep ( PG_FUNCTION_ARGS  )

Definition at line 58 of file test_saslprep.c.

59{
60 bytea *string = PG_GETARG_BYTEA_PP(0);
61 char *src;
63 char *input_data;
64 char *result;
67 const char *status = NULL;
69 bool *nulls;
70 TupleDesc tupdesc;
72
73 /* determine result type */
74 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
75 elog(ERROR, "return type must be a row type");
76
77 values = palloc0_array(Datum, tupdesc->natts);
78 nulls = palloc0_array(bool, tupdesc->natts);
79
80 src_len = VARSIZE_ANY_EXHDR(string);
81 src = VARDATA_ANY(string);
82
83 /*
84 * Copy the input given, to make SASLprep() act on a sanitized string.
85 */
87 strlcpy(input_data, src, src_len + 1);
88
89 rc = pg_saslprep(input_data, &result);
90 status = saslprep_status_to_text(rc);
91
92 if (result)
93 {
94 result_len = strlen(result);
99 }
100 else
101 nulls[0] = true;
102
103 values[1] = CStringGetTextDatum(status);
104
106}
size_t Size
Definition c.h:691
#define palloc0_array(type, count)
Definition fe_memutils.h:77
#define PG_GETARG_BYTEA_PP(n)
Definition fmgr.h:309
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
void * palloc0(Size size)
Definition mcxt.c:1417
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486

References CStringGetTextDatum, elog, ERROR, fb(), get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum(), TupleDescData::natts, palloc(), palloc0(), palloc0_array, PG_GETARG_BYTEA_PP, PG_RETURN_DATUM, pg_saslprep(), PointerGetDatum(), saslprep_status_to_text(), SET_VARSIZE(), strlcpy(), TYPEFUNC_COMPOSITE, values, VARDATA(), VARDATA_ANY(), VARHDRSZ, and VARSIZE_ANY_EXHDR().

◆ test_saslprep_ranges()

Datum test_saslprep_ranges ( PG_FUNCTION_ARGS  )

Definition at line 149 of file test_saslprep.c.

150{
153 HeapTuple tuple;
154 Datum result;
155
156 /* First call setup */
157 if (SRF_IS_FIRSTCALL())
158 {
159 MemoryContext oldcontext;
160 TupleDesc tupdesc;
161
163 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
164
165 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
166 elog(ERROR, "return type must be a row type");
167 funcctx->tuple_desc = tupdesc;
168
169 /* Allocate context with range setup */
171 ctx->current_range = 0;
173 funcctx->user_fctx = ctx;
174
175 MemoryContextSwitchTo(oldcontext);
176 }
177
179 ctx = (pg_saslprep_test_context *) funcctx->user_fctx;
180
182 {
183 char32_t codepoint = ctx->current_codepoint;
184 unsigned char utf8_buf[5];
185 char input_str[6];
186 char *output = NULL;
188 int utf8_len;
189 const char *status;
192 char codepoint_str[16];
193 Datum values[4] = {0};
194 bool nulls[4] = {0};
197
199
200 /* Switch to next range if finished with the previous one */
201 if (ctx->current_codepoint > range->end_codepoint)
202 {
203 ctx->current_range++;
205 ctx->current_codepoint =
207 continue;
208 }
209
210 codepoint = ctx->current_codepoint;
211
212 /* Convert code point to UTF-8 */
213 utf8_len = unicode_utf8len(codepoint);
214 if (utf8_len == 0)
215 {
216 ctx->current_codepoint++;
217 continue;
218 }
219 unicode_to_utf8(codepoint, utf8_buf);
220
221 /* Create null-terminated string */
223 input_str[utf8_len] = '\0';
224
225 /* Test with pg_saslprep */
227
228 /* Prepare output values */
229 memset(nulls, false, sizeof(nulls));
230
231 /* codepoint as text U+XXXX format */
232 if (codepoint <= 0xFFFF)
233 snprintf(codepoint_str, sizeof(codepoint_str), "U+%04X", codepoint);
234 else
235 snprintf(codepoint_str, sizeof(codepoint_str), "U+%06X", codepoint);
237
238 /* status */
239 status = saslprep_status_to_text(rc);
240 values[1] = CStringGetTextDatum(status);
241
242 /* input_bytes */
247
248 /* output_bytes */
249 if (output != NULL)
250 {
251 int output_len = strlen(output);
252
257 pfree(output);
258 }
259 else
260 {
261 nulls[3] = true;
262 values[3] = (Datum) 0;
263 }
264
265 /* Build and return tuple */
266 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
267 result = HeapTupleGetDatum(tuple);
268
269 /* Move to next code point */
270 ctx->current_codepoint++;
271
272 SRF_RETURN_NEXT(funcctx, result);
273 }
274
275 /* All done */
277}

References CHECK_FOR_INTERRUPTS, CStringGetTextDatum, pg_saslprep_test_context::current_codepoint, pg_saslprep_test_context::current_range, elog, ERROR, fb(), get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum(), MemoryContextSwitchTo(), output, palloc(), pfree(), pg_saslprep(), pg_utf8_test_ranges, PG_UTF8_TEST_RANGES_LEN, PointerGetDatum(), range(), saslprep_status_to_text(), SET_VARSIZE(), snprintf, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, pg_utf8_codepoint_range::start_codepoint, TYPEFUNC_COMPOSITE, unicode_to_utf8(), unicode_utf8len(), values, VARDATA(), and VARHDRSZ.

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 24 of file test_saslprep.c.

◆ pg_utf8_test_ranges

const pg_utf8_codepoint_range pg_utf8_test_ranges[]
static
Initial value:
= {
{0x0000, 0xD7FF},
{0xE000, 0xFFFF},
{0x10000, 0x1FFFF},
{0x20000, 0x2FFFF},
{0x30000, 0x3FFFF},
{0x40000, 0xDFFFF},
{0xE0000, 0xEFFFF},
{0xF0000, 0xFFFFF},
{0x100000, 0x10FFFF},
}

Definition at line 124 of file test_saslprep.c.

124 {
125 /* 1, 2, 3 bytes */
126 {0x0000, 0xD7FF}, /* Basic Multilingual Plane, before surrogates */
127 {0xE000, 0xFFFF}, /* Basic Multilingual Plane, after surrogates */
128 /* 4 bytes */
129 {0x10000, 0x1FFFF}, /* Supplementary Multilingual Plane */
130 {0x20000, 0x2FFFF}, /* Supplementary Ideographic Plane */
131 {0x30000, 0x3FFFF}, /* Tertiary Ideographic Plane */
132 {0x40000, 0xDFFFF}, /* Unassigned planes */
133 {0xE0000, 0xEFFFF}, /* Supplementary Special-purpose Plane */
134 {0xF0000, 0xFFFFF}, /* Private Use Area A */
135 {0x100000, 0x10FFFF}, /* Private Use Area B */
136};

Referenced by test_saslprep_ranges().