LCOV - differential code coverage report
Current view: top level - contrib/pgcrypto - pgcrypto.c (source / functions) Coverage Total Hit LBC UIC UBC GIC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 93.4 % 183 171 1 9 2 89 82 10 88
Current Date: 2023-04-08 15:15:32 Functions: 91.7 % 24 22 2 22 2 22
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*
       2                 :  * pgcrypto.c
       3                 :  *      Various cryptographic stuff for PostgreSQL.
       4                 :  *
       5                 :  * Copyright (c) 2001 Marko Kreen
       6                 :  * All rights reserved.
       7                 :  *
       8                 :  * Redistribution and use in source and binary forms, with or without
       9                 :  * modification, are permitted provided that the following conditions
      10                 :  * are met:
      11                 :  * 1. Redistributions of source code must retain the above copyright
      12                 :  *    notice, this list of conditions and the following disclaimer.
      13                 :  * 2. Redistributions in binary form must reproduce the above copyright
      14                 :  *    notice, this list of conditions and the following disclaimer in the
      15                 :  *    documentation and/or other materials provided with the distribution.
      16                 :  *
      17                 :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      18                 :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      19                 :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      20                 :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      21                 :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      22                 :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      23                 :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      24                 :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      25                 :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      26                 :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      27                 :  * SUCH DAMAGE.
      28                 :  *
      29                 :  * contrib/pgcrypto/pgcrypto.c
      30                 :  */
      31                 : 
      32                 : #include "postgres.h"
      33                 : 
      34                 : #include <ctype.h>
      35                 : 
      36                 : #include "parser/scansup.h"
      37                 : #include "pgcrypto.h"
      38                 : #include "px-crypt.h"
      39                 : #include "px.h"
      40                 : #include "utils/builtins.h"
      41                 : #include "utils/uuid.h"
      42                 : #include "varatt.h"
      43                 : 
      44 GIC          22 : PG_MODULE_MAGIC;
      45 ECB             : 
      46                 : /* private stuff */
      47                 : 
      48                 : typedef int (*PFN) (const char *name, void **res);
      49                 : static void *find_provider(text *name, PFN provider_lookup, const char *desc,
      50                 :                            int silent);
      51                 : 
      52                 : /* SQL function: hash(bytea, text) returns bytea */
      53 GIC           8 : PG_FUNCTION_INFO_V1(pg_digest);
      54                 : 
      55 ECB             : Datum
      56 GIC          44 : pg_digest(PG_FUNCTION_ARGS)
      57                 : {
      58 ECB             :     bytea      *arg;
      59                 :     text       *name;
      60                 :     unsigned    len,
      61                 :                 hlen;
      62                 :     PX_MD      *md;
      63                 :     bytea      *res;
      64                 : 
      65 GIC          44 :     name = PG_GETARG_TEXT_PP(1);
      66                 : 
      67 ECB             :     /* will give error if fails */
      68 GIC          44 :     md = find_provider(name, (PFN) px_find_digest, "Digest", 0);
      69                 : 
      70 CBC          43 :     hlen = px_md_result_size(md);
      71                 : 
      72              43 :     res = (text *) palloc(hlen + VARHDRSZ);
      73 GIC          43 :     SET_VARSIZE(res, hlen + VARHDRSZ);
      74 ECB             : 
      75 CBC          43 :     arg = PG_GETARG_BYTEA_PP(0);
      76 GIC          43 :     len = VARSIZE_ANY_EXHDR(arg);
      77 ECB             : 
      78 CBC          43 :     px_md_update(md, (uint8 *) VARDATA_ANY(arg), len);
      79 GIC          43 :     px_md_finish(md, (uint8 *) VARDATA(res));
      80 CBC          43 :     px_md_free(md);
      81 ECB             : 
      82 CBC          43 :     PG_FREE_IF_COPY(arg, 0);
      83 GIC          43 :     PG_FREE_IF_COPY(name, 1);
      84 ECB             : 
      85 CBC          43 :     PG_RETURN_BYTEA_P(res);
      86                 : }
      87 ECB             : 
      88                 : /* SQL function: hmac(data:bytea, key:bytea, type:text) returns bytea */
      89 GIC           7 : PG_FUNCTION_INFO_V1(pg_hmac);
      90                 : 
      91 ECB             : Datum
      92 GIC          15 : pg_hmac(PG_FUNCTION_ARGS)
      93                 : {
      94 ECB             :     bytea      *arg;
      95                 :     bytea      *key;
      96                 :     text       *name;
      97                 :     unsigned    len,
      98                 :                 hlen,
      99                 :                 klen;
     100                 :     PX_HMAC    *h;
     101                 :     bytea      *res;
     102                 : 
     103 GIC          15 :     name = PG_GETARG_TEXT_PP(2);
     104                 : 
     105 ECB             :     /* will give error if fails */
     106 GIC          15 :     h = find_provider(name, (PFN) px_find_hmac, "HMAC", 0);
     107                 : 
     108 CBC          14 :     hlen = px_hmac_result_size(h);
     109                 : 
     110              14 :     res = (text *) palloc(hlen + VARHDRSZ);
     111 GIC          14 :     SET_VARSIZE(res, hlen + VARHDRSZ);
     112 ECB             : 
     113 CBC          14 :     arg = PG_GETARG_BYTEA_PP(0);
     114 GIC          14 :     key = PG_GETARG_BYTEA_PP(1);
     115 CBC          14 :     len = VARSIZE_ANY_EXHDR(arg);
     116              14 :     klen = VARSIZE_ANY_EXHDR(key);
     117 ECB             : 
     118 CBC          14 :     px_hmac_init(h, (uint8 *) VARDATA_ANY(key), klen);
     119 GIC          14 :     px_hmac_update(h, (uint8 *) VARDATA_ANY(arg), len);
     120 CBC          14 :     px_hmac_finish(h, (uint8 *) VARDATA(res));
     121              14 :     px_hmac_free(h);
     122 ECB             : 
     123 CBC          14 :     PG_FREE_IF_COPY(arg, 0);
     124 GIC          14 :     PG_FREE_IF_COPY(key, 1);
     125 CBC          14 :     PG_FREE_IF_COPY(name, 2);
     126 ECB             : 
     127 CBC          14 :     PG_RETURN_BYTEA_P(res);
     128                 : }
     129 ECB             : 
     130                 : 
     131                 : /* SQL function: pg_gen_salt(text) returns text */
     132 GIC           4 : PG_FUNCTION_INFO_V1(pg_gen_salt);
     133                 : 
     134 ECB             : Datum
     135 GIC           3 : pg_gen_salt(PG_FUNCTION_ARGS)
     136                 : {
     137 CBC           3 :     text       *arg0 = PG_GETARG_TEXT_PP(0);
     138                 :     int         len;
     139 ECB             :     char        buf[PX_MAX_SALT_LEN + 1];
     140                 : 
     141 GIC           3 :     text_to_cstring_buffer(arg0, buf, sizeof(buf));
     142               3 :     len = px_gen_salt(buf, buf, 0);
     143 CBC           3 :     if (len < 0)
     144               1 :         ereport(ERROR,
     145 ECB             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     146                 :                  errmsg("gen_salt: %s", px_strerror(len))));
     147                 : 
     148 GIC           2 :     PG_FREE_IF_COPY(arg0, 0);
     149                 : 
     150 CBC           2 :     PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len));
     151                 : }
     152 ECB             : 
     153                 : /* SQL function: pg_gen_salt(text, int4) returns text */
     154 GIC           3 : PG_FUNCTION_INFO_V1(pg_gen_salt_rounds);
     155                 : 
     156 ECB             : Datum
     157 GIC           2 : pg_gen_salt_rounds(PG_FUNCTION_ARGS)
     158                 : {
     159 CBC           2 :     text       *arg0 = PG_GETARG_TEXT_PP(0);
     160 GIC           2 :     int         rounds = PG_GETARG_INT32(1);
     161 ECB             :     int         len;
     162                 :     char        buf[PX_MAX_SALT_LEN + 1];
     163                 : 
     164 GIC           2 :     text_to_cstring_buffer(arg0, buf, sizeof(buf));
     165               2 :     len = px_gen_salt(buf, buf, rounds);
     166 CBC           2 :     if (len < 0)
     167 LBC           0 :         ereport(ERROR,
     168 ECB             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     169 EUB             :                  errmsg("gen_salt: %s", px_strerror(len))));
     170                 : 
     171 GIC           2 :     PG_FREE_IF_COPY(arg0, 0);
     172                 : 
     173 CBC           2 :     PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len));
     174                 : }
     175 ECB             : 
     176                 : /* SQL function: pg_crypt(psw:text, salt:text) returns text */
     177 GIC           5 : PG_FUNCTION_INFO_V1(pg_crypt);
     178                 : 
     179 ECB             : Datum
     180 GIC          25 : pg_crypt(PG_FUNCTION_ARGS)
     181                 : {
     182 CBC          25 :     text       *arg0 = PG_GETARG_TEXT_PP(0);
     183 GIC          25 :     text       *arg1 = PG_GETARG_TEXT_PP(1);
     184 ECB             :     char       *buf0,
     185                 :                *buf1,
     186                 :                *cres,
     187                 :                *resbuf;
     188                 :     text       *res;
     189                 : 
     190 GIC          25 :     buf0 = text_to_cstring(arg0);
     191              25 :     buf1 = text_to_cstring(arg1);
     192 ECB             : 
     193 CBC          25 :     resbuf = palloc0(PX_MAX_CRYPT);
     194                 : 
     195              25 :     cres = px_crypt(buf0, buf1, resbuf, PX_MAX_CRYPT);
     196                 : 
     197              20 :     pfree(buf0);
     198 GIC          20 :     pfree(buf1);
     199 ECB             : 
     200 CBC          20 :     if (cres == NULL)
     201 GIC           2 :         ereport(ERROR,
     202 ECB             :                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
     203                 :                  errmsg("crypt(3) returned NULL")));
     204                 : 
     205 GIC          18 :     res = cstring_to_text(cres);
     206                 : 
     207 CBC          18 :     pfree(resbuf);
     208                 : 
     209              18 :     PG_FREE_IF_COPY(arg0, 0);
     210 GIC          18 :     PG_FREE_IF_COPY(arg1, 1);
     211 ECB             : 
     212 CBC          18 :     PG_RETURN_TEXT_P(res);
     213                 : }
     214 ECB             : 
     215                 : /* SQL function: pg_encrypt(bytea, bytea, text) returns bytea */
     216 GIC           7 : PG_FUNCTION_INFO_V1(pg_encrypt);
     217                 : 
     218 ECB             : Datum
     219 GIC          55 : pg_encrypt(PG_FUNCTION_ARGS)
     220                 : {
     221 ECB             :     int         err;
     222                 :     bytea      *data,
     223                 :                *key,
     224                 :                *res;
     225                 :     text       *type;
     226                 :     PX_Combo   *c;
     227                 :     unsigned    dlen,
     228                 :                 klen,
     229                 :                 rlen;
     230                 : 
     231 GIC          55 :     type = PG_GETARG_TEXT_PP(2);
     232              55 :     c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
     233 ECB             : 
     234 CBC          54 :     data = PG_GETARG_BYTEA_PP(0);
     235 GIC          54 :     key = PG_GETARG_BYTEA_PP(1);
     236 CBC          54 :     dlen = VARSIZE_ANY_EXHDR(data);
     237              54 :     klen = VARSIZE_ANY_EXHDR(key);
     238 ECB             : 
     239 CBC          54 :     rlen = px_combo_encrypt_len(c, dlen);
     240 GIC          54 :     res = palloc(VARHDRSZ + rlen);
     241 ECB             : 
     242 CBC          54 :     err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen, NULL, 0);
     243 GIC          54 :     if (!err)
     244 CBC          50 :         err = px_combo_encrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
     245 ECB             :                                (uint8 *) VARDATA(res), &rlen);
     246 CBC          54 :     px_combo_free(c);
     247                 : 
     248              54 :     PG_FREE_IF_COPY(data, 0);
     249 GIC          54 :     PG_FREE_IF_COPY(key, 1);
     250 CBC          54 :     PG_FREE_IF_COPY(type, 2);
     251 ECB             : 
     252 CBC          54 :     if (err)
     253                 :     {
     254              33 :         pfree(res);
     255 GIC          33 :         ereport(ERROR,
     256 ECB             :                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
     257                 :                  errmsg("encrypt error: %s", px_strerror(err))));
     258                 :     }
     259                 : 
     260 GIC          21 :     SET_VARSIZE(res, VARHDRSZ + rlen);
     261              21 :     PG_RETURN_BYTEA_P(res);
     262 ECB             : }
     263                 : 
     264                 : /* SQL function: pg_decrypt(bytea, bytea, text) returns bytea */
     265 GIC           3 : PG_FUNCTION_INFO_V1(pg_decrypt);
     266                 : 
     267 ECB             : Datum
     268 GIC           5 : pg_decrypt(PG_FUNCTION_ARGS)
     269                 : {
     270 ECB             :     int         err;
     271                 :     bytea      *data,
     272                 :                *key,
     273                 :                *res;
     274                 :     text       *type;
     275                 :     PX_Combo   *c;
     276                 :     unsigned    dlen,
     277                 :                 klen,
     278                 :                 rlen;
     279                 : 
     280 GIC           5 :     type = PG_GETARG_TEXT_PP(2);
     281               5 :     c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
     282 ECB             : 
     283 CBC           5 :     data = PG_GETARG_BYTEA_PP(0);
     284 GIC           5 :     key = PG_GETARG_BYTEA_PP(1);
     285 CBC           5 :     dlen = VARSIZE_ANY_EXHDR(data);
     286               5 :     klen = VARSIZE_ANY_EXHDR(key);
     287 ECB             : 
     288 CBC           5 :     rlen = px_combo_decrypt_len(c, dlen);
     289 GIC           5 :     res = palloc(VARHDRSZ + rlen);
     290 ECB             : 
     291 CBC           5 :     err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen, NULL, 0);
     292 GIC           5 :     if (!err)
     293 CBC           5 :         err = px_combo_decrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
     294 ECB             :                                (uint8 *) VARDATA(res), &rlen);
     295                 : 
     296 GIC           5 :     px_combo_free(c);
     297                 : 
     298 CBC           5 :     if (err)
     299 GIC           1 :         ereport(ERROR,
     300 ECB             :                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
     301                 :                  errmsg("decrypt error: %s", px_strerror(err))));
     302                 : 
     303 GIC           4 :     SET_VARSIZE(res, VARHDRSZ + rlen);
     304                 : 
     305 CBC           4 :     PG_FREE_IF_COPY(data, 0);
     306 GIC           4 :     PG_FREE_IF_COPY(key, 1);
     307 CBC           4 :     PG_FREE_IF_COPY(type, 2);
     308 ECB             : 
     309 CBC           4 :     PG_RETURN_BYTEA_P(res);
     310                 : }
     311 ECB             : 
     312                 : /* SQL function: pg_encrypt_iv(bytea, bytea, bytea, text) returns bytea */
     313 GIC           6 : PG_FUNCTION_INFO_V1(pg_encrypt_iv);
     314                 : 
     315 ECB             : Datum
     316 GIC           5 : pg_encrypt_iv(PG_FUNCTION_ARGS)
     317                 : {
     318 ECB             :     int         err;
     319                 :     bytea      *data,
     320                 :                *key,
     321                 :                *iv,
     322                 :                *res;
     323                 :     text       *type;
     324                 :     PX_Combo   *c;
     325                 :     unsigned    dlen,
     326                 :                 klen,
     327                 :                 ivlen,
     328                 :                 rlen;
     329                 : 
     330 GIC           5 :     type = PG_GETARG_TEXT_PP(3);
     331               5 :     c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
     332 ECB             : 
     333 CBC           5 :     data = PG_GETARG_BYTEA_PP(0);
     334 GIC           5 :     key = PG_GETARG_BYTEA_PP(1);
     335 CBC           5 :     iv = PG_GETARG_BYTEA_PP(2);
     336               5 :     dlen = VARSIZE_ANY_EXHDR(data);
     337               5 :     klen = VARSIZE_ANY_EXHDR(key);
     338               5 :     ivlen = VARSIZE_ANY_EXHDR(iv);
     339 ECB             : 
     340 CBC           5 :     rlen = px_combo_encrypt_len(c, dlen);
     341 GIC           5 :     res = palloc(VARHDRSZ + rlen);
     342 ECB             : 
     343 CBC           5 :     err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen,
     344                 :                         (uint8 *) VARDATA_ANY(iv), ivlen);
     345               5 :     if (!err)
     346 GIC           5 :         err = px_combo_encrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
     347 ECB             :                                (uint8 *) VARDATA(res), &rlen);
     348                 : 
     349 GIC           5 :     px_combo_free(c);
     350                 : 
     351 CBC           5 :     if (err)
     352 GIC           3 :         ereport(ERROR,
     353 ECB             :                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
     354                 :                  errmsg("encrypt_iv error: %s", px_strerror(err))));
     355                 : 
     356 GIC           2 :     SET_VARSIZE(res, VARHDRSZ + rlen);
     357                 : 
     358 CBC           2 :     PG_FREE_IF_COPY(data, 0);
     359 GIC           2 :     PG_FREE_IF_COPY(key, 1);
     360 CBC           2 :     PG_FREE_IF_COPY(iv, 2);
     361               2 :     PG_FREE_IF_COPY(type, 3);
     362 ECB             : 
     363 CBC           2 :     PG_RETURN_BYTEA_P(res);
     364                 : }
     365 ECB             : 
     366                 : /* SQL function: pg_decrypt_iv(bytea, bytea, bytea, text) returns bytea */
     367 GIC           6 : PG_FUNCTION_INFO_V1(pg_decrypt_iv);
     368                 : 
     369 ECB             : Datum
     370 GIC           6 : pg_decrypt_iv(PG_FUNCTION_ARGS)
     371                 : {
     372 ECB             :     int         err;
     373                 :     bytea      *data,
     374                 :                *key,
     375                 :                *iv,
     376                 :                *res;
     377                 :     text       *type;
     378                 :     PX_Combo   *c;
     379                 :     unsigned    dlen,
     380                 :                 klen,
     381                 :                 rlen,
     382                 :                 ivlen;
     383                 : 
     384 GIC           6 :     type = PG_GETARG_TEXT_PP(3);
     385               6 :     c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
     386 ECB             : 
     387 CBC           6 :     data = PG_GETARG_BYTEA_PP(0);
     388 GIC           6 :     key = PG_GETARG_BYTEA_PP(1);
     389 CBC           6 :     iv = PG_GETARG_BYTEA_PP(2);
     390               6 :     dlen = VARSIZE_ANY_EXHDR(data);
     391               6 :     klen = VARSIZE_ANY_EXHDR(key);
     392               6 :     ivlen = VARSIZE_ANY_EXHDR(iv);
     393 ECB             : 
     394 CBC           6 :     rlen = px_combo_decrypt_len(c, dlen);
     395 GIC           6 :     res = palloc(VARHDRSZ + rlen);
     396 ECB             : 
     397 CBC           6 :     err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen,
     398                 :                         (uint8 *) VARDATA_ANY(iv), ivlen);
     399               6 :     if (!err)
     400 GIC           6 :         err = px_combo_decrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
     401 ECB             :                                (uint8 *) VARDATA(res), &rlen);
     402                 : 
     403 GIC           6 :     px_combo_free(c);
     404                 : 
     405 CBC           6 :     if (err)
     406 GIC           4 :         ereport(ERROR,
     407 ECB             :                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
     408                 :                  errmsg("decrypt_iv error: %s", px_strerror(err))));
     409                 : 
     410 GIC           2 :     SET_VARSIZE(res, VARHDRSZ + rlen);
     411                 : 
     412 CBC           2 :     PG_FREE_IF_COPY(data, 0);
     413 GIC           2 :     PG_FREE_IF_COPY(key, 1);
     414 CBC           2 :     PG_FREE_IF_COPY(iv, 2);
     415               2 :     PG_FREE_IF_COPY(type, 3);
     416 ECB             : 
     417 CBC           2 :     PG_RETURN_BYTEA_P(res);
     418                 : }
     419 ECB             : 
     420                 : /* SQL function: pg_random_bytes(int4) returns bytea */
     421 GIC           1 : PG_FUNCTION_INFO_V1(pg_random_bytes);
     422                 : 
     423 ECB             : Datum
     424 UIC           0 : pg_random_bytes(PG_FUNCTION_ARGS)
     425                 : {
     426 UBC           0 :     int         len = PG_GETARG_INT32(0);
     427                 :     bytea      *res;
     428 EUB             : 
     429 UIC           0 :     if (len < 1 || len > 1024)
     430               0 :         ereport(ERROR,
     431 EUB             :                 (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
     432                 :                  errmsg("Length not in range")));
     433                 : 
     434 UIC           0 :     res = palloc(VARHDRSZ + len);
     435               0 :     SET_VARSIZE(res, VARHDRSZ + len);
     436 EUB             : 
     437                 :     /* generate result */
     438 UIC           0 :     if (!pg_strong_random(VARDATA(res), len))
     439               0 :         px_THROW_ERROR(PXE_NO_RANDOM);
     440 EUB             : 
     441 UBC           0 :     PG_RETURN_BYTEA_P(res);
     442                 : }
     443 EUB             : 
     444                 : /* SQL function: gen_random_uuid() returns uuid */
     445 GIC           1 : PG_FUNCTION_INFO_V1(pg_random_uuid);
     446                 : 
     447 ECB             : Datum
     448 UIC           0 : pg_random_uuid(PG_FUNCTION_ARGS)
     449                 : {
     450 EUB             :     /* redirect to built-in function */
     451 UIC           0 :     return gen_random_uuid(fcinfo);
     452                 : }
     453 EUB             : 
     454                 : static void *
     455 GIC         130 : find_provider(text *name,
     456                 :               PFN provider_lookup,
     457 ECB             :               const char *desc, int silent)
     458                 : {
     459                 :     void       *res;
     460                 :     char       *buf;
     461                 :     int         err;
     462                 : 
     463 GIC         130 :     buf = downcase_truncate_identifier(VARDATA_ANY(name),
     464             130 :                                        VARSIZE_ANY_EXHDR(name),
     465 ECB             :                                        false);
     466                 : 
     467 GIC         130 :     err = provider_lookup(buf, &res);
     468                 : 
     469 CBC         130 :     if (err && !silent)
     470 GIC           3 :         ereport(ERROR,
     471 ECB             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     472                 :                  errmsg("Cannot use \"%s\": %s", buf, px_strerror(err))));
     473                 : 
     474 GIC         127 :     pfree(buf);
     475                 : 
     476 CBC         127 :     return err ? NULL : res;
     477                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a