static int parse_variable(git_config_parser *reader, char **var_name, char **var_value) { const char *value_start = NULL; char *line; int quote_count; bool multiline; git_parse_advance_ws(&reader->ctx); line = git__strndup(reader->ctx.line, reader->ctx.line_len); if (line == NULL) return -1; quote_count = strip_comments(line, 0); /* If there is no value, boolean true is assumed */ *var_value = NULL; if (parse_name(var_name, &value_start, reader, line) < 0) goto on_error; /* * Now, let's try to parse the value */ if (value_start != NULL) { while (git__isspace(value_start[0])) value_start++; if (unescape_line(var_value, &multiline, value_start, 0) < 0) goto on_error; if (multiline) { git_buf multi_value = GIT_BUF_INIT; git_buf_attach(&multi_value, *var_value, 0); if (parse_multiline_variable(reader, &multi_value, quote_count) < 0 || git_buf_oom(&multi_value)) { git_buf_free(&multi_value); goto on_error; } *var_value = git_buf_detach(&multi_value); } } git__free(line); return 0; on_error: git__free(*var_name); git__free(line); return -1; }
static int parse_multiline_variable(git_config_parser *reader, git_buf *value, int in_quotes) { char *line = NULL, *proc_line = NULL; int quote_count; bool multiline; /* Check that the next line exists */ git_parse_advance_line(&reader->ctx); line = git__strndup(reader->ctx.line, reader->ctx.line_len); if (line == NULL) return -1; /* We've reached the end of the file, there is no continuation. * (this is not an error). */ if (line[0] == '\0') { git__free(line); return 0; } quote_count = strip_comments(line, !!in_quotes); /* If it was just a comment, pretend it didn't exist */ if (line[0] == '\0') { git__free(line); return parse_multiline_variable(reader, value, quote_count); /* TODO: unbounded recursion. This **could** be exploitable */ } if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) { git__free(line); return -1; } /* add this line to the multiline var */ git_buf_puts(value, proc_line); git__free(line); git__free(proc_line); /* * If we need to continue reading the next line, let's just * keep putting stuff in the buffer */ if (multiline) return parse_multiline_variable(reader, value, quote_count); return 0; }
int parse_baf(GapIO *io, char *fn, tg_args *a) { int nseqs = 0, nobj = 0, ntags = 0, ncontigs = 0; struct stat sb; zfp *fp; off_t pos; contig_t *c = NULL; tg_pair_t *pair = NULL; baf_block *b, *co = NULL; int last_obj_type = 0; int last_obj_pos = 0; tg_rec last_obj_rec = 0; tg_rec last_cnt_rec = 0; int last_cnt_pos = 0; int last_obj_orient = 0; printf("Loading %s...\n", fn); if (-1 == stat(fn, &sb) || NULL == (fp = zfopen(fn, "r"))) { perror(fn); return -1; } if (a->pair_reads) { pair = create_pair(a->pair_queue); } /* Loop: * Read 1 block of data. * If contig, create contig * If read, insert it, insert to index. * Anything else - reject for now */ pos = 0; while (b = baf_next_block(fp)) { int delay_destroy = 0; switch (b->type) { case CO: { char *contig = baf_block_value(b, CO); if (co) baf_block_destroy(co); co = b; delay_destroy = 1; ncontigs++; create_new_contig(io, &c, contig, a->merge_contigs); /* For anno */ last_obj_type = GT_Contig; last_obj_rec = c->rec; last_obj_pos = c->start + 1; last_cnt_rec = c->rec; last_cnt_pos = c->start + 1; last_obj_orient = 0; break; } case RD: { seq_t seq; int flags; char *tname; tg_rec recno; int is_pair = 0; /* Construct seq struct */ if (-1 == construct_seq_from_block(a, &seq, b, &tname)) { fprintf(stderr, "Failed to parse read block for seq %d\n", nseqs); break; } /* Create range, save sequence */ flags = GRANGE_FLAG_TYPE_SINGLE; if (seq.flags & SEQ_END_REV) flags |= GRANGE_FLAG_END_REV; else flags |= GRANGE_FLAG_END_FWD; if (seq.len < 0) flags |= GRANGE_FLAG_COMP1; if (pair) is_pair = 1; recno = save_range_sequence(io, &seq, seq.mapping_qual, pair, is_pair, tname, c, a, flags, NULL); /* For anno */ last_obj_type = GT_Seq; last_obj_rec = recno; if (seq.len >= 0) { last_obj_pos = seq.pos; last_obj_orient = 0; } else { last_obj_pos = seq.pos - seq.len - 1; last_obj_orient = 1; } nseqs++; break; } case AN: { range_t r; anno_ele_t *e; char *typ = baf_block_value(b, AN); char *loc = baf_block_value(b, LO); char *len = baf_block_value(b, LL); char *txt = baf_block_value(b, TX); char *at = baf_block_value(b, AT); int an_pos; bin_index_t *bin; int anno_obj_type; if (!(a->data_type & DATA_ANNO)) break; if (txt) unescape_line(txt); if (last_obj_type == GT_Contig || (at && *at == 'C')) anno_obj_type = GT_Contig; else anno_obj_type = GT_Seq; if (!loc) { an_pos = last_obj_pos; } else { if (*loc == '@') { an_pos = atoi(loc+1); } else { if (anno_obj_type == GT_Contig) { if (last_obj_orient == 0) an_pos = last_cnt_pos + atoi(loc)-1; else an_pos = last_cnt_pos - (atoi(loc)-1) - (len ? atoi(len)-1 : 0); } else { if (last_obj_orient == 0) an_pos = last_obj_pos + atoi(loc)-1; else an_pos = last_obj_pos - (atoi(loc)-1) - (len ? atoi(len)-1 : 0); } } } r.start = an_pos; r.end = an_pos + (len ? atoi(len)-1 : 0); r.mqual = str2type(typ); r.pair_rec = (anno_obj_type == GT_Contig) ? last_cnt_rec : last_obj_rec; r.flags = GRANGE_FLAG_ISANNO; if (GT_Seq == anno_obj_type) r.flags |= GRANGE_FLAG_TAG_SEQ; r.rec = anno_ele_new(io, 0, anno_obj_type, r.pair_rec, 0, str2type(typ), txt); e = (anno_ele_t *)cache_search(io, GT_AnnoEle, r.rec); e = cache_rw(io, e); bin = bin_add_range(io, &c, &r, NULL, NULL, 0); e->bin = bin->rec; ntags++; break; } case 0: /* blank line */ break; default: printf("Unsupported block type '%s'\n", linetype2str(b->type)); } if (!delay_destroy) baf_block_destroy(b); if ((++nobj & 0xfff) == 0) { int perc = 0; pos = zftello(fp); perc = 100.0 * pos / sb.st_size; printf("\r%d%c", perc, (nobj & 0x3fff) ? '%' : '*'); fflush(stdout); if ((nobj & 0x3fff) == 0) cache_flush(io); } #if 1 if ((nobj & 0x3fff) == 0) { static int perc = 0; if (perc < 100.0 * pos / sb.st_size) { perc = 100.0 * pos / sb.st_size; printf("\r%d%%", perc); //HacheTableStats(io->cache, stdout); //HacheTableStats(((GDB **)io->dbh)[0]->gfile->idx_hash, stdout); { static struct timeval last, curr; static int first = 1; static int last_obj = 0; static int last_contigs = 0; long delta; gettimeofday(&curr, NULL); if (first) { last = curr; first = 0; } delta = (curr.tv_sec - last.tv_sec) * 1000000 + (curr.tv_usec - last.tv_usec); printf(" - %g sec %d obj (%d contigs)\n", delta/1000000.0, nobj - last_obj, ncontigs - last_contigs); last = curr; last_obj = nobj; last_contigs = ncontigs; } fflush(stdout); } } #endif } if (pair && !a->fast_mode) { finish_pairs(io, pair); } if (co) baf_block_destroy(co); cache_flush(io); zfclose(fp); printf("\nLoaded %12d contigs\n", ncontigs); printf(" %12d sequences\n", nseqs); printf(" %12d annotations\n", ntags); if (pair) delete_pair(pair); if (c) cache_decr(io, c); return 0; }