📄 gen_decode.c
字号:
"int tag;\n" "e = der_get_tag (p, len, &class, &type, &tag, NULL);\n" "if(e) %s;\n", forwstr); fprintf(codefile, "switch (MAKE_TAG(class, type, tag)) {\n"); memno = 0; ASN1_TAILQ_FOREACH(m, t->members, members) { char *s; assert(m->type->type == TTag); fprintf(codefile, "case MAKE_TAG(%s, %s, %s):\n", classname(m->type->tag.tagclass), is_primitive_type(m->type->subtype->type) ? "PRIM" : "CONS", valuename(m->type->tag.tagclass, m->type->tag.tagvalue)); asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name); if (s == NULL) errx(1, "malloc"); if(m->optional) fprintf(codefile, "%s = calloc(1, sizeof(*%s));\n" "if (%s == NULL) { e = ENOMEM; %s; }\n", s, s, s, forwstr); decode_type (s, m->type, 0, forwstr, m->gen_name); free (s); fprintf(codefile, "members |= (1 << %d);\n", memno); memno++; fprintf(codefile, "break;\n"); } fprintf(codefile, "default:\n" "return ASN1_MISPLACED_FIELD;\n" "break;\n"); fprintf(codefile, "}\n"); fprintf(codefile, "}\n"); memno = 0; ASN1_TAILQ_FOREACH(m, t->members, members) { char *s; asprintf (&s, "%s->%s", name, m->gen_name); if (s == NULL) errx(1, "malloc"); fprintf(codefile, "if((members & (1 << %d)) == 0)\n", memno); if(m->optional) fprintf(codefile, "%s = NULL;\n", s); else if(m->defval) gen_assign_defval(s, m->defval); else fprintf(codefile, "return ASN1_MISSING_FIELD;\n"); free(s); memno++; } fprintf(codefile, "}\n"); break; } case TSetOf: case TSequenceOf: { char *n; char *sname; fprintf (codefile, "{\n" "size_t %s_origlen = len;\n" "size_t %s_oldret = ret;\n" "size_t %s_olen = 0;\n" "void *%s_tmp;\n" "ret = 0;\n" "(%s)->len = 0;\n" "(%s)->val = NULL;\n", tmpstr, tmpstr, tmpstr, tmpstr, name, name); fprintf (codefile, "while(ret < %s_origlen) {\n" "size_t %s_nlen = %s_olen + sizeof(*((%s)->val));\n" "if (%s_olen > %s_nlen) { e = ASN1_OVERFLOW; %s; }\n" "%s_olen = %s_nlen;\n" "%s_tmp = realloc((%s)->val, %s_olen);\n" "if (%s_tmp == NULL) { e = ENOMEM; %s; }\n" "(%s)->val = %s_tmp;\n", tmpstr, tmpstr, tmpstr, name, tmpstr, tmpstr, forwstr, tmpstr, tmpstr, tmpstr, name, tmpstr, tmpstr, forwstr, name, tmpstr); asprintf (&n, "&(%s)->val[(%s)->len]", name, name); if (n == NULL) errx(1, "malloc"); asprintf (&sname, "%s_s_of", tmpstr); if (sname == NULL) errx(1, "malloc"); decode_type (n, t->subtype, 0, forwstr, sname); fprintf (codefile, "(%s)->len++;\n" "len = %s_origlen - ret;\n" "}\n" "ret += %s_oldret;\n" "}\n", name, tmpstr, tmpstr); if (t->range) range_check(name, "len", forwstr, t->range); free (n); free (sname); break; } case TGeneralizedTime: decode_primitive ("generalized_time", name, forwstr); break; case TGeneralString: decode_primitive ("general_string", name, forwstr); break; case TTag:{ char *tname; fprintf(codefile, "{\n" "size_t %s_datalen, %s_oldlen;\n", tmpstr, tmpstr); if(dce_fix) fprintf(codefile, "int dce_fix;\n"); fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, %s, %s, " "&%s_datalen, &l);\n", classname(t->tag.tagclass), is_primitive_type(t->subtype->type) ? "PRIM" : "CONS", valuename(t->tag.tagclass, t->tag.tagvalue), tmpstr); if(optional) { fprintf(codefile, "if(e) {\n" "%s = NULL;\n" "} else {\n" "%s = calloc(1, sizeof(*%s));\n" "if (%s == NULL) { e = ENOMEM; %s; }\n", name, name, name, name, forwstr); } else { fprintf(codefile, "if(e) %s;\n", forwstr); } fprintf (codefile, "p += l; len -= l; ret += l;\n" "%s_oldlen = len;\n", tmpstr); if(dce_fix) fprintf (codefile, "if((dce_fix = _heim_fix_dce(%s_datalen, &len)) < 0)\n" "{ e = ASN1_BAD_FORMAT; %s; }\n", tmpstr, forwstr); else fprintf(codefile, "if (%s_datalen > len) { e = ASN1_OVERRUN; %s; }\n" "len = %s_datalen;\n", tmpstr, forwstr, tmpstr); asprintf (&tname, "%s_Tag", tmpstr); if (tname == NULL) errx(1, "malloc"); decode_type (name, t->subtype, 0, forwstr, tname); if(dce_fix) fprintf(codefile, "if(dce_fix){\n" "e = der_match_tag_and_length (p, len, " "(Der_class)0,(Der_type)0, UT_EndOfContent, " "&%s_datalen, &l);\n" "if(e) %s;\np += l; len -= l; ret += l;\n" "} else \n", tmpstr, forwstr); fprintf(codefile, "len = %s_oldlen - %s_datalen;\n", tmpstr, tmpstr); if(optional) fprintf(codefile, "}\n"); fprintf(codefile, "}\n"); free(tname); break; } case TChoice: { Member *m, *have_ellipsis = NULL; const char *els = ""; if (t->members == NULL) break; ASN1_TAILQ_FOREACH(m, t->members, members) { const Type *tt = m->type; char *s; Der_class cl; Der_type ty; unsigned tag; if (m->ellipsis) { have_ellipsis = m; continue; } find_tag(tt, &cl, &ty, &tag); fprintf(codefile, "%sif (der_match_tag(p, len, %s, %s, %s, NULL) == 0) {\n", els, classname(cl), ty ? "CONS" : "PRIM", valuename(cl, tag)); asprintf (&s, "%s(%s)->u.%s", m->optional ? "" : "&", name, m->gen_name); if (s == NULL) errx(1, "malloc"); decode_type (s, m->type, m->optional, forwstr, m->gen_name); fprintf(codefile, "(%s)->element = %s;\n", name, m->label); free(s); fprintf(codefile, "}\n"); els = "else "; } if (have_ellipsis) { fprintf(codefile, "else {\n" "(%s)->u.%s.data = calloc(1, len);\n" "if ((%s)->u.%s.data == NULL) {\n" "e = ENOMEM; %s;\n" "}\n" "(%s)->u.%s.length = len;\n" "memcpy((%s)->u.%s.data, p, len);\n" "(%s)->element = %s;\n" "p += len;\n" "ret += len;\n" "len -= len;\n" "}\n", name, have_ellipsis->gen_name, name, have_ellipsis->gen_name, forwstr, name, have_ellipsis->gen_name, name, have_ellipsis->gen_name, name, have_ellipsis->label); } else { fprintf(codefile, "else {\n" "e = ASN1_PARSE_ERROR;\n" "%s;\n" "}\n", forwstr); } break; } case TUTCTime: decode_primitive ("utctime", name, forwstr); break; case TUTF8String: decode_primitive ("utf8string", name, forwstr); break; case TPrintableString: decode_primitive ("printable_string", name, forwstr); break; case TIA5String: decode_primitive ("ia5_string", name, forwstr); break; case TBMPString: decode_primitive ("bmp_string", name, forwstr); break; case TUniversalString: decode_primitive ("universal_string", name, forwstr); break; case TVisibleString: decode_primitive ("visible_string", name, forwstr); break; case TNull: fprintf (codefile, "/* NULL */\n"); break; case TOID: decode_primitive ("oid", name, forwstr); break; default : abort (); } return 0;}voidgenerate_type_decode (const Symbol *s){ int preserve = preserve_type(s->name) ? TRUE : FALSE; fprintf (headerfile, "int " "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n", s->gen_name, s->gen_name); fprintf (codefile, "int\n" "decode_%s(const unsigned char *p," " size_t len, %s *data, size_t *size)\n" "{\n", s->gen_name, s->gen_name); switch (s->type->type) { case TInteger: case TBoolean: case TOctetString: case TOID: case TGeneralizedTime: case TGeneralString: case TUTF8String: case TPrintableString: case TIA5String: case TBMPString: case TUniversalString: case TVisibleString: case TUTCTime: case TNull: case TEnumerated: case TBitString: case TSequence: case TSequenceOf: case TSet: case TSetOf: case TTag: case TType: case TChoice: fprintf (codefile, "size_t ret = 0;\n" "size_t l;\n" "int e;\n"); if (preserve) fprintf (codefile, "const unsigned char *begin = p;\n"); fprintf (codefile, "\n"); fprintf (codefile, "memset(data, 0, sizeof(*data));\n"); /* hack to avoid `unused variable' */ decode_type ("data", s->type, 0, "goto fail", "Top"); if (preserve) fprintf (codefile, "data->_save.data = calloc(1, ret);\n" "if (data->_save.data == NULL) { \n" "e = ENOMEM; goto fail; \n" "}\n" "data->_save.length = ret;\n" "memcpy(data->_save.data, begin, ret);\n"); fprintf (codefile, "if(size) *size = ret;\n" "return 0;\n"); fprintf (codefile, "fail:\n" "free_%s(data);\n" "return e;\n", s->gen_name); break; default: abort (); } fprintf (codefile, "}\n\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -