コード例 #1
0
ファイル: html_tbl.c プロジェクト: ebichu/dd-wrt
void set_td_width(struct table *t, int x, int width, int f)
{
	if (x >= t->xc) {
		int n = t->xc ? t->xc : 1;
		int i;
		int *nc;
		while (x >= n) {
			if ((unsigned)n > MAXINT / 2) overalloc();
			n *= 2;
		}
		if ((unsigned)n > MAXINT / sizeof(int)) overalloc();
		nc = mem_realloc(t->xcols, n * sizeof(int));
		for (i = t->xc; i < n; i++) nc[i] = W_AUTO;
		t->xc = n;
		t->xcols = nc;
	}
	if (t->xcols[x] == W_AUTO || f) {
		set:
		t->xcols[x] = width;
		return;
	}
	if (width == W_AUTO) return;
	if (width < 0 && t->xcols[x] >= 0) goto set;
	if (width >= 0 && t->xcols[x] < 0) return;
	t->xcols[x] = (t->xcols[x] + width) / 2;
}
コード例 #2
0
void alloc_term_screen(struct terminal *term, int x, int y)
{
    unsigned *s, *t;
    if (x && (unsigned)x * (unsigned)y / (unsigned)x != (unsigned)y) overalloc();
    if ((unsigned)x * (unsigned)y > MAXINT / sizeof(unsigned)) overalloc();
    s = mem_realloc(term->screen, x * y * sizeof(unsigned));
    t = mem_realloc(term->last_screen, x * y * sizeof(unsigned));
    memset(t, -1, x * y * sizeof(unsigned));
    term->x = x;
    term->y = y;
    term->last_screen = t;
    memset(s, 0, x * y * sizeof(unsigned));
    term->screen = s;
    term->dirty = 1;
}
コード例 #3
0
ファイル: tiff.c プロジェクト: lince/ginga-srpp
static void flip_buffer(void *buf,int width,int height)
{
	if (htonl(0x12345678L)!=0x12345678L)	/* little endian --- ja to chci na intelu rychly!!! */
	{
#ifdef t4c
		t4c* buffer=(t4c*)buf;
		register t4c a,b;
		t4c *p,*q;
		int i,l;
		
		for (l=0,p=buffer,q=buffer+width*(height-1);l<(height>>1);l++,q-=(width<<1))
			for (i=0;i<width;a=*p,b=*q,*p++=b,*q++=a,i++);
#else
		unsigned char* buffer=(unsigned char*)buf;
		unsigned char *p,*q;
		int l;
		unsigned char *tmp;
		int w=4*width;
		
		if ((unsigned)w > MAXINT) overalloc();
		tmp=mem_alloc(w*sizeof(unsigned char));
		
		/* tohle je pomalejsi, protoze se kopiruje pamet->pamet, pamet->pamet */
		/* kdyz mame 4B typek, tak se kopiruje pamet->reg, reg->pamet */
		for (l=0,p=buffer,q=buffer+w*(height-1);l<(height>>1);l++,q-=w,p+=w)
			memcpy(tmp,p,w),memcpy(p,q,w),memcpy(q,tmp,w);
		mem_free(tmp);
#endif
	}
コード例 #4
0
ファイル: gif.c プロジェクト: engine12/links
/* colors: number of triplets (color entries) */
static void alloc_color_map(int colors)
{
 struct gif_decoder* deco=global_cimg->decoder;

 if (deco->color_map) mem_free(deco->color_map);
 if ((unsigned)colors > MAXINT / 3 / sizeof(*(deco->color_map))) overalloc();
 deco->color_map=mem_alloc(colors*3*sizeof(*(deco->color_map)));
}
コード例 #5
0
ファイル: tiff.c プロジェクト: lince/ginga-srpp
void tiff_restart(struct cached_image *cimg, unsigned char *data, int length)
{
	struct tiff_decoder * deco=(struct tiff_decoder*)cimg->decoder;
	unsigned char *p;

	if (!deco->tiff_data) {
		if ((unsigned)length > MAXINT) overalloc();
		p=mem_alloc(length);
	} else {
		if ((unsigned)length + (unsigned)deco->tiff_size > MAXINT) overalloc();
		if ((unsigned)length + (unsigned)deco->tiff_size < (unsigned)length) overalloc();
		p=mem_realloc(deco->tiff_data,deco->tiff_size+length);
	}
	deco->tiff_data=p;
	memcpy(deco->tiff_data+deco->tiff_size,data,length);
	deco->tiff_size+=length;
}
コード例 #6
0
ファイル: html_r.c プロジェクト: ebichu/dd-wrt
void r_xpand_spaces(struct part *p, int l)
{
	unsigned char *c;
	if ((unsigned)l >= MAXINT) overalloc();
	c = mem_realloc(p->spaces, l + 1);
	memset(c + p->spl, 0, l - p->spl + 1);
	p->spl = l + 1;
	p->spaces = c;
}
コード例 #7
0
ファイル: html_gr.c プロジェクト: lince/ginga-srpp
static inline int pw2(int a)
{
	int x = 1;
	while (x < a && x) {
		if ((unsigned)x > MAXINT / 2) overalloc();
		x <<= 1;
	}
	return x;
}
コード例 #8
0
ファイル: html_r.c プロジェクト: ebichu/dd-wrt
struct link *new_link(struct f_data *f)
{
	if (!f) return NULL;
	if (!(f->nlinks & (ALLOC_GR - 1))) {
		if ((unsigned)f->nlinks > MAXINT / sizeof(struct link) - ALLOC_GR) overalloc();
		f->links = mem_realloc(f->links, (f->nlinks + ALLOC_GR) * sizeof(struct link));
	}
	memset(&f->links[f->nlinks], 0, sizeof(struct link));
	return &f->links[f->nlinks++];
}
コード例 #9
0
ファイル: html_r.c プロジェクト: ebichu/dd-wrt
static inline void xpand_lines(struct part *p, int y)
{
	/*if (y >= p->y) p->y = y + 1;*/
	if (!p->data) return;
	if (XALIGN((unsigned)y + (unsigned)p->yp) > MAXINT) overalloc();
	y += p->yp;
	if (y >= p->data->y) {			/* !!! FIXME: out of inline */
		int i;
		if (XALIGN(y + 1) > XALIGN(p->data->y)) {
			if (XALIGN((unsigned)y + 1) > MAXINT / sizeof(struct line)) overalloc();
			p->data->data = mem_realloc(p->data->data, XALIGN(y+1)*sizeof(struct line));
		}
		for (i = p->data->y; i <= y; i++) {
			p->data->data[i].l = 0;
			p->data->data[i].c = p->bgcolor;
			p->data->data[i].d = DUMMY;
		}
		p->data->y = i;
	}
}
コード例 #10
0
ファイル: html_r.c プロジェクト: ebichu/dd-wrt
static inline void shift_chars(struct part *p, int y, int s)
{
	chr *a;
	int l = LEN(y);
	if ((unsigned)l > MAXINT / sizeof(chr)) overalloc();
	a = mem_alloc(l * sizeof(chr));
	memcpy(a, &POS(0, y), l * sizeof(chr));
	set_hchars(p, 0, y, s, (p->data->data[y].c << 11) | ' ');
	copy_chars(p, s, y, l, a);
	mem_free(a);
	move_links(p, 0, y, s, y);
}
コード例 #11
0
ファイル: drivers.c プロジェクト: JamesLinus/LiteBSD-Ports
int init_virtual_devices(struct graphics_driver *drv, int n)
{
	if (n_virtual_devices) {
		internal("init_virtual_devices: already initialized");
		return -1;
	}
	if ((unsigned)n > MAXINT / sizeof(struct graphics_device *)) overalloc();
	virtual_devices = mem_calloc(n * sizeof(struct graphics_device *));
	n_virtual_devices = n;
	virtual_device_timer = NULL;
	current_virtual_device = NULL;
	return 0;
}
コード例 #12
0
ファイル: connect.c プロジェクト: ebichu/dd-wrt
void read_select(struct connection *c)
{
	struct read_buffer *rb;
	int rd;
	if (!(rb = c->buffer)) {
		internal("read socket has no buffer");
		setcstate(c, S_INTERNAL);
		abort_connection(c);
		return;
	}
	set_handlers(rb->sock, NULL, NULL, NULL, NULL);
	if ((unsigned)rb->len > MAXINT - sizeof(struct read_buffer) - READ_SIZE) overalloc();
	rb = mem_realloc(rb, sizeof(struct read_buffer) + rb->len + READ_SIZE);
	c->buffer = rb;

#ifdef HAVE_SSL
	if(c->ssl) {
		if ((rd = SSL_read(c->ssl, rb->data + rb->len, READ_SIZE)) <= 0) {
			int err;
			if ((err = SSL_get_error(c->ssl, rd)) == SSL_ERROR_WANT_READ) {
				read_from_socket(c, rb->sock, rb, rb->done);
				return;
			}
			if (rb->close && !rd) {
				rb->close = 2;
				rb->done(c, rb);
				return;
			}
			setcstate(c, rd ? (err == SSL_ERROR_SYSCALL ? get_error_from_errno(errno) : S_SSL_ERROR) : S_CANT_READ);
			/*mem_free(rb);*/
			if (!rd || err == SSL_ERROR_SYSCALL) retry_connection(c);
			else abort_connection(c);
			return;
		}
	} else
#endif
		if ((rd = read(rb->sock, rb->data + rb->len, READ_SIZE)) <= 0) {
			if (rb->close && !rd) {
				rb->close = 2;
				rb->done(c, rb);
				return;
			}
			setcstate(c, rd ? get_error_from_errno(errno) : S_CANT_READ);
			/*mem_free(rb);*/
			retry_connection(c);
			return;
		}
	log_data(rb->data + rb->len, rd);
	rb->len += rd;
	rb->done(c, rb);
}
コード例 #13
0
ファイル: html_tbl.c プロジェクト: ebichu/dd-wrt
void new_columns(struct table *t, int span, int width, int align, int valign, int group)
{
	if ((unsigned)t->c + (unsigned)span > MAXINT) overalloc();
	if (t->c + span > t->rc) {
		int n = t->rc;
		struct table_column *nc;
		while (t->c + span > n) {
			if ((unsigned)n > MAXINT / 2) overalloc();
			n *= 2;
		}
		if ((unsigned)n > MAXINT / sizeof(struct table_column)) overalloc();
		nc = mem_realloc(t->cols, n * sizeof(struct table_column));
		t->rc = n;
		t->cols = nc;
	}
	while (span--) {
		t->cols[t->c].align = align;
		t->cols[t->c].valign = valign;
		t->cols[t->c].width = width;
		t->cols[t->c++].group = group;
		group = 0;
	}
}
コード例 #14
0
unsigned char *get_cwd()
{
    int bufsize = 128;
    unsigned char *buf;
    while (1) {
        buf = mem_alloc(bufsize);
        if (getcwd(buf, bufsize)) return buf;
        mem_free(buf);
        if (errno == EINTR) continue;
        if (errno != ERANGE) return NULL;
        if ((unsigned)bufsize > MAXINT - 128) overalloc();
        bufsize += 128;
    }
    return NULL;
}
コード例 #15
0
ファイル: connect.c プロジェクト: ebichu/dd-wrt
void write_to_socket(struct connection *c, int s, unsigned char *data, int len, void (*write_func)(struct connection *))
{
	struct write_buffer *wb;
	log_data(data, len);
	if ((unsigned)len > MAXINT - sizeof(struct write_buffer)) overalloc();
	wb = mem_alloc(sizeof(struct write_buffer) + len);
	wb->sock = s;
	wb->len = len;
	wb->pos = 0;
	wb->done = write_func;
	memcpy(wb->data, data, len);
	if (c->buffer) mem_free(c->buffer);
	c->buffer = wb;
	set_handlers(s, NULL, (void (*)(void *))write_select, (void (*)(void *))exception, c);
}
コード例 #16
0
ファイル: html_tbl.c プロジェクト: ebichu/dd-wrt
struct table_cell *new_cell(struct table *t, int x, int y)
{
	struct table nt;
	int i, j;
	if (x < t->x && y < t->y) goto ret;
	rep:
	if (x < t->rx && y < t->ry) {
		expand_cells(t, x, y);
		goto ret;
	}
	nt.rx = t->rx;
	nt.ry = t->ry;
	while (x >= nt.rx) {
		if ((unsigned)nt.rx > MAXINT / 2) overalloc();
		nt.rx *= 2;
	}
	while (y >= nt.ry) {
		if ((unsigned)nt.ry > MAXINT / 2) overalloc();
		nt.ry *= 2;
	}
	if ((unsigned)nt.rx * (unsigned)nt.ry / (unsigned)nt.rx != (unsigned)nt.ry) overalloc();
	if ((unsigned)nt.rx * (unsigned)nt.ry > MAXINT / sizeof(struct table_cell)) overalloc();
	nt.cells = mem_alloc(nt.rx * nt.ry * sizeof(struct table_cell));
	memset(nt.cells, 0, nt.rx * nt.ry * sizeof(struct table_cell));
	for (i = 0; i < t->x; i++)
		for (j = 0; j < t->y; j++)
			memcpy(CELL(&nt, i, j), CELL(t, i, j), sizeof(struct table_cell));
	mem_free(t->cells);
	t->cells = nt.cells;
	t->rx = nt.rx;
	t->ry = nt.ry;
	goto rep;

	ret:
	return CELL(t, x, y);
}
コード例 #17
0
ファイル: html_r.c プロジェクト: ebichu/dd-wrt
static inline void xpand_line(struct part *p, int y, int x)
{
	if (!p->data) return; /* !!! FIXME: p->x (?) */
	if (XALIGN((unsigned)x + (unsigned)p->xp) > MAXINT) overalloc();
	x += p->xp;
	y += p->yp;
#ifdef DEBUG
	if (y >= p->data->y) {
		internal("line does not exist");
		return;
	}
#endif
	if (x >= p->data->data[y].l) {		/* !!! FIXME: out of inline */
		int i;
		if (XALIGN(x+1) > XALIGN(p->data->data[y].l)) {
			if (XALIGN((unsigned)x + 1) > MAXINT / sizeof(chr)) overalloc();
			p->data->data[y].d = mem_realloc(p->data->data[y].d, XALIGN(x+1)*sizeof(chr));
		}
		for (i = p->data->data[y].l; i <= x; i++)
			p->data->data[y].d[i] = (p->data->data[y].c << 11) | ' ';
		p->data->data[y].c = p->bgcolor;
		p->data->data[y].l = i;
	}
}
コード例 #18
0
ファイル: x.c プロジェクト: lince/ginga-srpp
/* adds graphics device to hash table */
static int x_add_to_table(struct graphics_device* gd)
{
	int a=(*((Window*)(gd->driver_data)))&(X_HASH_TABLE_SIZE-1);
	int c=x_hash_table[a].count;

	if (!c) {
		x_hash_table[a].pointer=mem_alloc(sizeof(struct graphics_device *));
	} else {
		if ((unsigned)c > MAXINT / sizeof(struct graphics_device *) - 1) overalloc();
		x_hash_table[a].pointer=mem_realloc(x_hash_table[a].pointer,(c+1)*sizeof(struct graphics_device *));
	}

	x_hash_table[a].pointer[c]=gd;
	x_hash_table[a].count++;
	return 0;
}
コード例 #19
0
ファイル: html_tbl.c プロジェクト: ebichu/dd-wrt
int get_column_widths(struct table *t)
{
	int i, j, s, ns;
	if ((unsigned)t->x > MAXINT / sizeof(int)) overalloc();
	if (!t->min_c) t->min_c = mem_alloc(t->x * sizeof(int));
	if (!t->max_c) t->max_c = mem_alloc(t->x * sizeof(int));
	if (!t->w_c) t->w_c = mem_alloc(t->x * sizeof(int));
	memset(t->min_c, 0, t->x * sizeof(int));
	memset(t->max_c, 0, t->x * sizeof(int));
	s = 1;
	do {
		ns = MAXINT;
		for (i = 0; i < t->x; i++) for (j = 0; j < t->y; j++) {
			struct table_cell *c = CELL(t, i, j);
			if (c->spanned || !c->used) continue;
			if (c->colspan + i > t->x) {
				/*internal("colspan out of table");
				return -1;*/
				continue;
			}
			if (c->colspan == s) {
				int k, p = 0;
				/*int pp = t->max_c[i];*/
				int m = 0;
				for (k = 1; k < s; k++) {
					p += get_vline_width(t, i + k) >= 0;
					/*pp += t->max_c[i + k];*/
				}
				/*if (0 && s > 1 && (t->p->data || t->p->xp)) {
					int d, cc = (!!(t->frame & F_LHS) + !!(t->frame & F_RHS)) * !!t->border;
					for (d = 0; d < t->c; c++) {
						cc += t->max_c[d];
						if (d > 0) d += get_vline_width(t, d) >= 0;
					}
					if (cc >= t->width) goto nd;
					if (cc + c->max_width - p - pp >= t->width) {
						m = cc + c->max_width - p - pp - t->width;
					}
				}*/
				dst_width(t->min_c + i, s, c->min_width - p, t->max_c + i);
				dst_width(t->max_c + i, s, c->max_width - p - m, NULL);
				for (k = 0; k < s; k++) if (t->min_c[i + k] > t->max_c[i + k]) t->max_c[i + k] = t->min_c[i + k];
			} else if (c->colspan > s && c->colspan < ns) ns = c->colspan;
		}
	} while ((s = ns) != MAXINT);
	return 0;
}
コード例 #20
0
ファイル: png.c プロジェクト: Gingar/port
void png_row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32
	row_num, int pass)
{
	struct cached_image *cimg;
#ifdef REPACK_16
	unsigned char *tmp;
	int channels;
#endif /* #ifdef REPACK_16 */

	cimg=global_cimg;
#ifdef REPACK_16
	if (cimg->buffer_bytes_per_pixel>4)
	{
		channels=cimg->buffer_bytes_per_pixel/sizeof(unsigned
			short);
		if (PNG_INTERLACE_NONE==png_get_interlace_type(png_ptr,
			((struct png_decoder *)cimg->decoder)->info_ptr))
		{
			unsigned_short_from_2char((unsigned short *)(cimg->buffer+cimg
				->buffer_bytes_per_pixel *cimg->width
				*row_num), new_row, cimg->width
				*channels);
		}else{
			if ((unsigned)cimg->width > MAXINT / 2 / channels) overalloc();
			tmp=mem_alloc(cimg->width*2*channels);
			a2char_from_unsigned_short(tmp, (unsigned short *)(cimg->buffer
				+cimg->buffer_bytes_per_pixel
				*cimg->width*row_num), cimg->width*channels);
			png_progressive_combine_row(png_ptr, tmp, new_row);
			unsigned_short_from_2char((unsigned short *)(cimg->buffer
				+cimg->buffer_bytes_per_pixel
				*cimg->width*row_num), tmp, cimg->width*channels);
			mem_free(tmp);
		}
	}else
#endif /* #ifdef REPACK_16 */
	{
		png_progressive_combine_row(png_ptr,
			cimg->buffer+cimg->buffer_bytes_per_pixel
			*cimg->width*row_num, new_row);
	}
	cimg->rows_added=1;
}
コード例 #21
0
unsigned char *parse_header_param(unsigned char *x, unsigned char *e)
{
    unsigned char u;
    size_t le = strlen(e);
    int lp;
    unsigned char *y = x;
a:
    if (!(y = strchr(y, ';'))) return NULL;
    while (*y && (*y == ';' || *y <= ' ')) y++;
    if (strlen(y) < le) return NULL;
    if (casecmp(y, e, le)) goto a;
    y += le;
    while (*y && (*y <= ' ' || *y == '=')) y++;
    u = ';';
    if (*y == '\'' || *y == '"') u = *y++;
    lp = 0;
    while (y[lp] >= ' ' && y[lp] != u) {
        lp++;
        if (lp == MAXINT) overalloc();
    }
    return memacpy(y, lp);
}
コード例 #22
0
ファイル: html_tbl.c プロジェクト: ebichu/dd-wrt
void distribute_widths(struct table *t, int width)
{
	int i;
	int d = width - t->min_t;
	int om = 0;
	char *u;
	int *w, *mx;
	int mmax_c = 0;
	if (!t->x) return;
	if (d < 0) {
		/*internal("too small width %d, required %d", width, t->min_t);*/
		return;
	}
	for (i = 0; i < t->x; i++) if (t->max_c[i] > mmax_c) mmax_c = t->max_c[i];
	memcpy(t->w_c, t->min_c, t->x * sizeof(int));
	t->rw = width;
	if ((unsigned)t->x > MAXINT / sizeof(int)) overalloc();
	u = mem_alloc(t->x);
	w = mem_alloc(t->x * sizeof(int));
	mx = mem_alloc(t->x * sizeof(int));
	while (d) {
		int mss, mii;
		int p = 0;
		int wq;
		int dd;
		memset(w, 0, t->x * sizeof(int));
		memset(mx, 0, t->x * sizeof(int));
		for (i = 0; i < t->x; i++) {
			switch (om) {
				case 0:
					if (t->w_c[i] < t->xcols[i]) {
						w[i] = 1, mx[i] = (t->xcols[i] > t->max_c[i] ? t->max_c[i] : t->xcols[i]) - t->w_c[i];
						if (mx[i] <= 0) w[i] = 0;
					}
					break;
				case 1:
					if (t->xcols[i] < -1 && t->xcols[i] != -2) {
						w[i] = t->xcols[i] <= -2 ? -2 - t->xcols[i] : 1;
						mx[i] = t->max_c[i] - t->w_c[i];
						if (mx[i] <= 0) w[i] = 0;
					}
					break;
				case 2:
				case 3:
					if (t->w_c[i] < t->max_c[i] && (om == 3 || t->xcols[i] == W_AUTO)) {
						mx[i] = t->max_c[i] - t->w_c[i];
						if (mmax_c) w[i] = 5 + t->max_c[i] * 10 / mmax_c;
						else w[i] = 1;
					}
					break;
				case 4:
					if (t->xcols[i] >= 0) {
						w[i] = 1, mx[i] = t->xcols[i] - t->w_c[i];
						if (mx[i] <= 0) w[i] = 0;
					}
					break;
				case 5:
					if (t->xcols[i] < 0) w[i] = t->xcols[i] <= -2 ? -2 - t->xcols[i] : 1, mx[i] = MAXINT;
					break;
				case 6:
					w[i] = 1, mx[i] = MAXINT;
					break;
				default:
					/*internal("could not expand table");*/
					goto end2;
			}
			p += w[i];
		}
		if (!p) {
			om++;
			continue;
		}
		wq = 0;
		if (u) memset(u, 0, t->x);
		dd = d;
		a:
		mss = 0; mii = -1;
		for (i = 0; i < t->x; i++) if (w[i]) {
			int ss;
			if (u && u[i]) continue;
			if (!(ss = dd * w[i] / p)) ss = 1;
			if (ss > mx[i]) ss = mx[i];
			if (ss > mss) mss = ss, mii = i;
		}
		if (mii != -1) {
			int q = t->w_c[mii];
			if (u) u[mii] = 1;
			t->w_c[mii] += mss;
			d -= t->w_c[mii] - q;
			while (d < 0) t->w_c[mii]--, d++;
			if (t->w_c[mii] < q) {
				/*internal("shrinking cell");*/
				t->w_c[mii] = q;
			}
			wq = 1;
			if (d) goto a;
		} else if (!wq) om++;
	}
	end2:
	mem_free(mx);
	mem_free(w);
	if (u) mem_free(u);
}
コード例 #23
0
ファイル: file.c プロジェクト: Gingar/port
void file_func(struct connection *c)
{
	struct cache_entry *e;
	unsigned char *file, *name, *head;
	int fl;
	DIR *d;
	int h, r;
	struct stat stt;
	if (anonymous && !anonymousGinga) {
		setcstate(c, S_BAD_URL);
		abort_connection(c);
		return;
	}
	if (!(name = get_filename(c->url))) {
		setcstate(c, S_OUT_OF_MEM); abort_connection(c); return;
	}
	
	if (anonymousGinga && !allowedPath(name)){
		setcstate(c, S_BAD_URL);
		abort_connection(c);
		return;
	}

	if (stat(name, &stt)) {
		mem_free(name);
		setcstate(c, -errno); abort_connection(c); return;
	}
	if (!S_ISDIR(stt.st_mode) && !S_ISREG(stt.st_mode)) {
		mem_free(name);
		setcstate(c, S_FILE_TYPE); abort_connection(c); return;
	}
	if ((h = open(name, O_RDONLY | O_NOCTTY)) == -1) {
		int er = errno;
		if ((d = opendir(name))) goto dir;
		mem_free(name);
		setcstate(c, -er); abort_connection(c); return;
	}
	set_bin(h);
	if (S_ISDIR(stt.st_mode)) {
		struct dirs *dir;
		int dirl;
		int i;
		struct dirent *de;
		d = opendir(name);
		close(h);
		if (!d) {
			mem_free(name);
			setcstate(c, -errno); abort_connection(c); return;
		}
		dir:
		dir = DUMMY, dirl = 0;
		if (name[0] && !dir_sep(name[strlen(name) - 1])) {
			if (get_cache_entry(c->url, &e)) {
				mem_free(name);
				closedir(d);
				setcstate(c, S_OUT_OF_MEM); abort_connection(c); return;
			}
			c->cache = e;
			if (e->redirect) mem_free(e->redirect);
			e->redirect = stracpy(c->url);
			e->redirect_get = 1;
			add_to_strn(&e->redirect, "/");
			mem_free(name);
			closedir(d);
			goto end;
		}
		last_uid = -1;
		last_gid = -1;
		file = init_str();
		fl = 0;
		add_to_str(&file, &fl, "<html><head><title>");
		add_conv_str(&file, &fl, name, strlen(name), -1);
		add_to_str(&file, &fl, "</title></head><body><h2>Directory ");
		add_conv_str(&file, &fl, name, strlen(name), -1);
		add_to_str(&file, &fl, "</h2><pre>");
		while ((de = readdir(d))) {
			struct stat stt, *stp;
			unsigned char **p;
			int l;
			unsigned char *n;
			if (!strcmp(de->d_name, ".")) continue;
			if ((unsigned)dirl > MAXINT / sizeof(struct dirs) - 1) overalloc();
			dir = mem_realloc(dir, (dirl + 1) * sizeof(struct dirs));
			dir[dirl].f = stracpy(de->d_name);
			*(p = &dir[dirl++].s) = init_str();
			l = 0;
			n = stracpy(name);
			add_to_strn(&n, de->d_name);
#ifdef FS_UNIX_SOFTLINKS
			if (lstat(n, &stt))
#else
			if (stat(n, &stt))
#endif
			     stp = NULL;
			else stp = &stt;
			mem_free(n);
			stat_mode(p, &l, stp);
			stat_links(p, &l, stp);
			stat_user(p, &l, stp, 0);
			stat_user(p, &l, stp, 1);
			stat_size(p, &l, stp);
			stat_date(p, &l, stp);
		}
		closedir(d);
		if (dirl) qsort(dir, dirl, sizeof(struct dirs), (int(*)(const void *, const void *))comp_de);
		for (i = 0; i < dirl; i++) {
			unsigned char *lnk = NULL;
#ifdef FS_UNIX_SOFTLINKS
			if (dir[i].s[0] == 'l') {
				unsigned char *buf = NULL;
				int size = 0;
				int r;
				unsigned char *n = stracpy(name);
				add_to_strn(&n, dir[i].f);
				do {
					if (buf) mem_free(buf);
					size += ALLOC_GR;
					if ((unsigned)size > MAXINT) overalloc();
					buf = mem_alloc(size);
					r = readlink(n, buf, size);
				} while (r == size);
				if (r == -1) goto yyy;
				buf[r] = 0;
				lnk = buf;
				goto xxx;
				yyy:
				mem_free(buf);
				xxx:
				mem_free(n);
			}
#endif
			/*add_to_str(&file, &fl, "   ");*/
			add_to_str(&file, &fl, dir[i].s);
			add_to_str(&file, &fl, "<a href=\"");
			add_conv_str(&file, &fl, dir[i].f, strlen(dir[i].f), 1);
			if (dir[i].s[0] == 'd') add_to_str(&file, &fl, "/");
			else if (lnk) {
				struct stat st;
				unsigned char *n = stracpy(name);
				add_to_strn(&n, dir[i].f);
				if (!stat(n, &st)) if (S_ISDIR(st.st_mode)) add_to_str(&file, &fl, "/");
				mem_free(n);
			}
			add_to_str(&file, &fl, "\">");
			/*if (dir[i].s[0] == 'd') add_to_str(&file, &fl, "<font color=\"yellow\">");*/
			add_conv_str(&file, &fl, dir[i].f, strlen(dir[i].f), 0);
			/*if (dir[i].s[0] == 'd') add_to_str(&file, &fl, "</font>");*/
			add_to_str(&file, &fl, "</a>");
			if (lnk) {
				add_to_str(&file, &fl, " -> ");
				add_to_str(&file, &fl, lnk);
				mem_free(lnk);
			}
			add_to_str(&file, &fl, "\n");
		}
		mem_free(name);
		for (i = 0; i < dirl; i++) mem_free(dir[i].s), mem_free(dir[i].f);
		mem_free(dir);
		add_to_str(&file, &fl, "</pre></body></html>\n");
		head = stracpy("\r\nContent-Type: text/html\r\n");
	} else {
		mem_free(name);
		/* + !stt.st_size is there because of bug in Linux. Read returns
		   -EACCES when reading 0 bytes to invalid address */
		if (stt.st_size > MAXINT) {
			close(h);
			setcstate(c, S_LARGE_FILE); abort_connection(c);
			return;
		}
		file = mem_alloc(stt.st_size + !stt.st_size);
		if ((r = read(h, file, stt.st_size)) != stt.st_size) {
			mem_free(file); close(h);
			setcstate(c, r == -1 ? -errno : S_FILE_ERROR);
			abort_connection(c); return;
		}
		close(h);
		fl = stt.st_size;
		head = stracpy("");
	}
	if (get_cache_entry(c->url, &e)) {
		mem_free(file);
		setcstate(c, S_OUT_OF_MEM); abort_connection(c); return;
	}
	if (e->head) mem_free(e->head);
	e->head = head;
	c->cache = e;
	add_fragment(e, 0, file, fl);
	truncate_entry(e, fl, 1);
	mem_free(file);
	end:
	c->cache->incomplete = 0;
	setcstate(c, S_OK);
	abort_connection(c);
}
コード例 #24
0
ファイル: html_r.c プロジェクト: ebichu/dd-wrt
void put_chars(struct part *p, unsigned char *c, int l)
{
	static struct text_attrib_beginning ta_cache = { -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
	static int bg_cache;
	static int fg_cache;

	int bg, fg;
	int i;
	struct link *link;
	struct point *pt;
	if (l < 0) overalloc();
	/*printf("%d-", p->cx);for (i=0; i<l; i++) printf("%c", c[i]); printf("-\n");sleep(1);*/
	while (par_format.align != AL_NO && p->cx == -1 && l && *c == ' ') c++, l--;
	if (!l) return;
	if (c[0] != ' ' || (c[1] && c[1] != ' ')) {
		last_tag_for_newline = (void *)&p->data->tags;
	}
	if (p->cx < par_format.leftmargin) p->cx = par_format.leftmargin;
	if (last_link || last_image || last_form || format.link || format.image || format.form) goto process_link;
	no_l:
	/*printf("%d %d\n",p->cx, p->cy);*/
	if (memcmp(&ta_cache, &format, sizeof(struct text_attrib_beginning))) goto format_change;
	bg = bg_cache, fg = fg_cache;
	end_format_change:
	if (p->cx == par_format.leftmargin && *c == ' ' && par_format.align != AL_NO) c++, l--;
	if (p->y < p->cy + 1) p->y = p->cy + 1;
	if (nowrap && p->cx + l > rm(par_format)) return;
	set_hline(p, p->cx, p->cy, l, c, (((fg&0x08)<<3)|(bg<<3)|(fg&0x07))<<8, 1);
	p->cx += l;
	nobreak = 0;
	if (par_format.align != AL_NO)
		while (p->cx > rm(par_format) && p->cx > par_format.leftmargin) {
			int x;
			/*if (p->cx > p->x) {
				p->x = p->cx + par_format.rightmargin;
				if (c[l - 1] == ' ') p->x--;
			}*/
			if (!(x = split_line(p))) break;
			/*if (LEN(p->cy-1) > p->x) p->x = LEN(p->cy-1);*/
			align_line(p, p->cy - 1);
			nobreak = x - 1;
		}
	if ((p->xa += l) - (c[l-1] == ' ' && par_format.align != AL_NO) + par_format.leftmargin + par_format.rightmargin > p->xmax) p->xmax = p->xa - (c[l-1] == ' ' && par_format.align != AL_NO) + par_format.leftmargin + par_format.rightmargin;
	return;
	process_link:
	if ((last_link /*|| last_target*/ || last_image || last_form) &&
	    !xstrcmp(format.link, last_link) && !xstrcmp(format.target, last_target) &&
	    !xstrcmp(format.image, last_image) && format.form == last_form) {
		if (!p->data) goto x;
		link = &p->data->links[p->data->nlinks - 1];
		if (!p->data->nlinks) {
			internal("no link");
			goto no_l;
		}
		goto set_link;
		x:;
	} else {
		if (last_link) mem_free(last_link);	/* !!! FIXME: optimize */
		if (last_target) mem_free(last_target);
		if (last_image) mem_free(last_image);
		last_link = last_target = last_image = NULL;
		last_form = NULL;
		if (!(format.link || format.image || format.form)) goto no_l;
		if (d_opt->num_links) {
			unsigned char s[64];
			unsigned char *fl = format.link, *ft = format.target, *fi = format.image;
			struct form_control *ff = format.form;
			format.link = format.target = format.image = NULL;
			format.form = NULL;
			s[0] = '[';
			snzprint(s + 1, 62, p->link_num);
			strcat(s, "]");
			put_chars(p, s, strlen(s));
			if (ff && ff->type == FC_TEXTAREA) line_break(p);
			if (p->cx == -1) p->cx = par_format.leftmargin;
			format.link = fl, format.target = ft, format.image = fi;
			format.form = ff;
		}
		p->link_num++;
		last_link = stracpy(format.link);
		last_target = stracpy(format.target);
		last_image = stracpy(format.image);
		last_form = format.form;
		if (!p->data) goto no_l;
		if (!(link = new_link(p->data))) goto no_l;
		link->num = p->link_num - 1;
		link->pos = DUMMY;
		if (!last_form) {
			link->type = L_LINK;
			link->where = stracpy(last_link);
			link->target = stracpy(last_target);
		} else {
			link->type = last_form->type == FC_TEXT || last_form->type == FC_PASSWORD || last_form->type == FC_FILE ? L_FIELD : last_form->type == FC_TEXTAREA ? L_AREA : last_form->type == FC_CHECKBOX || last_form->type == FC_RADIO ? L_CHECKBOX : last_form->type == FC_SELECT ? L_SELECT : L_BUTTON;
			link->form = last_form;
			link->target = stracpy(last_form->target);
		}
		link->where_img = stracpy(last_image);
		if (link->type != L_FIELD && link->type != L_AREA) {
			bg = find_nearest_color(&format.clink, 8);
			fg = find_nearest_color(&format.bg, 8);
			fg = fg_color(fg, bg);
		} else {
			fg = find_nearest_color(&format.fg, 8);
			bg = find_nearest_color(&format.bg, 8);
			fg = fg_color(fg, bg);
		}
		link->sel_color = ((fg & 8) << 3) | (fg & 7) | (bg << 3);
		link->n = 0;
		set_link:
		if ((unsigned)link->n + (unsigned)l > MAXINT / sizeof(struct point)) overalloc();
		pt = mem_realloc(link->pos, (link->n + l) * sizeof(struct point));
		link->pos = pt;
		for (i = 0; i < l; i++) pt[link->n + i].x = X(p->cx) + i,
					pt[link->n + i].y = Y(p->cy);
		link->n += l;
	}
	goto no_l;

		format_change:
		bg = find_nearest_color(&format.bg, 8);
		fg = find_nearest_color(&format.fg, 16);
		fg = fg_color(fg, bg);
		if (format.attr & AT_ITALIC) fg = fg ^ 0x01;
		if (format.attr & AT_UNDERLINE) fg = (fg ^ 0x04) | 0x08;
		if (format.attr & AT_BOLD) fg = fg | 0x08;
		fg = fg_color(fg, bg);
		if (format.attr & AT_GRAPHICS) bg = bg | 0x10;
		memcpy(&ta_cache, &format, sizeof(struct text_attrib_beginning));
		fg_cache = fg; bg_cache = bg;
		goto end_format_change;
}
コード例 #25
0
ファイル: html_r.c プロジェクト: ebichu/dd-wrt
struct frameset_desc *create_frameset(struct f_data *fda, struct frameset_param *fp)
{
	int i;
	struct frameset_desc *fd;
	if (!fp->x || !fp->y) {
		internal("zero size of frameset");
		return NULL;
	}
	if (fp->x && (unsigned)fp->x * (unsigned)fp->y / (unsigned)fp->x != (unsigned)fp->y) overalloc();
	if ((unsigned)fp->x * (unsigned)fp->y > (MAXINT - sizeof(struct frameset_desc)) / sizeof(struct frame_desc)) overalloc();
	fd = mem_alloc(sizeof(struct frameset_desc) + fp->x * fp->y * sizeof(struct frame_desc));
	memset(fd, 0, sizeof(struct frameset_desc) + fp->x * fp->y * sizeof(struct frame_desc));
	fd->n = fp->x * fp->y;
	fd->x = fp->x;
	fd->y = fp->y;
	for (i = 0; i < fd->n; i++) {
		fd->f[i].xw = fp->xw[i % fp->x];
		fd->f[i].yw = fp->yw[i / fp->x];
	}
	if (fp->parent) add_frameset_entry(fp->parent, fd, NULL, NULL);
	else if (!fda->frame_desc) fda->frame_desc = fd;
	     else mem_free(fd), fd = NULL;
	return fd;
}
コード例 #26
0
void in_term(struct terminal *term)
{
    struct event *ev;
    int r;
    unsigned char *iq;
    if ((unsigned)term->qlen + ALLOC_GR > MAXINT) overalloc();
    iq = mem_realloc(term->input_queue, term->qlen + ALLOC_GR);
    term->input_queue = iq;
    if ((r = read(term->fdin, iq + term->qlen, ALLOC_GR)) <= 0) {
        if (r == -1 && errno != ECONNRESET) error("ERROR: error %d on terminal: could not read event", errno);
        destroy_terminal(term);
        return;
    }
    term->qlen += r;
test_queue:
    if ((size_t)term->qlen < sizeof(struct event)) return;
    ev = (struct event *)iq;
    r = sizeof(struct event);
    if (ev->ev != EV_INIT && ev->ev != EV_RESIZE && ev->ev != EV_REDRAW && ev->ev != EV_KBD && ev->ev != EV_MOUSE && ev->ev != EV_ABORT) {
        error("ERROR: error on terminal: bad event %d", ev->ev);
        goto mm;
    }
    if (ev->ev == EV_INIT) {
        int init_len;
        if ((size_t)term->qlen < sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int)) return;
        init_len = *(int *)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + sizeof(int));
        if ((size_t)term->qlen < sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int) + init_len) return;
        memcpy(term->term, iq + sizeof(struct event), MAX_TERM_LEN);
        term->term[MAX_TERM_LEN - 1] = 0;
        memcpy(term->cwd, iq + sizeof(struct event) + MAX_TERM_LEN, MAX_CWD_LEN);
        term->cwd[MAX_CWD_LEN - 1] = 0;
        term->environment = *(int *)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN);
        ev->b = (long)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + sizeof(int));
        r = sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int) + init_len;
        sync_term_specs();
    }
    if (ev->ev == EV_REDRAW || ev->ev == EV_RESIZE || ev->ev == EV_INIT) {
        struct window *win;
send_redraw:
        if (ev->x < 0 || ev->y < 0) {
            error("ERROR: bad terminal size: %d, %d", (int)ev->x, (int)ev->y);
            goto mm;
        }
        alloc_term_screen(term, ev->x, ev->y);
        clear_terminal(term);
        erase_screen(term);
        term->redrawing = 1;
        foreachback(win, term->windows) win->handler(win, ev, 0);
        term->redrawing = 0;
    }
    if (ev->ev == EV_KBD || ev->ev == EV_MOUSE) {
        if (ev->ev == EV_KBD && upcase(ev->x) == 'L' && ev->y == KBD_CTRL) {
            ev->ev = EV_REDRAW;
            ev->x = term->x;
            ev->y = term->y;
            goto send_redraw;
        }
        else if (ev->ev == EV_KBD && ev->x == KBD_CTRL_C) ((struct window *)term->windows.prev)->handler(term->windows.prev, ev, 0);
        else ((struct window *)term->windows.next)->handler(term->windows.next, ev, 0);
    }
    if (ev->ev == EV_ABORT) {
        destroy_terminal(term);
        return;
    }
    /*redraw_screen(term);*/
mm:
    if (term->qlen == r) term->qlen = 0;
    else memmove(iq, iq + r, term->qlen -= r);
    goto test_queue;
}
コード例 #27
0
void jpeg_restart(struct cached_image *cimg, unsigned char *data, int length)
{
	struct jpg_decoder *deco;

	deco=(struct jpg_decoder *)(cimg->decoder);
#ifdef DEBUG
	if (!deco) internal("NULL decoder in jpeg_restart");
#endif /* #ifdef DEBUG */
	global_cinfo=((struct jpg_decoder *)(cimg->decoder))->cinfo;
	global_jerr=((struct jpg_decoder *)(cimg->decoder))->jerr;
	/* These global variables are here so that we don't have to pass lots
	 * of structure pointers into each function. The jpeg decoder is never
	 * running twice at the same time so it doesn't matter.
	 */

	/* If the decoder wants us to skip bytes it's not interested in */
	if (deco->skip_bytes>=length){
		/* If the decoder wants to skip as much as or more bytes than
		 * the chunk that has just arrived */
		deco->skip_bytes-=length;
		return;
	}else{
		/* If the decoder wants to skip less bytes than the chunk
		 * that has just arrived */
		data+=deco->skip_bytes;
		length-=deco->skip_bytes;
		deco->skip_bytes=0;
	}

	/* Add the arrived data chunk into the decoder buffer. Sometimes the
	 * chunks are so small the decoder can't move on on a single chunk
	 * so it has to accumulate more chunks together. This is why the buffer
	 * is there. */
	if ((unsigned)global_cinfo->src->bytes_in_buffer + (unsigned)length > MAXINT) overalloc();
	if ((unsigned)global_cinfo->src->bytes_in_buffer + (unsigned)length < (unsigned)length) overalloc();
	if (deco->jdata){
		/* If there is already some decoder buffer, we have to
		 * allocate more space */
		memmove(deco->jdata,global_cinfo->src->next_input_byte,
			global_cinfo->src->bytes_in_buffer);
		deco->jdata=mem_realloc(
			deco->jdata, global_cinfo->src->bytes_in_buffer+length);
	}else{
		/* If there is no decoder buffer we'll have to allocate
		 * space for a new buffer */
		deco->jdata=mem_alloc(global_cinfo->src->bytes_in_buffer+length);
	}

	/* Copy the data iself into the decoder buffer */
	memcpy(deco->jdata+global_cinfo->src->bytes_in_buffer
		,data,length);

	/* Update the next input byte pointer for the decoder to continue at
	 * the right position */
	global_cinfo->src->next_input_byte=deco->jdata;

	/* ...:::...:..:.:::.:.::::.::.:.:.:.::..::::.::::.:...: */
	/* Update the length of data in the decoder buffer */
	global_cinfo->src->bytes_in_buffer+=length;

	if (setjmp(global_jerr->setjmp_buffer)) goto decoder_ended;
	switch(deco->state){
		case 0:
		/* jpeg_read_header */
	   	if (JPEG_SUSPENDED==jpeg_read_header(global_cinfo,TRUE))
			break;
		global_cinfo->buffered_image=TRUE;
		deco->state=1;

		case 1:
		/* If the scaling is sufficiently brutal we can leave out
		 * some DCT coefficients...: */
		/* jpeg_start_decompress */
		if (jpeg_start_decompress(global_cinfo)==FALSE)
			break;

		cimg->width=global_cinfo->output_width;
		cimg->height=global_cinfo->output_height;

		switch(cimg->buffer_bytes_per_pixel=
			global_cinfo->output_components)
		{
			case 1:
				/* We'll do the conversion ourselves
				 * because libjpeg seems to be buggy */
				cimg->buffer_bytes_per_pixel=3;
				break;


			case 3: /* RGB or YCrCb. We will ask libjpeg to
				 * possibly convert from YCrCb to RGB. */

				global_cinfo->out_color_space=JCS_RGB;
				break;

			case 4:
				/* CMYK or YCCK. We need to enable conversion
				 * to CMYK and then convert CMYK data to RGBA
				 * with dummy A ourselves.
				 * We will ask libjpeg to possibly convert from
				 * YCCK to CMYK. */
				global_cinfo->out_color_space=JCS_CMYK;
				break;

			default:
			/* Let's make a decompression fatal error here */

			if (!mesg_unsup_emitted){
				fprintf(stderr,
			"Unsupported JPEG output components number: %d.\n",
			cimg->buffer_bytes_per_pixel);
				mesg_unsup_emitted=1;
			}
			longjmp(global_jerr->setjmp_buffer,2);

			/* longjmp()  and  siglongjmp() make programs hard to
			 * understand and maintain.  If possible an alternative
			 * should be used. Hahaha :) ;-)
			 */
			/* Free will makes people hard to understand 
			 * and maintain. If possible an alternative should be 
			 * used.
			 */
			/* With our new LongJump(TM) your jumps will be longer
			 * than with ordinary commercially available jumps.
			 */
		}
		cimg->red_gamma=sRGB_gamma;
		cimg->green_gamma=sRGB_gamma;
		cimg->blue_gamma=sRGB_gamma;
		/* This is defined in the JPEG standard somehow that sRGB
		 * color space is used. */

		cimg->strip_optimized=0;
		/* Strip optimization yet waits to be written. This will
		 * allow huge jpegs to be processed without consuming
		 * Links memory and consuming Xserver memory instead ;-)
		 * However strip optimization is already written for PNG's.
		 */

		header_dimensions_known(cimg);
new_scan:
		deco->state=2;

		case 2:
		/* jpeg_start_output */
		if (FALSE==jpeg_start_output(global_cinfo,global_cinfo->input_scan_number)){
susp0:
			/* Suspended */
			break;
		}
		deco->state=3;

		case 3:
		/* jpeg_read_scanlines */
			/* color */
        	while (global_cinfo->output_scanline
			<global_cinfo->output_height){
			int a, lines;

			for (a=0;a<16;a++){
				deco->scanlines[a]=cimg->buffer
				+(global_cinfo
				->output_scanline+a)
				*global_cinfo->output_width*cimg->
					buffer_bytes_per_pixel;
			}
		
         		if ((lines=
				jpeg_read_scanlines(
				global_cinfo,deco->scanlines,1))){
				/* Some lines were written into cimg buffer */
				cimg->rows_added=1;
				
				fix_data(deco, lines);
			}else{
				/* No lines have been written into cimg
				 * buffer */
                	 	/* We are suspended and we want more data */
         	 		goto susp0; /* Break the outer 
					     * switch statement */
			}
		}
		deco->state=4;

		case 4:
		/* jpeg_finish_output */
		if (FALSE==jpeg_finish_output(global_cinfo))
		{
			/* Suspended */
			break;
		}
		if (!jpeg_input_complete(global_cinfo))
		{
			/* Some more scans awaited... */
			goto new_scan;
		}
		deco->state=5;

		case 5:
		/* jpeg_finish_decompress */
		if (FALSE==jpeg_finish_decompress(global_cinfo))
			break;
decoder_ended:
		img_end(cimg);
	}
}
コード例 #28
0
ファイル: html_tbl.c プロジェクト: ebichu/dd-wrt
struct table *parse_table(unsigned char *html, unsigned char *eof, unsigned char **end, struct rgb *bgcolor, int sh, struct s_e **bad_html, int *bhp)
{
	int qqq;
	struct table *t;
	struct table_cell *cell;
	unsigned char *t_name, *t_attr, *en;
	int t_namelen;
	int x = 0, y = -1;
	int p = 0;
	unsigned char *lbhp = NULL;
	int l_al = AL_LEFT;
	int l_val = VAL_MIDDLE;
	int csp, rsp;
	int group = 0;
	int i, j, k;
	struct rgb l_col;
	int c_al = AL_TR, c_val = VAL_TR, c_width = W_AUTO, c_span = 0;
	memcpy(&l_col, bgcolor, sizeof(struct rgb));
	*end = html;
	if (bad_html) {
		*bad_html = DUMMY;
		*bhp = 0;
	}
	if (!(t = new_table())) return NULL;
	se:
	en = html;
	see:
	html = en;
	if (bad_html && !p && !lbhp) {
		if (!(*bhp & (ALLOC_GR-1))) {
			if ((unsigned)*bhp > MAXINT / sizeof(struct s_e) - ALLOC_GR) overalloc();
			*bad_html = mem_realloc(*bad_html, (*bhp + ALLOC_GR) * sizeof(struct s_e));
		}
		lbhp = (*bad_html)[(*bhp)++].s = html;
	}
	while (html < eof && *html != '<') html++;
	if (html >= eof) {
		if (p) CELL(t, x, y)->end = html;
		if (lbhp) (*bad_html)[*bhp-1].e = html;
		goto scan_done;
	}
	if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) {
		html = skip_comment(html, eof);
		goto se;
	}
	if (parse_element(html, eof, &t_name, &t_namelen, &t_attr, &en)) {
		html++;
		goto se;
	}
	if (t_namelen == 5 && !casecmp(t_name, "TABLE", 5)) {
		en = skip_table(en, eof);
		goto see;
	}
	if (t_namelen == 6 && !casecmp(t_name, "/TABLE", 6)) {
		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);
		if (p) CELL(t, x, y)->end = html;
		if (lbhp) (*bad_html)[*bhp-1].e = html;
		goto scan_done;
	}
	if (t_namelen == 8 && !casecmp(t_name, "COLGROUP", 8)) {
		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);
		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;
		c_al = AL_TR;
		c_val = VAL_TR;
		c_width = W_AUTO;
		get_align(t_attr, &c_al);
		get_valign(t_attr, &c_val);
		get_c_width(t_attr, &c_width, sh);
		if ((c_span = get_num(t_attr, "span")) == -1) c_span = 1;
		goto see;
	}
	if (t_namelen == 9 && !casecmp(t_name, "/COLGROUP", 9)) {
		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);
		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;
		c_span = 0;
		c_al = AL_TR;
		c_val = VAL_TR;
		c_width = W_AUTO;
		goto see;
	}
	if (t_namelen == 3 && !casecmp(t_name, "COL", 3)) {
		int sp, wi, al, val;
		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;
		if ((sp = get_num(t_attr, "span")) == -1) sp = 1;
		wi = c_width;
		al = c_al;
		val = c_val;
		get_align(t_attr, &al);
		get_valign(t_attr, &val);
		get_c_width(t_attr, &wi, sh);
		new_columns(t, sp, wi, al, val, !!c_span);
		c_span = 0;
		goto see;
	}
	if (t_namelen == 3 && (!casecmp(t_name, "/TR", 3) || !casecmp(t_name, "/TD", 3) || !casecmp(t_name, "/TH", 3))) {
		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);
		if (p) CELL(t, x, y)->end = html, p = 0;
		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;
	}
	if (t_namelen == 2 && !casecmp(t_name, "TR", 2)) {
		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);
		if (p) CELL(t, x, y)->end = html, p = 0;
		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;
		if (group) group--;
		l_al = AL_LEFT;
		l_val = VAL_MIDDLE;
		memcpy(&l_col, bgcolor, sizeof(struct rgb));
		get_align(t_attr, &l_al);
		get_valign(t_attr, &l_val);
		get_bgcolor(t_attr, &l_col);
		y++, x = 0;
		goto see;
	}
	if (t_namelen == 5 && ((!casecmp(t_name, "THEAD", 5)) || (!casecmp(t_name, "TBODY", 5)) || (!casecmp(t_name, "TFOOT", 5)))) {
		if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);
		if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;
		group = 2;
	}
	if (t_namelen != 2 || (casecmp(t_name, "TD", 2) && casecmp(t_name, "TH", 2))) goto see;
	if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1);
	if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL;
	if (p) CELL(t, x, y)->end = html, p = 0;
	if (y == -1) y = 0, x = 0;
	nc:
	cell = new_cell(t, x, y);
	if (cell->used) {
		if (cell->colspan == -1) goto see;
		x++;
		goto nc;
	}
	cell->mx = x;
	cell->my = y;
	cell->used = 1;
	cell->start = en;
	p = 1;
	cell->align = l_al;
	cell->valign = l_val;
	if ((cell->b = upcase(t_name[1]) == 'H')) cell->align = AL_CENTER;
	if (group == 1) cell->group = 1;
	if (x < t->c) {
		if (t->cols[x].align != AL_TR) cell->align = t->cols[x].align;
		if (t->cols[x].valign != VAL_TR) cell->valign = t->cols[x].valign;
	}
	memcpy(&cell->bgcolor, &l_col, sizeof(struct rgb));
	get_align(t_attr, &cell->align);
	get_valign(t_attr, &cell->valign);
	get_bgcolor(t_attr, &cell->bgcolor);
	if ((csp = get_num(t_attr, "colspan")) == -1) csp = 1;
	if (!csp) csp = -1;
	if ((rsp = get_num(t_attr, "rowspan")) == -1) rsp = 1;
	if (!rsp) rsp = -1;
	if (csp >= 0 && rsp >= 0 && csp * rsp > 100000) {
		if (csp > 10) csp = -1;
		if (rsp > 10) rsp = -1;
	}
	cell->colspan = csp;
	cell->rowspan = rsp;
	if (csp == 1) {
		int w = W_AUTO;
		get_c_width(t_attr, &w, sh);
		if (w != W_AUTO) set_td_width(t, x, w, 0);
	}
	qqq = t->x;
	for (i = 1; csp != -1 ? i < csp : x + i < qqq; i++) {
		struct table_cell *sc = new_cell(t, x + i, y);
		if (sc->used) {
			csp = i;
			for (k = 0; k < i; k++) CELL(t, x + k, y)->colspan = csp;
			break;
		}
		sc->used = sc->spanned = 1;
		sc->rowspan = rsp;
		sc->colspan = csp;
		sc->mx = x;
		sc->my = y;
	}
	qqq = t->y;
	for (j = 1; rsp != -1 ? j < rsp : y + j < qqq; j++) {
		for (k = 0; k < i; k++) {
			struct table_cell *sc = new_cell(t, x + k, y + j);
			if (sc->used) {
				int l, m;
				if (sc->mx == x && sc->my == y) continue;
				/*internal("boo");*/
				for (l = 0; l < k; l++) memset(CELL(t, x + l, y + j), 0, sizeof(struct table_cell));
				rsp = j;
				for (l = 0; l < i; l++) for (m = 0; m < j; m++) CELL(t, x + l, y + m)->rowspan = j;
				goto brk;
			}
			sc->used = sc->spanned = 1;
			sc->rowspan = rsp;
			sc->colspan = csp;
			sc->mx = x;
			sc->my = y;
		}
	}
	brk:
	goto see;

	scan_done:
	*end = html;

	for (x = 0; x < t->x; x++) for (y = 0; y < t->y; y++) {
		struct table_cell *c = CELL(t, x, y);
		if (!c->spanned) {
			if (c->colspan == -1) c->colspan = t->x - x;
			if (c->rowspan == -1) c->rowspan = t->y - y;
		}
	}

	if ((unsigned)t->y > MAXINT / sizeof(int)) overalloc();
	t->r_heights = mem_alloc(t->y * sizeof(int));
	memset(t->r_heights, 0, t->y * sizeof(int));

	for (x = 0; x < t->c; x++) if (t->cols[x].width != W_AUTO) set_td_width(t, x, t->cols[x].width, 1);
	set_td_width(t, t->x, W_AUTO, 0);

	return t;
}
コード例 #29
0
ファイル: html_tbl.c プロジェクト: ebichu/dd-wrt
void check_table_widths(struct table *t)
{
	int *w;
	int i, j;
	int s, ns;
	int m, mi = 0; /* go away, warning! */
	if ((unsigned)t->x > MAXINT / sizeof(int)) overalloc();
	w = mem_alloc(t->x * sizeof(int));
	memset(w, 0, t->x * sizeof(int));
	for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) {
		struct table_cell *c = CELL(t, i, j);
		int k, p = 0;
		if (!c->start) continue;
		for (k = 1; k < c->colspan; k++) p += get_vline_width(t, i + k) >= 0;
		for (k = 0; k < c->colspan; k++) p += t->w_c[i + k];
		get_cell_width(c->start, c->end, t->cellpd, p, 1, &c->x_width, NULL, c->link_num, NULL);
		if (c->x_width > p) {
			/*int min, max;
			get_cell_width(c->start, c->end, t->cellpd, 0, 0, &min, &max, c->link_num, NULL);
			internal("cell is now wider (%d > %d) min = %d, max = %d, now_min = %d, now_max = %d", c->x_width, p, t->min_c[i], t->max_c[i], min, max);*/
			/* sbohem, internale. chytl jsi mi spoustu chyb v tabulkovaci, ale ted je proste cas jit ... ;-( */
			c->x_width = p;
		}
	}
	s = 1;
	do {
		ns = MAXINT;
		for (i = 0; i < t->x; i++) for (j = 0; j < t->y; j++) {
			struct table_cell *c = CELL(t, i, j);
			if (!c->start) continue;
			if (c->colspan + i > t->x) {
				/*internal("colspan out of table");*/
				mem_free(w);
				return;
			}
			if (c->colspan == s) {
				int k, p = 0;
				for (k = 1; k < s; k++) p += get_vline_width(t, i + k) >= 0;
				dst_width(w + i, s, c->x_width - p, t->max_c + i);
				/*for (k = i; k < i + s; k++) if (w[k] > t->w_c[k]) {
					int l;
					int c;
					ag:
					c = 0;
					for (l = i; l < i + s; l++) if (w[l] < t->w_c[k]) w[l]++, w[k]--, c = 1;
					if (w[k] > t->w_c[k]) {
						if (!c) internal("can't shrink cell");
						else goto ag;
					}
				}*/
			} else if (c->colspan > s && c->colspan < ns) ns = c->colspan;
		}
	} while ((s = ns) != MAXINT);

	s = 0; ns = 0;
	for (i = 0; i < t->x; i++) {
		s += t->w_c[i], ns += w[i];
		/*if (w[i] > t->w_c[i]) {
			int k;
			for (k = 0; k < t->x; k++) debug("%d, %d", t->w_c[k], w[k]);
			debug("column %d: new width(%d) is larger than previous(%d)", i, w[i], t->w_c[i]);
		}*/
	}
	if (ns > s) {
		/*internal("new width(%d) is larger than previous(%d)", ns, s);*/
		mem_free(w);
		return;
	}
	m = -1;
	for (i = 0; i < t->x; i++) {
		/*if (table_level == 1) debug("%d: %d %d %d %d", i, t->max_c[i], t->min_c[i], t->w_c[i], w[i]);*/
		if (t->max_c[i] > m) m = t->max_c[i], mi = i;
	}
	/*if (table_level == 1) debug("%d %d", mi, s - ns);*/
	if (m != -1) {
		w[mi] += s - ns;
		if (w[mi] <= t->max_c[mi]) {
			mem_free(t->w_c);
			t->w_c = w;
			return;
		}
	}
	mem_free(w);
}
コード例 #30
0
ファイル: html_tbl.c プロジェクト: ebichu/dd-wrt
void display_table_frames(struct table *t, int x, int y)
{
	signed char *fh, *fv;
	int i, j;
	int cx, cy;
	if ((unsigned)t->x > MAXINT) overalloc();
	if ((unsigned)t->y > MAXINT) overalloc();
	if (((unsigned)t->x + 2) * ((unsigned)t->y + 2) / ((unsigned)t->x + 2) != ((unsigned)t->y + 2)) overalloc();
	if (((unsigned)t->x + 2) * ((unsigned)t->y + 2) > MAXINT) overalloc();
	fh = mem_alloc((t->x + 2) * (t->y + 1));
	memset(fh, -1, (t->x + 2) * (t->y + 1));
	fv = mem_alloc((t->x + 1) * (t->y + 2));
	memset(fv, -1, (t->x + 1) * (t->y + 2));
#ifndef DEBUG
#define H_LINE_X(xx, yy) fh[(xx) + 1 + (t->x + 2) * (yy)]
#define V_LINE_X(xx, yy) fv[(yy) + 1 + (t->y + 2) * (xx)]
#else
#define H_LINE_X(xx, yy) (*(xx < -1 || xx > t->x + 1 || yy < 0 || yy > t->y ? (signed char *)NULL : &fh[(xx) + 1 + (t->x + 2) * (yy)]))
#define V_LINE_X(xx, yy) (*(xx < 0 || xx > t->x || yy < -1 || yy > t->y + 1 ? (signed char *)NULL : &fv[(yy) + 1 + (t->y + 2) * (xx)]))
#endif
#define H_LINE(xx, yy) (H_LINE_X((xx), (yy)) == -1 ? 0 : H_LINE_X((xx), (yy)))
#define V_LINE(xx, yy) (V_LINE_X((xx), (yy)) == -1 ? 0 : V_LINE_X((xx), (yy)))
	for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) {
		int x, y;
		int xsp, ysp;
		struct table_cell *cell = CELL(t, i, j);
		if (!cell->used || cell->spanned) continue;
		if ((xsp = cell->colspan) == 0) xsp = t->x - i;
		if ((ysp = cell->rowspan) == 0) ysp = t->y - j;
		if (t->rules != R_NONE && t->rules != R_COLS) for (x = 0; x < xsp; x++) {H_LINE_X(i + x, j) = t->cellsp; H_LINE_X(i + x, j + ysp) = t->cellsp;}
		if (t->rules != R_NONE && t->rules != R_ROWS) for (y = 0; y < ysp; y++) {V_LINE_X(i, j + y) = t->cellsp; V_LINE_X(i + xsp, j + y) = t->cellsp;}
	}
	if (t->rules == R_GROUPS) {
		for (i = 1; i < t->x; i++) {
			if (/*i < t->xc &&*/ t->xcols[i]) continue;
			for (j = 0; j < t->y; j++) V_LINE_X(i, j) = 0;
		}
		for (j = 1; j < t->y; j++) {
			for (i = 0; i < t->x; i++) if (CELL(t, i, j)->group) goto c;
			for (i = 0; i < t->x; i++) H_LINE_X(i, j) = 0;
			c:;
		}
	}
	for (i = 0; i < t->x; i++) {
		H_LINE_X(i, 0) = t->border * !!(t->frame & F_ABOVE);
		H_LINE_X(i, t->y) = t->border * !!(t->frame & F_BELOW);
	}
	for (j = 0; j < t->y; j++) {
		V_LINE_X(0, j) = t->border * !!(t->frame & F_LHS);
		V_LINE_X(t->x, j) = t->border * !!(t->frame & F_RHS);
	}

	cy = y;
	for (j = 0; j <= t->y; j++) {
		cx = x;
		if ((j > 0 && j < t->y && get_hline_width(t, j) >= 0) || (j == 0 && t->border && (t->frame & F_ABOVE)) || (j == t->y && t->border && (t->frame & F_BELOW))) {
			for (i = 0; i < t->x; i++) {
				int w;
				if (i > 0) w = get_vline_width(t, i);
				else w = t->border && (t->frame & F_LHS) ? t->border : -1;
				if (w >= 0) {
					draw_frame_point(cx, cy, i, j);
					if (j < t->y) draw_frame_vline(cx, cy + 1, t->r_heights[j], i, j);
					cx++;
				}
				w = t->w_c[i];
				draw_frame_hline(cx, cy, w, i, j);
				cx += w;
			}
			if (t->border && (t->frame & F_RHS)) {
				draw_frame_point(cx, cy, i, j);
				if (j < t->y) draw_frame_vline(cx, cy + 1, t->r_heights[j], i, j);
				cx++;
			}
			cy++;
		} else if (j < t->y) {
			for (i = 0; i <= t->x; i++) {
				if ((i > 0 && i < t->x && get_vline_width(t, i) >= 0) || (i == 0 && t->border && (t->frame & F_LHS)) || (i == t->x && t->border && (t->frame & F_RHS))) {
					draw_frame_vline(cx, cy, t->r_heights[j], i, j);
					cx++;
				}
				if (i < t->x) cx += t->w_c[i];
			}
		}
		if (j < t->y) cy += t->r_heights[j];
		/*for (cyy = cy1; cyy < cy; cyy++) xxpand_line(t->p, cyy, cx - 1);*/
	}
	mem_free(fh);
	mem_free(fv);
}