diff options
| author | djm <> | 2010-10-01 22:59:01 +0000 |
|---|---|---|
| committer | djm <> | 2010-10-01 22:59:01 +0000 |
| commit | 8922d4bc4a8b8893d72a48deb2cdf58215f98505 (patch) | |
| tree | 939b752540947d33507b3acc48d76a8bfb7c3dc3 /src/lib/libcrypto/objects/obj_dat.c | |
| parent | 76262f7bf9262f965142b1b2b2105cb279c5c696 (diff) | |
| download | openbsd-8922d4bc4a8b8893d72a48deb2cdf58215f98505.tar.gz openbsd-8922d4bc4a8b8893d72a48deb2cdf58215f98505.tar.bz2 openbsd-8922d4bc4a8b8893d72a48deb2cdf58215f98505.zip | |
resolve conflicts, fix local changes
Diffstat (limited to 'src/lib/libcrypto/objects/obj_dat.c')
| -rw-r--r-- | src/lib/libcrypto/objects/obj_dat.c | 180 |
1 files changed, 102 insertions, 78 deletions
diff --git a/src/lib/libcrypto/objects/obj_dat.c b/src/lib/libcrypto/objects/obj_dat.c index 7fd7433241..8a342ba3eb 100644 --- a/src/lib/libcrypto/objects/obj_dat.c +++ b/src/lib/libcrypto/objects/obj_dat.c | |||
| @@ -74,16 +74,17 @@ | |||
| 74 | #define NUM_SN 0 | 74 | #define NUM_SN 0 |
| 75 | #define NUM_LN 0 | 75 | #define NUM_LN 0 |
| 76 | #define NUM_OBJ 0 | 76 | #define NUM_OBJ 0 |
| 77 | static unsigned char lvalues[1]; | 77 | static const unsigned char lvalues[1]; |
| 78 | static ASN1_OBJECT nid_objs[1]; | 78 | static const ASN1_OBJECT nid_objs[1]; |
| 79 | static ASN1_OBJECT *sn_objs[1]; | 79 | static const unsigned int sn_objs[1]; |
| 80 | static ASN1_OBJECT *ln_objs[1]; | 80 | static const unsigned int ln_objs[1]; |
| 81 | static ASN1_OBJECT *obj_objs[1]; | 81 | static const unsigned int obj_objs[1]; |
| 82 | #endif | 82 | #endif |
| 83 | 83 | ||
| 84 | static int sn_cmp(const void *a, const void *b); | 84 | DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); |
| 85 | static int ln_cmp(const void *a, const void *b); | 85 | DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); |
| 86 | static int obj_cmp(const void *a, const void *b); | 86 | DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); |
| 87 | |||
| 87 | #define ADDED_DATA 0 | 88 | #define ADDED_DATA 0 |
| 88 | #define ADDED_SNAME 1 | 89 | #define ADDED_SNAME 1 |
| 89 | #define ADDED_LNAME 2 | 90 | #define ADDED_LNAME 2 |
| @@ -94,30 +95,27 @@ typedef struct added_obj_st | |||
| 94 | int type; | 95 | int type; |
| 95 | ASN1_OBJECT *obj; | 96 | ASN1_OBJECT *obj; |
| 96 | } ADDED_OBJ; | 97 | } ADDED_OBJ; |
| 98 | DECLARE_LHASH_OF(ADDED_OBJ); | ||
| 97 | 99 | ||
| 98 | static int new_nid=NUM_NID; | 100 | static int new_nid=NUM_NID; |
| 99 | static LHASH *added=NULL; | 101 | static LHASH_OF(ADDED_OBJ) *added=NULL; |
| 100 | 102 | ||
| 101 | static int sn_cmp(const void *a, const void *b) | 103 | static int sn_cmp(const ASN1_OBJECT * const *a, const unsigned int *b) |
| 102 | { | 104 | { return(strcmp((*a)->sn,nid_objs[*b].sn)); } |
| 103 | const ASN1_OBJECT * const *ap = a, * const *bp = b; | ||
| 104 | return(strcmp((*ap)->sn,(*bp)->sn)); | ||
| 105 | } | ||
| 106 | 105 | ||
| 107 | static int ln_cmp(const void *a, const void *b) | 106 | IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); |
| 108 | { | 107 | |
| 109 | const ASN1_OBJECT * const *ap = a, * const *bp = b; | 108 | static int ln_cmp(const ASN1_OBJECT * const *a, const unsigned int *b) |
| 110 | return(strcmp((*ap)->ln,(*bp)->ln)); | 109 | { return(strcmp((*a)->ln,nid_objs[*b].ln)); } |
| 111 | } | ||
| 112 | 110 | ||
| 113 | /* static unsigned long add_hash(ADDED_OBJ *ca) */ | 111 | IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); |
| 114 | static unsigned long add_hash(const void *ca_void) | 112 | |
| 113 | static unsigned long added_obj_hash(const ADDED_OBJ *ca) | ||
| 115 | { | 114 | { |
| 116 | const ASN1_OBJECT *a; | 115 | const ASN1_OBJECT *a; |
| 117 | int i; | 116 | int i; |
| 118 | unsigned long ret=0; | 117 | unsigned long ret=0; |
| 119 | unsigned char *p; | 118 | unsigned char *p; |
| 120 | const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void; | ||
| 121 | 119 | ||
| 122 | a=ca->obj; | 120 | a=ca->obj; |
| 123 | switch (ca->type) | 121 | switch (ca->type) |
| @@ -145,14 +143,12 @@ static unsigned long add_hash(const void *ca_void) | |||
| 145 | ret|=ca->type<<30L; | 143 | ret|=ca->type<<30L; |
| 146 | return(ret); | 144 | return(ret); |
| 147 | } | 145 | } |
| 146 | static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ) | ||
| 148 | 147 | ||
| 149 | /* static int add_cmp(ADDED_OBJ *ca, ADDED_OBJ *cb) */ | 148 | static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) |
| 150 | static int add_cmp(const void *ca_void, const void *cb_void) | ||
| 151 | { | 149 | { |
| 152 | ASN1_OBJECT *a,*b; | 150 | ASN1_OBJECT *a,*b; |
| 153 | int i; | 151 | int i; |
| 154 | const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void; | ||
| 155 | const ADDED_OBJ *cb = (const ADDED_OBJ *)cb_void; | ||
| 156 | 152 | ||
| 157 | i=ca->type-cb->type; | 153 | i=ca->type-cb->type; |
| 158 | if (i) return(i); | 154 | if (i) return(i); |
| @@ -179,15 +175,16 @@ static int add_cmp(const void *ca_void, const void *cb_void) | |||
| 179 | return 0; | 175 | return 0; |
| 180 | } | 176 | } |
| 181 | } | 177 | } |
| 178 | static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ) | ||
| 182 | 179 | ||
| 183 | static int init_added(void) | 180 | static int init_added(void) |
| 184 | { | 181 | { |
| 185 | if (added != NULL) return(1); | 182 | if (added != NULL) return(1); |
| 186 | added=lh_new(add_hash,add_cmp); | 183 | added=lh_ADDED_OBJ_new(); |
| 187 | return(added != NULL); | 184 | return(added != NULL); |
| 188 | } | 185 | } |
| 189 | 186 | ||
| 190 | static void cleanup1(ADDED_OBJ *a) | 187 | static void cleanup1_doall(ADDED_OBJ *a) |
| 191 | { | 188 | { |
| 192 | a->obj->nid=0; | 189 | a->obj->nid=0; |
| 193 | a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC| | 190 | a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC| |
| @@ -195,28 +192,46 @@ static void cleanup1(ADDED_OBJ *a) | |||
| 195 | ASN1_OBJECT_FLAG_DYNAMIC_DATA; | 192 | ASN1_OBJECT_FLAG_DYNAMIC_DATA; |
| 196 | } | 193 | } |
| 197 | 194 | ||
| 198 | static void cleanup2(ADDED_OBJ *a) | 195 | static void cleanup2_doall(ADDED_OBJ *a) |
| 199 | { a->obj->nid++; } | 196 | { a->obj->nid++; } |
| 200 | 197 | ||
| 201 | static void cleanup3(ADDED_OBJ *a) | 198 | static void cleanup3_doall(ADDED_OBJ *a) |
| 202 | { | 199 | { |
| 203 | if (--a->obj->nid == 0) | 200 | if (--a->obj->nid == 0) |
| 204 | ASN1_OBJECT_free(a->obj); | 201 | ASN1_OBJECT_free(a->obj); |
| 205 | OPENSSL_free(a); | 202 | OPENSSL_free(a); |
| 206 | } | 203 | } |
| 207 | 204 | ||
| 208 | static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *) | 205 | static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ) |
| 209 | static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *) | 206 | static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ) |
| 210 | static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *) | 207 | static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ) |
| 208 | |||
| 209 | /* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting | ||
| 210 | * to use freed up OIDs. If neccessary the actual freeing up of OIDs is | ||
| 211 | * delayed. | ||
| 212 | */ | ||
| 213 | |||
| 214 | int obj_cleanup_defer = 0; | ||
| 215 | |||
| 216 | void check_defer(int nid) | ||
| 217 | { | ||
| 218 | if (!obj_cleanup_defer && nid >= NUM_NID) | ||
| 219 | obj_cleanup_defer = 1; | ||
| 220 | } | ||
| 211 | 221 | ||
| 212 | void OBJ_cleanup(void) | 222 | void OBJ_cleanup(void) |
| 213 | { | 223 | { |
| 224 | if (obj_cleanup_defer) | ||
| 225 | { | ||
| 226 | obj_cleanup_defer = 2; | ||
| 227 | return ; | ||
| 228 | } | ||
| 214 | if (added == NULL) return; | 229 | if (added == NULL) return; |
| 215 | added->down_load=0; | 230 | lh_ADDED_OBJ_down_load(added) = 0; |
| 216 | lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ | 231 | lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ |
| 217 | lh_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */ | 232 | lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */ |
| 218 | lh_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */ | 233 | lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */ |
| 219 | lh_free(added); | 234 | lh_ADDED_OBJ_free(added); |
| 220 | added=NULL; | 235 | added=NULL; |
| 221 | } | 236 | } |
| 222 | 237 | ||
| @@ -252,7 +267,7 @@ int OBJ_add_object(const ASN1_OBJECT *obj) | |||
| 252 | { | 267 | { |
| 253 | ao[i]->type=i; | 268 | ao[i]->type=i; |
| 254 | ao[i]->obj=o; | 269 | ao[i]->obj=o; |
| 255 | aop=(ADDED_OBJ *)lh_insert(added,ao[i]); | 270 | aop=lh_ADDED_OBJ_insert(added,ao[i]); |
| 256 | /* memory leak, buit should not normally matter */ | 271 | /* memory leak, buit should not normally matter */ |
| 257 | if (aop != NULL) | 272 | if (aop != NULL) |
| 258 | OPENSSL_free(aop); | 273 | OPENSSL_free(aop); |
| @@ -292,7 +307,7 @@ ASN1_OBJECT *OBJ_nid2obj(int n) | |||
| 292 | ad.type=ADDED_NID; | 307 | ad.type=ADDED_NID; |
| 293 | ad.obj= &ob; | 308 | ad.obj= &ob; |
| 294 | ob.nid=n; | 309 | ob.nid=n; |
| 295 | adp=(ADDED_OBJ *)lh_retrieve(added,&ad); | 310 | adp=lh_ADDED_OBJ_retrieve(added,&ad); |
| 296 | if (adp != NULL) | 311 | if (adp != NULL) |
| 297 | return(adp->obj); | 312 | return(adp->obj); |
| 298 | else | 313 | else |
| @@ -324,7 +339,7 @@ const char *OBJ_nid2sn(int n) | |||
| 324 | ad.type=ADDED_NID; | 339 | ad.type=ADDED_NID; |
| 325 | ad.obj= &ob; | 340 | ad.obj= &ob; |
| 326 | ob.nid=n; | 341 | ob.nid=n; |
| 327 | adp=(ADDED_OBJ *)lh_retrieve(added,&ad); | 342 | adp=lh_ADDED_OBJ_retrieve(added,&ad); |
| 328 | if (adp != NULL) | 343 | if (adp != NULL) |
| 329 | return(adp->obj->sn); | 344 | return(adp->obj->sn); |
| 330 | else | 345 | else |
| @@ -356,7 +371,7 @@ const char *OBJ_nid2ln(int n) | |||
| 356 | ad.type=ADDED_NID; | 371 | ad.type=ADDED_NID; |
| 357 | ad.obj= &ob; | 372 | ad.obj= &ob; |
| 358 | ob.nid=n; | 373 | ob.nid=n; |
| 359 | adp=(ADDED_OBJ *)lh_retrieve(added,&ad); | 374 | adp=lh_ADDED_OBJ_retrieve(added,&ad); |
| 360 | if (adp != NULL) | 375 | if (adp != NULL) |
| 361 | return(adp->obj->ln); | 376 | return(adp->obj->ln); |
| 362 | else | 377 | else |
| @@ -367,9 +382,22 @@ const char *OBJ_nid2ln(int n) | |||
| 367 | } | 382 | } |
| 368 | } | 383 | } |
| 369 | 384 | ||
| 385 | static int obj_cmp(const ASN1_OBJECT * const *ap, const unsigned int *bp) | ||
| 386 | { | ||
| 387 | int j; | ||
| 388 | const ASN1_OBJECT *a= *ap; | ||
| 389 | const ASN1_OBJECT *b= &nid_objs[*bp]; | ||
| 390 | |||
| 391 | j=(a->length - b->length); | ||
| 392 | if (j) return(j); | ||
| 393 | return(memcmp(a->data,b->data,a->length)); | ||
| 394 | } | ||
| 395 | |||
| 396 | IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); | ||
| 397 | |||
| 370 | int OBJ_obj2nid(const ASN1_OBJECT *a) | 398 | int OBJ_obj2nid(const ASN1_OBJECT *a) |
| 371 | { | 399 | { |
| 372 | ASN1_OBJECT **op; | 400 | const unsigned int *op; |
| 373 | ADDED_OBJ ad,*adp; | 401 | ADDED_OBJ ad,*adp; |
| 374 | 402 | ||
| 375 | if (a == NULL) | 403 | if (a == NULL) |
| @@ -381,14 +409,13 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) | |||
| 381 | { | 409 | { |
| 382 | ad.type=ADDED_DATA; | 410 | ad.type=ADDED_DATA; |
| 383 | ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */ | 411 | ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */ |
| 384 | adp=(ADDED_OBJ *)lh_retrieve(added,&ad); | 412 | adp=lh_ADDED_OBJ_retrieve(added,&ad); |
| 385 | if (adp != NULL) return (adp->obj->nid); | 413 | if (adp != NULL) return (adp->obj->nid); |
| 386 | } | 414 | } |
| 387 | op=(ASN1_OBJECT **)OBJ_bsearch((const char *)&a,(const char *)obj_objs, | 415 | op=OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); |
| 388 | NUM_OBJ, sizeof(ASN1_OBJECT *),obj_cmp); | ||
| 389 | if (op == NULL) | 416 | if (op == NULL) |
| 390 | return(NID_undef); | 417 | return(NID_undef); |
| 391 | return((*op)->nid); | 418 | return(nid_objs[*op].nid); |
| 392 | } | 419 | } |
| 393 | 420 | ||
| 394 | /* Convert an object name into an ASN1_OBJECT | 421 | /* Convert an object name into an ASN1_OBJECT |
| @@ -441,7 +468,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) | |||
| 441 | int i,n=0,len,nid, first, use_bn; | 468 | int i,n=0,len,nid, first, use_bn; |
| 442 | BIGNUM *bl; | 469 | BIGNUM *bl; |
| 443 | unsigned long l; | 470 | unsigned long l; |
| 444 | unsigned char *p; | 471 | const unsigned char *p; |
| 445 | char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2]; | 472 | char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2]; |
| 446 | 473 | ||
| 447 | if ((a == NULL) || (a->data == NULL)) { | 474 | if ((a == NULL) || (a->data == NULL)) { |
| @@ -456,10 +483,13 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) | |||
| 456 | s=OBJ_nid2ln(nid); | 483 | s=OBJ_nid2ln(nid); |
| 457 | if (s == NULL) | 484 | if (s == NULL) |
| 458 | s=OBJ_nid2sn(nid); | 485 | s=OBJ_nid2sn(nid); |
| 459 | if (buf) | 486 | if (s) |
| 460 | BUF_strlcpy(buf,s,buf_len); | 487 | { |
| 461 | n=strlen(s); | 488 | if (buf) |
| 462 | return n; | 489 | BUF_strlcpy(buf,s,buf_len); |
| 490 | n=strlen(s); | ||
| 491 | return n; | ||
| 492 | } | ||
| 463 | } | 493 | } |
| 464 | 494 | ||
| 465 | 495 | ||
| @@ -607,62 +637,56 @@ int OBJ_txt2nid(const char *s) | |||
| 607 | 637 | ||
| 608 | int OBJ_ln2nid(const char *s) | 638 | int OBJ_ln2nid(const char *s) |
| 609 | { | 639 | { |
| 610 | ASN1_OBJECT o,*oo= &o,**op; | 640 | ASN1_OBJECT o; |
| 641 | const ASN1_OBJECT *oo= &o; | ||
| 611 | ADDED_OBJ ad,*adp; | 642 | ADDED_OBJ ad,*adp; |
| 643 | const unsigned int *op; | ||
| 612 | 644 | ||
| 613 | o.ln=s; | 645 | o.ln=s; |
| 614 | if (added != NULL) | 646 | if (added != NULL) |
| 615 | { | 647 | { |
| 616 | ad.type=ADDED_LNAME; | 648 | ad.type=ADDED_LNAME; |
| 617 | ad.obj= &o; | 649 | ad.obj= &o; |
| 618 | adp=(ADDED_OBJ *)lh_retrieve(added,&ad); | 650 | adp=lh_ADDED_OBJ_retrieve(added,&ad); |
| 619 | if (adp != NULL) return (adp->obj->nid); | 651 | if (adp != NULL) return (adp->obj->nid); |
| 620 | } | 652 | } |
| 621 | op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs, NUM_LN, | 653 | op=OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); |
| 622 | sizeof(ASN1_OBJECT *),ln_cmp); | ||
| 623 | if (op == NULL) return(NID_undef); | 654 | if (op == NULL) return(NID_undef); |
| 624 | return((*op)->nid); | 655 | return(nid_objs[*op].nid); |
| 625 | } | 656 | } |
| 626 | 657 | ||
| 627 | int OBJ_sn2nid(const char *s) | 658 | int OBJ_sn2nid(const char *s) |
| 628 | { | 659 | { |
| 629 | ASN1_OBJECT o,*oo= &o,**op; | 660 | ASN1_OBJECT o; |
| 661 | const ASN1_OBJECT *oo= &o; | ||
| 630 | ADDED_OBJ ad,*adp; | 662 | ADDED_OBJ ad,*adp; |
| 663 | const unsigned int *op; | ||
| 631 | 664 | ||
| 632 | o.sn=s; | 665 | o.sn=s; |
| 633 | if (added != NULL) | 666 | if (added != NULL) |
| 634 | { | 667 | { |
| 635 | ad.type=ADDED_SNAME; | 668 | ad.type=ADDED_SNAME; |
| 636 | ad.obj= &o; | 669 | ad.obj= &o; |
| 637 | adp=(ADDED_OBJ *)lh_retrieve(added,&ad); | 670 | adp=lh_ADDED_OBJ_retrieve(added,&ad); |
| 638 | if (adp != NULL) return (adp->obj->nid); | 671 | if (adp != NULL) return (adp->obj->nid); |
| 639 | } | 672 | } |
| 640 | op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)sn_objs,NUM_SN, | 673 | op=OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); |
| 641 | sizeof(ASN1_OBJECT *),sn_cmp); | ||
| 642 | if (op == NULL) return(NID_undef); | 674 | if (op == NULL) return(NID_undef); |
| 643 | return((*op)->nid); | 675 | return(nid_objs[*op].nid); |
| 644 | } | 676 | } |
| 645 | 677 | ||
| 646 | static int obj_cmp(const void *ap, const void *bp) | 678 | const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, |
| 647 | { | 679 | int (*cmp)(const void *, const void *)) |
| 648 | int j; | ||
| 649 | const ASN1_OBJECT *a= *(ASN1_OBJECT * const *)ap; | ||
| 650 | const ASN1_OBJECT *b= *(ASN1_OBJECT * const *)bp; | ||
| 651 | |||
| 652 | j=(a->length - b->length); | ||
| 653 | if (j) return(j); | ||
| 654 | return(memcmp(a->data,b->data,a->length)); | ||
| 655 | } | ||
| 656 | |||
| 657 | const char *OBJ_bsearch(const char *key, const char *base, int num, int size, | ||
| 658 | int (*cmp)(const void *, const void *)) | ||
| 659 | { | 680 | { |
| 660 | return OBJ_bsearch_ex(key, base, num, size, cmp, 0); | 681 | return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); |
| 661 | } | 682 | } |
| 662 | 683 | ||
| 663 | const char *OBJ_bsearch_ex(const char *key, const char *base, int num, | 684 | const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, |
| 664 | int size, int (*cmp)(const void *, const void *), int flags) | 685 | int size, |
| 686 | int (*cmp)(const void *, const void *), | ||
| 687 | int flags) | ||
| 665 | { | 688 | { |
| 689 | const char *base=base_; | ||
| 666 | int l,h,i=0,c=0; | 690 | int l,h,i=0,c=0; |
| 667 | const char *p = NULL; | 691 | const char *p = NULL; |
| 668 | 692 | ||
