txt_db.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "internal/cryptlib.h"
  13. #include <openssl/buffer.h>
  14. #include <openssl/txt_db.h>
  15. #undef BUFSIZE
  16. #define BUFSIZE 512
  17. TXT_DB *TXT_DB_read(BIO *in, int num)
  18. {
  19. TXT_DB *ret = NULL;
  20. int esc = 0;
  21. long ln = 0;
  22. int i, add, n;
  23. int size = BUFSIZE;
  24. int offset = 0;
  25. char *p, *f;
  26. OPENSSL_STRING *pp;
  27. BUF_MEM *buf = NULL;
  28. if ((buf = BUF_MEM_new()) == NULL)
  29. goto err;
  30. if (!BUF_MEM_grow(buf, size))
  31. goto err;
  32. if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
  33. goto err;
  34. ret->num_fields = num;
  35. ret->index = NULL;
  36. ret->qual = NULL;
  37. if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL)
  38. goto err;
  39. if ((ret->index = OPENSSL_malloc(sizeof(*ret->index) * num)) == NULL)
  40. goto err;
  41. if ((ret->qual = OPENSSL_malloc(sizeof(*(ret->qual)) * num)) == NULL)
  42. goto err;
  43. for (i = 0; i < num; i++) {
  44. ret->index[i] = NULL;
  45. ret->qual[i] = NULL;
  46. }
  47. add = (num + 1) * sizeof(char *);
  48. buf->data[size - 1] = '\0';
  49. offset = 0;
  50. for (;;) {
  51. if (offset != 0) {
  52. size += BUFSIZE;
  53. if (!BUF_MEM_grow_clean(buf, size))
  54. goto err;
  55. }
  56. buf->data[offset] = '\0';
  57. BIO_gets(in, &(buf->data[offset]), size - offset);
  58. ln++;
  59. if (buf->data[offset] == '\0')
  60. break;
  61. if ((offset == 0) && (buf->data[0] == '#'))
  62. continue;
  63. i = strlen(&(buf->data[offset]));
  64. offset += i;
  65. if (buf->data[offset - 1] != '\n')
  66. continue;
  67. else {
  68. buf->data[offset - 1] = '\0'; /* blat the '\n' */
  69. if ((p = OPENSSL_malloc(add + offset)) == NULL)
  70. goto err;
  71. offset = 0;
  72. }
  73. pp = (char **)p;
  74. p += add;
  75. n = 0;
  76. pp[n++] = p;
  77. i = 0;
  78. f = buf->data;
  79. esc = 0;
  80. for (;;) {
  81. if (*f == '\0')
  82. break;
  83. if (*f == '\t') {
  84. if (esc)
  85. p--;
  86. else {
  87. *(p++) = '\0';
  88. f++;
  89. if (n >= num)
  90. break;
  91. pp[n++] = p;
  92. continue;
  93. }
  94. }
  95. esc = (*f == '\\');
  96. *(p++) = *(f++);
  97. }
  98. *(p++) = '\0';
  99. if ((n != num) || (*f != '\0')) {
  100. OPENSSL_free(pp);
  101. ret->error = DB_ERROR_WRONG_NUM_FIELDS;
  102. goto err;
  103. }
  104. pp[n] = p;
  105. if (!sk_OPENSSL_PSTRING_push(ret->data, pp)) {
  106. OPENSSL_free(pp);
  107. goto err;
  108. }
  109. }
  110. BUF_MEM_free(buf);
  111. return ret;
  112. err:
  113. BUF_MEM_free(buf);
  114. if (ret != NULL) {
  115. sk_OPENSSL_PSTRING_free(ret->data);
  116. OPENSSL_free(ret->index);
  117. OPENSSL_free(ret->qual);
  118. OPENSSL_free(ret);
  119. }
  120. return NULL;
  121. }
  122. OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
  123. OPENSSL_STRING *value)
  124. {
  125. OPENSSL_STRING *ret;
  126. LHASH_OF(OPENSSL_STRING) *lh;
  127. if (idx >= db->num_fields) {
  128. db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
  129. return NULL;
  130. }
  131. lh = db->index[idx];
  132. if (lh == NULL) {
  133. db->error = DB_ERROR_NO_INDEX;
  134. return NULL;
  135. }
  136. ret = lh_OPENSSL_STRING_retrieve(lh, value);
  137. db->error = DB_ERROR_OK;
  138. return ret;
  139. }
  140. int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
  141. OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp)
  142. {
  143. LHASH_OF(OPENSSL_STRING) *idx;
  144. OPENSSL_STRING *r, *k;
  145. int i, n;
  146. if (field >= db->num_fields) {
  147. db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
  148. return 0;
  149. }
  150. /* FIXME: we lose type checking at this point */
  151. if ((idx = (LHASH_OF(OPENSSL_STRING) *)OPENSSL_LH_new(hash, cmp)) == NULL) {
  152. db->error = DB_ERROR_MALLOC;
  153. return 0;
  154. }
  155. n = sk_OPENSSL_PSTRING_num(db->data);
  156. for (i = 0; i < n; i++) {
  157. r = sk_OPENSSL_PSTRING_value(db->data, i);
  158. if ((qual != NULL) && (qual(r) == 0))
  159. continue;
  160. if ((k = lh_OPENSSL_STRING_insert(idx, r)) != NULL) {
  161. db->error = DB_ERROR_INDEX_CLASH;
  162. db->arg1 = sk_OPENSSL_PSTRING_find(db->data, k);
  163. db->arg2 = i;
  164. lh_OPENSSL_STRING_free(idx);
  165. return 0;
  166. }
  167. if (lh_OPENSSL_STRING_retrieve(idx, r) == NULL) {
  168. db->error = DB_ERROR_MALLOC;
  169. lh_OPENSSL_STRING_free(idx);
  170. return 0;
  171. }
  172. }
  173. lh_OPENSSL_STRING_free(db->index[field]);
  174. db->index[field] = idx;
  175. db->qual[field] = qual;
  176. return 1;
  177. }
  178. long TXT_DB_write(BIO *out, TXT_DB *db)
  179. {
  180. long i, j, n, nn, l, tot = 0;
  181. char *p, **pp, *f;
  182. BUF_MEM *buf = NULL;
  183. long ret = -1;
  184. if ((buf = BUF_MEM_new()) == NULL)
  185. goto err;
  186. n = sk_OPENSSL_PSTRING_num(db->data);
  187. nn = db->num_fields;
  188. for (i = 0; i < n; i++) {
  189. pp = sk_OPENSSL_PSTRING_value(db->data, i);
  190. l = 0;
  191. for (j = 0; j < nn; j++) {
  192. if (pp[j] != NULL)
  193. l += strlen(pp[j]);
  194. }
  195. if (!BUF_MEM_grow_clean(buf, (int)(l * 2 + nn)))
  196. goto err;
  197. p = buf->data;
  198. for (j = 0; j < nn; j++) {
  199. f = pp[j];
  200. if (f != NULL)
  201. for (;;) {
  202. if (*f == '\0')
  203. break;
  204. if (*f == '\t')
  205. *(p++) = '\\';
  206. *(p++) = *(f++);
  207. }
  208. *(p++) = '\t';
  209. }
  210. p[-1] = '\n';
  211. j = p - buf->data;
  212. if (BIO_write(out, buf->data, (int)j) != j)
  213. goto err;
  214. tot += j;
  215. }
  216. ret = tot;
  217. err:
  218. BUF_MEM_free(buf);
  219. return ret;
  220. }
  221. int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
  222. {
  223. int i;
  224. OPENSSL_STRING *r;
  225. for (i = 0; i < db->num_fields; i++) {
  226. if (db->index[i] != NULL) {
  227. if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
  228. continue;
  229. r = lh_OPENSSL_STRING_retrieve(db->index[i], row);
  230. if (r != NULL) {
  231. db->error = DB_ERROR_INDEX_CLASH;
  232. db->arg1 = i;
  233. db->arg_row = r;
  234. goto err;
  235. }
  236. }
  237. }
  238. for (i = 0; i < db->num_fields; i++) {
  239. if (db->index[i] != NULL) {
  240. if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
  241. continue;
  242. (void)lh_OPENSSL_STRING_insert(db->index[i], row);
  243. if (lh_OPENSSL_STRING_retrieve(db->index[i], row) == NULL)
  244. goto err1;
  245. }
  246. }
  247. if (!sk_OPENSSL_PSTRING_push(db->data, row))
  248. goto err1;
  249. return 1;
  250. err1:
  251. db->error = DB_ERROR_MALLOC;
  252. while (i-- > 0) {
  253. if (db->index[i] != NULL) {
  254. if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
  255. continue;
  256. (void)lh_OPENSSL_STRING_delete(db->index[i], row);
  257. }
  258. }
  259. err:
  260. return 0;
  261. }
  262. void TXT_DB_free(TXT_DB *db)
  263. {
  264. int i, n;
  265. char **p, *max;
  266. if (db == NULL)
  267. return;
  268. if (db->index != NULL) {
  269. for (i = db->num_fields - 1; i >= 0; i--)
  270. lh_OPENSSL_STRING_free(db->index[i]);
  271. OPENSSL_free(db->index);
  272. }
  273. OPENSSL_free(db->qual);
  274. if (db->data != NULL) {
  275. for (i = sk_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) {
  276. /*
  277. * check if any 'fields' have been allocated from outside of the
  278. * initial block
  279. */
  280. p = sk_OPENSSL_PSTRING_value(db->data, i);
  281. max = p[db->num_fields]; /* last address */
  282. if (max == NULL) { /* new row */
  283. for (n = 0; n < db->num_fields; n++)
  284. OPENSSL_free(p[n]);
  285. } else {
  286. for (n = 0; n < db->num_fields; n++) {
  287. if (((p[n] < (char *)p) || (p[n] > max)))
  288. OPENSSL_free(p[n]);
  289. }
  290. }
  291. OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data, i));
  292. }
  293. sk_OPENSSL_PSTRING_free(db->data);
  294. }
  295. OPENSSL_free(db);
  296. }