⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn1fix_retrieve.c

📁 RSA加密/解密算法源码 asn1c-0.9.12
💻 C
字号:
#include "asn1fix_internal.h"static asn1p_expr_t *asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, int type_or_value);static int asn1f_compatible_with_exports(arg_t *arg, asn1p_module_t *mod, const char *name);/* * Lookup a child by its name. */asn1p_expr_t *asn1f_lookup_child(asn1p_expr_t *tc, const char *name) {	asn1p_expr_t *child_tc;	TQ_FOR(child_tc, &(tc->members), next) {		if(child_tc->Identifier		&& strcmp(child_tc->Identifier, name) == 0) {			return child_tc;		}	}	errno = ESRCH;	return NULL;}asn1p_module_t *asn1f_lookup_in_imports(arg_t *arg, asn1p_module_t *mod, const char *name) {	asn1p_xports_t *xp;	asn1p_expr_t *tc;	/*	 * Search in which exactly module this name is defined.	 */	TQ_FOR(xp, &(mod->imports), xp_next) {		TQ_FOR(tc, &(xp->members), next) {			if(strcmp(name, tc->Identifier) == 0)				break;		}		if(tc) break;	}	if(xp == NULL) {		errno = ESRCH;		return NULL;	}	/*	 * Okay, right now we have a module name and, hopefully, an OID.	 * Search the arg->asn for the specified module.	 */	mod = asn1f_lookup_module(arg, xp->from, xp->from_oid);	if(mod == NULL) {		/* ENOENT/ETOOMANYREFS */		return NULL;	}	/*	 * Check that the EXPORTS section of this module contains	 * the symbol we care about, or it is EXPORTS ALL.	 */	if(asn1f_compatible_with_exports(arg, mod, name)) {		errno = EPERM;		return NULL;	}	return mod;}asn1p_module_t *asn1f_lookup_module(arg_t *arg, const char *module_name, asn1p_oid_t *oid) {	asn1p_module_t *mod;	assert(module_name);	/*	 * If OID is given, the module_name is unused.	 * If OID is not given, the module_name may mean	 * either the real module's name, or the symbol which is the	 * result of renaming. Check this first.	 */	if(oid == 0) {		asn1p_xports_t *xp;		/*		 * Check inside the IMPORTS section for possible renaming.		 * Renaming practically means that a module_name is mentioned		 * somewhere in the IMPORTS section AND OID is given.		 */		TQ_FOR(xp, &(arg->mod->imports), xp_next) {			if(strcmp(module_name, xp->from))				continue;			if(oid) {				FATAL("Ambiguous reference: "					"%s "					"matches several modules",					module_name);				errno = ETOOMANYREFS;				return NULL;			}			/*			 * Yes, there is a renaming.			 * Make lookup use OID instead.			 */			oid = xp->from_oid;		}	}	/*	 * Perform lookup using OID or module_name.	 */	TQ_FOR(mod, &(arg->asn->modules), mod_next) {		if(oid) {			if(mod->module_oid) {				if(asn1p_oid_compare(oid,					mod->module_oid)) {					continue;				} else {					/* Match! Even if name doesn't. */					return mod;				}			} else {				/* Not match, even if name is the same. */				continue;			}		}			if(strcmp(module_name, mod->Identifier) == 0)			return mod;	}	DEBUG("\tModule \"%s\" not found", module_name);	errno = ENOENT;	return NULL;}asn1p_expr_t *asn1f_lookup_symbol(arg_t *arg, asn1p_module_t *mod, asn1p_ref_t *ref) {	asn1p_expr_t *ref_tc;			/* Referenced tc */	asn1p_module_t *imports_from;	char *modulename;	char *identifier;	/*	 * First of all, a reference to a symbol may be specified	 * using several possible forms:	 * a) simple identifier	 *	v INTEGER ::= value	 * b) external reference	 * 	v INTEGER ::= Module1.value	 * c) class-related stuff (the most complex stuff)	 * 	v ::= <[A-Z][A-Z0-9a-z-]*>.&<[A-Z0-9a-z-]+>.	 * All other forms are not implemented at this moment.	 */	DEBUG("(%s) in %s for line %d",		asn1f_printable_reference(ref),		mod->Identifier,		ref->_lineno);	if(ref->comp_count == 1) {		modulename = NULL;		identifier = ref->components[0].name;	} else if(ref->comp_count == 2		&& ref->components[1].name[0] != '&') {		modulename = ref->components[0].name;		identifier = ref->components[1].name;	} else if(ref->comp_count > 1		&& isupper(ref->components[0].name[0])		&& ref->components[1].name[0] == '&') {		asn1p_expr_t *extract;		/*		 * This is a reference to a CLASS-related stuff.		 * Employ a separate function for that.		 */		extract = asn1f_class_access(arg, mod, ref);				return extract;	} else {		DEBUG("\tToo many components: %d", ref->comp_count);		errno = EINVAL;		return NULL;	}	/*	 * If module name is specified explicitly	 * OR the current module's IMPORTS clause contains the identifier,	 * fetch that module.	 */	if(modulename) {		imports_from = asn1f_lookup_module(arg, modulename, 0);		if(imports_from == NULL) {			FATAL("Module \"%s\" "				"mentioned at line %d is not found",				modulename, ref->_lineno);			return NULL;		}		/*		 * Check that the EXPORTS section of this module contains		 * the symbol we care about, or it is EXPORTS ALL.		 */		if(asn1f_compatible_with_exports(arg,imports_from,identifier)) {			errno = EPERM;			return NULL;		}	} else {		imports_from = asn1f_lookup_in_imports(arg, mod, identifier);		if(imports_from == NULL && errno != ESRCH) {			/*			 * Return only of the name was not found.			 * If module was not found or more serious error			 * encountered, just return preserving the errno.			 */			return NULL;		}	}	/*	 * The symbol is being imported from another module.	 */	if(imports_from) {		asn1p_ref_t tmpref = *ref;		if(modulename) {			/*			 * The modulename is specified inside this reference.			 * To avoid recursion, reformat the reference			 * as it were local to that module.			 */			tmpref.components++;	/* Hide the first element */			tmpref.comp_count--;			assert(tmpref.comp_count > 0);		}		return asn1f_lookup_symbol(arg, imports_from, &tmpref);	}	/*	 * Now we know where to search for a value: in the current module.	 */	TQ_FOR(ref_tc, &(mod->members), next) {		if(ref_tc->Identifier)		if(strcmp(ref_tc->Identifier, identifier) == 0)			break;	}	if(ref_tc == NULL) {		DEBUG("Module \"%s\" does not contain \"%s\" "			"mentioned at line %d: %s",			mod->Identifier,			identifier,			ref->_lineno,			strerror(errno)		);		if(asn1f_check_known_external_type(identifier) == 0) {			errno = EEXIST; /* Exists somewhere */		} else {			errno = ESRCH;		}		return NULL;	}	return ref_tc;}asn1p_expr_t *asn1f_find_terminal_type(arg_t *arg, asn1p_expr_t *expr) {	return asn1f_find_terminal_thing(arg, expr, 0);}asn1p_expr_t *asn1f_find_terminal_value(arg_t *arg, asn1p_expr_t *expr) {	return asn1f_find_terminal_thing(arg, expr, 1);}static asn1p_expr_t *asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, int type_or_value) {	asn1p_ref_t *ref;	asn1p_expr_t *tc;	if(type_or_value) {		/* VALUE */		assert(expr->meta_type == AMT_VALUE);		assert(expr->value);		/* Expression may be a terminal type itself */		if(expr->value->type != ATV_REFERENCED)			return expr;		ref = expr->value->value.reference;	} else {		/* TYPE */		/* Expression may be a terminal type itself */		if(expr->expr_type != A1TC_REFERENCE)			return expr;		ref = expr->reference;	}	DEBUG("%s(%s->%s) for line %d",		type_or_value?"VALUE":"TYPE",		expr->Identifier, asn1f_printable_reference(ref),		expr->_lineno);	assert(ref);	/*	 * Lookup inside the type itself (ENUMERATED, INTEGER, etc).	 */	if(type_or_value) {		asn1p_expr_t *val_type_tc;		val_type_tc = asn1f_find_terminal_type(arg, expr);		if(val_type_tc		&& asn1f_look_value_in_type(arg, val_type_tc, expr))			return NULL;		if(expr->value->type != ATV_REFERENCED) {			return expr;		}		assert(ref == expr->value->value.reference);		ref = expr->value->value.reference;	}	/*	 * Lookup inside the default module.	 */	tc = asn1f_lookup_symbol(arg, expr->module, ref);	if(tc == NULL) {		DEBUG("\tSymbol \"%s\" not found: %s",			asn1f_printable_reference(ref),			strerror(errno));		return NULL;	}	/*	 * Recursive loops detection.	 */	if(tc->_mark & TM_RECURSION) {		DEBUG("Recursion loop detected for %s at line %d",			asn1f_printable_reference(ref), ref->_lineno);		errno = EPERM;		return NULL;	}	tc->_mark |= TM_RECURSION;	WITH_MODULE(tc->module,		expr = asn1f_find_terminal_thing(arg, tc, type_or_value));	tc->_mark &= ~TM_RECURSION;	return expr;}/* * Make sure that the specified name is present or otherwise does * not contradict with the EXPORTS clause of the specified module. */static intasn1f_compatible_with_exports(arg_t *arg, asn1p_module_t *mod, const char *name) {	asn1p_xports_t *exports;	asn1p_expr_t *item;	assert(mod);	assert(name);	exports = TQ_FIRST(&(mod->exports));	if(exports == NULL) {		/* No EXPORTS section or EXPORTS ALL; */		return 0;	}	TQ_FOR(item, &(exports->members), next) {		if(strcmp(item->Identifier, name) == 0)			return 0;	}	DEBUG("Symbol \"%s\" contradicts with EXPORTS of module %s",		name, mod->Identifier);	errno = ESRCH;	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -