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 139 of file test_saslprep.c.

150{
153 HeapTuple tuple;
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
273 }
274
275 /* All done */
277}
static Datum values[MAXATTR]
Definition bootstrap.c:190
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define VARHDRSZ
Definition c.h:781
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
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:1025
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:125
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:428
static int unicode_utf8len(char32_t c)
Definition pg_wchar.h:460
#define snprintf
Definition port.h:260
uint64_t Datum
Definition postgres.h:70
#define PointerGetDatum(X)
Definition postgres.h:354
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:776
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 */
88 input_data[src_len] = '\0';
89
91 status = saslprep_status_to_text(rc);
92
93 if (result)
94 {
100 }
101 else
102 nulls[0] = true;
103
104 values[1] = CStringGetTextDatum(status);
105
107}
size_t Size
Definition c.h:689
#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
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(), memcpy(), TupleDescData::natts, palloc(), palloc0(), palloc0_array, PG_GETARG_BYTEA_PP, PG_RETURN_DATUM, pg_saslprep(), PointerGetDatum, result, saslprep_status_to_text(), SET_VARSIZE(), TYPEFUNC_COMPOSITE, values, VARDATA(), VARDATA_ANY(), VARHDRSZ, and VARSIZE_ANY_EXHDR().

◆ test_saslprep_ranges()

Datum test_saslprep_ranges ( PG_FUNCTION_ARGS  )

Definition at line 150 of file test_saslprep.c.

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

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(), memcpy(), MemoryContextSwitchTo(), output, palloc(), pfree(), pg_saslprep(), pg_utf8_test_ranges, PG_UTF8_TEST_RANGES_LEN, PointerGetDatum, range(), result, 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 125 of file test_saslprep.c.

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

Referenced by test_saslprep_ranges().