blob: 374f68e72a7a429825d9b0b0e924c666b9589bee [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <stdio.h>
Lev Walkinb1107e62004-09-27 20:54:44 +00002#include <string.h>
Lev Walkind370e9f2006-03-16 10:03:35 +00003#include <stdlib.h>
Lev Walkinf15320b2004-06-03 03:38:44 +00004#include <sys/types.h>
5#include <sys/stat.h>
6#include <assert.h>
7#include <errno.h>
8
9#include "asn1parser.h"
10#include "asn1p_list.h"
11
12int asn1p_parse(void **param);
13
14void *asn1p__scan_bytes(const char *, int len);
15void *asn1p__delete_buffer(void *);
16void *asn1p_restart(FILE *);
17
18extern int asn1p_lineno;
19
20static int _asn1p_set_flags(enum asn1p_flags flags);
Lev Walkin070a52d2004-08-22 03:19:54 +000021static int _asn1p_fix_modules(asn1p_t *a, const char *fname);
Lev Walkinf15320b2004-06-03 03:38:44 +000022
23/*
24 * Parse the given buffer.
25 */
26asn1p_t *
27asn1p_parse_buffer(const char *buffer, int size /* = -1 */, enum asn1p_flags flags) {
28 asn1p_t *a = 0;
29 void *ap;
30 void *ybuf;
31 int ret;
32
33 if(_asn1p_set_flags(flags)) {
34 /* EINVAL */
35 return 0;
36 }
37
38 if(size < 0)
Lev Walkin4efbfb72005-02-25 14:20:30 +000039 size = (int)strlen(buffer);
Lev Walkinf15320b2004-06-03 03:38:44 +000040
Lev Walkind523ea42017-09-06 22:15:08 -070041 asn1p_parse_debug_filename = "<stdin>";
Lev Walkinf15320b2004-06-03 03:38:44 +000042 ybuf = asn1p__scan_bytes(buffer, size);
Lev Walkind523ea42017-09-06 22:15:08 -070043 asn1p_parse_debug_filename = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000044 if(!ybuf) {
45 assert(ybuf);
46 return 0;
47 }
48
49 asn1p_lineno = 1;
50
51 ap = (void *)&a;
52 ret = asn1p_parse(ap);
53
54 asn1p__delete_buffer(ybuf);
55
56 if(ret == 0) {
57 assert(a);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +080058 if(_asn1p_fix_modules(a, "-")) {
59 asn1p_delete(a);
Lev Walkinf15320b2004-06-03 03:38:44 +000060 return NULL; /* FIXME: destroy (a) */
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +080061 }
Lev Walkin4cd43042005-04-08 10:14:30 +000062 } else if(a) {
Lev Walkin9b5df842006-09-12 04:21:30 +000063 asn1p_delete(a);
Lev Walkin4cd43042005-04-08 10:14:30 +000064 a = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000065 }
66
67 return a;
68}
69
70
71/*
72 * Parse the file identified by its name.
73 */
74asn1p_t *
75asn1p_parse_file(const char *filename, enum asn1p_flags flags) {
Lev Walkin93659562010-11-20 09:47:13 -080076#ifndef _WIN32
Lev Walkinf15320b2004-06-03 03:38:44 +000077 struct stat sb;
Lev Walkin4efbfb72005-02-25 14:20:30 +000078#endif
Lev Walkinf15320b2004-06-03 03:38:44 +000079 asn1p_t *a = 0;
80 void *ap;
81 FILE *fp;
82 int ret;
83
84 if(_asn1p_set_flags(flags)) {
85 /* EINVAL */
86 return 0;
87 }
88
89 fp = fopen(filename, "r");
90 if(fp == NULL) {
91 perror(filename);
92 return NULL;
93 }
94
Lev Walkin93659562010-11-20 09:47:13 -080095#ifndef _WIN32
Lev Walkinf15320b2004-06-03 03:38:44 +000096 if(fstat(fileno(fp), &sb)
97 || !S_ISREG(sb.st_mode)) {
98 fclose(fp);
99 fprintf(stderr, "%s file not recognized: Bad file format\n",
100 filename);
101 errno = EINVAL;
102 return NULL;
103 }
Lev Walkin93659562010-11-20 09:47:13 -0800104#endif /* _WIN32 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000105
106 asn1p_lineno = 1;
107
108 asn1p_restart(fp);
109
110 ap = (void *)&a;
Lev Walkind523ea42017-09-06 22:15:08 -0700111 asn1p_parse_debug_filename = filename;
Lev Walkinf15320b2004-06-03 03:38:44 +0000112 ret = asn1p_parse(ap);
Lev Walkind523ea42017-09-06 22:15:08 -0700113 asn1p_parse_debug_filename = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000114
115 fclose(fp);
116
117 if(ret == 0) {
118 assert(a);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800119 if(_asn1p_fix_modules(a, filename)) {
120 asn1p_delete(a);
Lev Walkinf15320b2004-06-03 03:38:44 +0000121 return NULL; /* FIXME: destroy (a) */
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800122 }
Lev Walkin4cd43042005-04-08 10:14:30 +0000123 } else if(a) {
Lev Walkin9b5df842006-09-12 04:21:30 +0000124 asn1p_delete(a);
Lev Walkinc16cf432005-04-08 10:12:40 +0000125 a = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000126 }
127
128 return a;
129}
130
131extern int asn1p_lexer_types_year;
132extern int asn1p_lexer_constructs_year;
133extern int asn1p__flex_debug;
134
135static int
136_asn1p_set_flags(enum asn1p_flags flags) {
137
138 asn1p_lexer_types_year = 0;
139 asn1p_lexer_constructs_year = 0;
140 asn1p__flex_debug = 0;
141
142 /*
143 * Enable debugging in lexer.
144 */
145 if(flags & A1P_LEXER_DEBUG) {
146 flags &= ~A1P_LEXER_DEBUG;
147 asn1p__flex_debug = 1;
148 }
149
150 /*
Lev Walkinf15320b2004-06-03 03:38:44 +0000151 * Check that we haven't missed an unknown flag.
152 */
153 if(flags) {
154 errno = EINVAL;
155 return -1;
156 }
157
158 return 0;
159}
160
161static int
Lev Walkin070a52d2004-08-22 03:19:54 +0000162_asn1p_fix_modules(asn1p_t *a, const char *fname) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000163 asn1p_module_t *mod;
164 TQ_FOR(mod, &(a->modules), mod_next) {
Lev Walkinb1107e62004-09-27 20:54:44 +0000165 mod->source_file_name = strdup(fname);
Lev Walkinf15320b2004-06-03 03:38:44 +0000166 if(mod->source_file_name == NULL)
167 return -1;
Lev Walkina9532f42006-09-17 04:52:50 +0000168 mod->asn1p = a;
Lev Walkinf15320b2004-06-03 03:38:44 +0000169 }
170 return 0;
171}