blob: fcc59b19d015a6ad7e237a08d12669d6342a8128 [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 *
Lev Walkinbe518fa2017-09-07 02:05:28 -070027asn1p_parse_buffer(const char *buffer, int size /* = -1 */, const char *debug_filename, int initial_lineno, enum asn1p_flags flags) {
Lev Walkinf15320b2004-06-03 03:38:44 +000028 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
41 ybuf = asn1p__scan_bytes(buffer, size);
42 if(!ybuf) {
43 assert(ybuf);
44 return 0;
45 }
46
Lev Walkinbe518fa2017-09-07 02:05:28 -070047 asn1p_lineno = initial_lineno;
Lev Walkinf15320b2004-06-03 03:38:44 +000048
49 ap = (void *)&a;
Lev Walkinbe518fa2017-09-07 02:05:28 -070050 asn1p_parse_debug_filename = debug_filename;
Lev Walkinf15320b2004-06-03 03:38:44 +000051 ret = asn1p_parse(ap);
Lev Walkinbe518fa2017-09-07 02:05:28 -070052 asn1p_parse_debug_filename = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000053
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;
Lev Walkinbe518fa2017-09-07 02:05:28 -0700133extern int asn1p_lexer_extended_values;
Lev Walkinf15320b2004-06-03 03:38:44 +0000134extern int asn1p__flex_debug;
Lev Walkin0c686452017-09-07 22:59:36 -0700135extern int asn1p_debug;
Lev Walkinf15320b2004-06-03 03:38:44 +0000136
137static int
138_asn1p_set_flags(enum asn1p_flags flags) {
139
140 asn1p_lexer_types_year = 0;
141 asn1p_lexer_constructs_year = 0;
142 asn1p__flex_debug = 0;
Lev Walkin0c686452017-09-07 22:59:36 -0700143 asn1p_debug = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000144
Lev Walkin0c686452017-09-07 22:59:36 -0700145 if(flags & A1P_DEBUG_LEXER) {
146 flags &= ~A1P_DEBUG_LEXER;
Lev Walkinf15320b2004-06-03 03:38:44 +0000147 asn1p__flex_debug = 1;
Lev Walkinbe518fa2017-09-07 02:05:28 -0700148 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000149
Lev Walkin0c686452017-09-07 22:59:36 -0700150 if(flags & A1P_DEBUG_PARSER) {
151 flags &= ~A1P_DEBUG_PARSER;
152 asn1p_debug = 1;
153 }
154
Lev Walkinbe518fa2017-09-07 02:05:28 -0700155 if(flags & A1P_EXTENDED_VALUES) {
156 flags &= ~A1P_EXTENDED_VALUES;
157 asn1p_lexer_extended_values = 1;
158 } else {
159 asn1p_lexer_extended_values = 0;
160 }
161
162 /*
Lev Walkinf15320b2004-06-03 03:38:44 +0000163 * Check that we haven't missed an unknown flag.
164 */
165 if(flags) {
166 errno = EINVAL;
167 return -1;
168 }
169
170 return 0;
171}
172
173static int
Lev Walkin070a52d2004-08-22 03:19:54 +0000174_asn1p_fix_modules(asn1p_t *a, const char *fname) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000175 asn1p_module_t *mod;
176 TQ_FOR(mod, &(a->modules), mod_next) {
Lev Walkinb1107e62004-09-27 20:54:44 +0000177 mod->source_file_name = strdup(fname);
Lev Walkinf15320b2004-06-03 03:38:44 +0000178 if(mod->source_file_name == NULL)
179 return -1;
Lev Walkina9532f42006-09-17 04:52:50 +0000180 mod->asn1p = a;
Lev Walkinf15320b2004-06-03 03:38:44 +0000181 }
182 return 0;
183}