handle errors in image data, modified base64 decode to handle white space

This commit is contained in:
Stefan Frederik 2022-01-20 18:28:29 +01:00
parent 6fcdd46022
commit a3ccc094f5
17 changed files with 520 additions and 115 deletions

View File

@ -2572,6 +2572,7 @@ typedef struct
static cairo_status_t png_reader(void *in_closure, unsigned char *out_data, unsigned int length)
{
png_to_byte_closure_t *closure = (png_to_byte_closure_t *) in_closure;
if(!closure->buffer) return CAIRO_STATUS_READ_ERROR;
memcpy(out_data, closure->buffer + closure->pos, length);
closure->pos += length;
return CAIRO_STATUS_SUCCESS;
@ -2580,6 +2581,7 @@ static cairo_status_t png_reader(void *in_closure, unsigned char *out_data, unsi
static cairo_status_t png_writer(void *in_closure, const unsigned char *in_data, unsigned int length)
{
png_to_byte_closure_t *closure = (png_to_byte_closure_t *) in_closure;
if(!in_data) return CAIRO_STATUS_READ_ERROR;
if(closure->pos + length > closure->size) {
my_realloc(1472, &closure->buffer, closure->pos + length + 65536);
closure->size = closure->pos + length + 65536;
@ -2672,14 +2674,29 @@ int draw_images_all(void)
dbg(1, "draw_images_all() w=%d, h=%d\n", w, h);
x = X_TO_SCREEN(r->x1);
y = Y_TO_SCREEN(r->y1);
rw = abs(r->x2 - r->x1);
rh = abs(r->y2 - r->y1);
cairo_translate(xctx->cairo_save_ctx, x, y);
scalex = rw/w * xctx->mooz;
scaley = rh/h * xctx->mooz;
cairo_scale(xctx->cairo_save_ctx, scalex, scaley);
cairo_set_source_surface(xctx->cairo_save_ctx, emb_ptr->image, 0. , 0.);
cairo_paint(xctx->cairo_save_ctx);
if(r->flags & 2048) { /* resize container rectangle to fit image */
r->x2 = r->x1 + w;
r->y2 = r->y1 + h;
scalex = xctx->mooz;
scaley = xctx->mooz;
} else { /* resize image to fit in rectangle */
rw = abs(r->x2 - r->x1);
rh = abs(r->y2 - r->y1);
scalex = rw/w * xctx->mooz;
scaley = rh/h * xctx->mooz;
}
if(xctx->draw_pixmap) {
cairo_translate(xctx->cairo_save_ctx, x, y);
cairo_scale(xctx->cairo_save_ctx, scalex, scaley);
cairo_set_source_surface(xctx->cairo_save_ctx, emb_ptr->image, 0. , 0.);
cairo_paint(xctx->cairo_save_ctx);
}
if(xctx->draw_window) {
cairo_translate(xctx->cairo_ctx, x, y);
cairo_scale(xctx->cairo_ctx, scalex, scaley);
cairo_set_source_surface(xctx->cairo_ctx, emb_ptr->image, 0. , 0.);
cairo_paint(xctx->cairo_ctx);
}
cairo_restore(xctx->cairo_ctx);
cairo_restore(xctx->cairo_save_ctx);
if(bbox_set) {

View File

@ -395,7 +395,7 @@ static void edit_rect_property(int x)
{
int i, c, n;
int drw = 0;
const char *dash, *flags;
const char *dash;
int preserve;
char *oldprop=NULL;
my_strdup(67, &oldprop, xctx->rect[xctx->sel_array[0].col][xctx->sel_array[0].n].prop_ptr);
@ -433,17 +433,11 @@ static void edit_rect_property(int x)
my_strdup(99, &xctx->rect[c][n].prop_ptr,
(char *) tclgetvar("retval"));
}
set_rect_flags(&xctx->rect[c][n]); /* set cached .flags bitmask from on attributes */
if(xctx->rect[c][n].extraptr) { /* used for images, clear so will be recreated from image attr */
setup_rect_extraptr(0, &xctx->rect[c][n], NULL);
}
flags = get_tok_value(xctx->rect[c][n].prop_ptr,"flags",0);
if( strcmp(flags, "") ) {
int d = atoi(flags);
xctx->rect[c][n].flags = d >= 0? d : 0;
} else
xctx->rect[c][n].flags = 0;
dash = get_tok_value(xctx->rect[c][n].prop_ptr,"dash",0);
if( strcmp(dash, "") ) {
int d = atoi(dash);

View File

@ -93,7 +93,7 @@ void merge_box(FILE *fd)
{
int i,c,n;
xRect *ptr;
const char *dash, *flags;
const char *dash;
n = fscanf(fd, "%d",&c);
if(n != 1 || c < 0 || c >= cadlayers) {
@ -122,14 +122,7 @@ void merge_box(FILE *fd)
} else {
ptr[i].dash = 0;
}
flags = get_tok_value(ptr[i].prop_ptr,"flags",0);
if(strcmp(flags, "")) {
int d = atoi(flags);
ptr[i].flags = d >= 0 ? d : 0;
} else {
ptr[i].flags = 0;
}
set_rect_flags(&xctx->rect[c][i]); /* set cached .flags bitmask from on attributes */
select_box(c,i, SELECTED, 1);
xctx->rects[c]++;
set_modify(1);

View File

@ -25,6 +25,9 @@
#include <sys/wait.h> /* waitpid */
#endif
/* define this if you want 128 char lenght line formatted base64 text */
#undef BASE64_BREAK_LINES
/* Caller should free returned buffer */
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {
static const char b64_enc[] = {
@ -38,21 +41,37 @@ char *base64_encode(const unsigned char *data, size_t input_length, size_t *outp
'4', '5', '6', '7', '8', '9', '+', '/'
};
static int mod_table[] = {0, 2, 1};
int i, j;
int i, j, cnt;
size_t alloc_length;
char *encoded_data;
*output_length = 4 * ((input_length + 2) / 3);
encoded_data = my_malloc(1469, *output_length);
int octet_a, octet_b, octet_c, triple;
*output_length = (1 + ((4 * ((input_length + 2) / 3)) / 4096)) * 4096;
alloc_length = *output_length;
encoded_data = my_malloc(1469, alloc_length);
if (encoded_data == NULL) return NULL;
cnt = 0;
for (i = 0, j = 0; i < input_length;) {
int octet_a = i < input_length ? (unsigned char)data[i++] : 0;
int octet_b = i < input_length ? (unsigned char)data[i++] : 0;
int octet_c = i < input_length ? (unsigned char)data[i++] : 0;
int triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
encoded_data[j++] = b64_enc[(triple >> 3 * 6) & 0x3F];
encoded_data[j++] = b64_enc[(triple >> 2 * 6) & 0x3F];
encoded_data[j++] = b64_enc[(triple >> 1 * 6) & 0x3F];
encoded_data[j++] = b64_enc[(triple >> 0 * 6) & 0x3F];
octet_a = i < input_length ? (unsigned char)data[i++] : 0;
octet_b = i < input_length ? (unsigned char)data[i++] : 0;
octet_c = i < input_length ? (unsigned char)data[i++] : 0;
triple = (octet_a << 16) + (octet_b << 8) + octet_c;
if(j + 10 >= alloc_length) {
dbg(1, "alloc-length=%ld, j=%d, output_length=%ld\n", alloc_length, j, *output_length);
alloc_length += 4096;
my_realloc(1471, &encoded_data, alloc_length);
}
#ifdef BASE64_BREAK_LINES
if((cnt & 31) == 0) {
*output_length += 1;
encoded_data[j++] = '\n';
}
#endif
encoded_data[j++] = b64_enc[(triple >> 18) & 0x3F];
encoded_data[j++] = b64_enc[(triple >> 12) & 0x3F];
encoded_data[j++] = b64_enc[(triple >> 6) & 0x3F];
encoded_data[j++] = b64_enc[(triple) & 0x3F];
cnt++;
}
for (i = 0; i < mod_table[input_length % 3]; i++)
encoded_data[*output_length - 1 - i] = '=';
@ -80,28 +99,34 @@ unsigned char *base64_decode(const char *data, size_t input_length, size_t *outp
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f
};
unsigned char *decoded_data;
int i, j;
if (input_length % 4 != 0) return NULL;
*output_length = input_length / 4 * 3;
if (data[input_length - 1] == '=') (*output_length)--;
if (data[input_length - 2] == '=') (*output_length)--;
int i, j, sextet[4], triple, cnt, padding, actual_length;
actual_length = input_length;
*output_length = input_length / 4 * 3 + 4; /* add 4 more just in case... */
padding = 0;
if (data[input_length - 1] == '=') padding++;
if (data[input_length - 2] == '=') padding++;
decoded_data = my_malloc(1470, *output_length);
if (decoded_data == NULL) return NULL;
cnt = 0;
for (i = 0, j = 0; i < input_length;) {
int sextet_a = data[i] == '=' ? 0 & i++ : b64_dec[(int)data[i++]];
int sextet_b = data[i] == '=' ? 0 & i++ : b64_dec[(int)data[i++]];
int sextet_c = data[i] == '=' ? 0 & i++ : b64_dec[(int)data[i++]];
int sextet_d = data[i] == '=' ? 0 & i++ : b64_dec[(int)data[i++]];
int triple = (sextet_a << 3 * 6)
+ (sextet_b << 2 * 6)
+ (sextet_c << 1 * 6)
+ (sextet_d << 0 * 6);
if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
if(data[i] == '\n' || data[i] == ' ' || data[i] == '\r' || data[i] == '\t') {
dbg(1, "base64_decode(): white space: i=%d, cnt=%d, j=%d\n", i, cnt, j);
actual_length--;
i++;
continue;
}
sextet[cnt & 3] = data[i] == '=' ? 0 : b64_dec[(int)data[i]];
if((cnt & 3) == 3) {
triple = (sextet[0] << 18) + (sextet[1] << 12) + (sextet[2] << 6) + (sextet[3]);
decoded_data[j++] = (triple >> 16) & 0xFF;
decoded_data[j++] = (triple >> 8) & 0xFF;
decoded_data[j++] = (triple) & 0xFF;
}
cnt++;
i++;
}
*output_length = actual_length / 4 * 3 - padding;
return decoded_data;
}
@ -756,11 +781,32 @@ static void load_arc(FILE *fd)
xctx->arcs[c]++;
}
/* set cached rect .flags bitmask based on attributes, currently:
* graph 1
* graph_unlocked 1 + 2
* image 1024
* image_unscaled 1024 + 2048
*/
int set_rect_flags(xRect *r)
{
const char *flags;
unsigned short f = 0;
if(r->prop_ptr && r->prop_ptr[0]) {
flags = get_tok_value(r->prop_ptr,"flags",0);
if(!strcmp(flags, "image")) f |= 1024;
else if(!strcmp(flags, "image_unscaled")) f |= 3072;
else if(!strcmp(flags, "graph")) f |= 1;
else if(!strcmp(flags, "graph_unlocked")) f |= 3;
}
r->flags = f;
return f;
}
static void load_box(FILE *fd)
{
int i,n,c;
xRect *ptr;
const char *dash, *flags;
const char *dash;
dbg(3, "load_box(): start\n");
n = fscanf(fd, "%d",&c);
@ -790,13 +836,7 @@ static void load_box(FILE *fd)
} else {
ptr[i].dash = 0;
}
flags = get_tok_value(ptr[i].prop_ptr,"flags",0);
if(strcmp(flags, "")) {
int d = atoi(flags);
ptr[i].flags = d >= 0 ? d : 0;
} else {
ptr[i].flags = 0;
}
set_rect_flags(&xctx->rect[c][i]); /* set cached .flags bitmask from on attributes */
xctx->rects[c]++;
}

View File

@ -2634,9 +2634,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if(!strcmp(argv[1],"test"))
{
cmd_found = 1;
if(argc > 2) {
dbg(0, "%s --> %d\n", argv[2], count_items(argv[2], " \t,;"));
}
Tcl_ResetResult(interp);
}

View File

@ -256,7 +256,7 @@ void storeobject(int pos, double x1,double y1,double x2,double y2,
unsigned short sel, const char *prop_ptr)
{
int n, j;
const char *dash, *flags;
const char *dash;
if(type == LINE)
{
check_line_storage(rectc);
@ -316,13 +316,7 @@ void storeobject(int pos, double x1,double y1,double x2,double y2,
xctx->rect[rectc][n].dash = d >= 0 ? d : 0;
} else
xctx->rect[rectc][n].dash = 0;
if(prop_ptr && (flags = get_tok_value(prop_ptr,"flags",0))[0]) {
int d = atoi(flags);
xctx->rect[rectc][n].flags = d >= 0 ? d : 0;
} else
xctx->rect[rectc][n].flags = 0;
set_rect_flags(&xctx->rect[rectc][n]); /* set cached .flags bitmask from on attributes */
xctx->rects[rectc]++;
set_modify(1);
}

View File

@ -998,6 +998,7 @@ extern int cli_opt_load_initfile;
extern Xschem_ctx *xctx;
/* FUNCTIONS */
extern int set_rect_flags(xRect *r);
extern int setup_rect_extraptr(int what, xRect *drptr, xRect *srptr);
extern unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length);
extern char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length);

File diff suppressed because one or more lines are too long

View File

@ -20,22 +20,22 @@ L 4 1420 -730 1440 -750 {dash=3}
L 4 1420 -770 1420 -730 {dash=3}
L 4 1420 -770 1440 -750 {dash=3}
L 4 1350 -750 1420 -750 {dash=3}
B 2 750 -490 1410 -260 {flags=3
B 2 750 -490 1410 -260 {flags=graph
y1 = -0.0578106
y2 = 3.04806
divy = 6
x1=-0.09512
x2=3.04331
x1=-0.0234922
x2=3.11495
divx=6
node="v(a) v(zz) v(zzz)"
color="4 6 8"
sweep="v(a)"}
B 2 10 -930 570 -700 {flags=3
B 2 10 -930 570 -700 {flags=graph
y1 = -0.0578112
y2 = 3.04806
divy = 6
x1=0.242453
x2=3.38088
x1=-0.0339625
x2=3.10448
divx=6
node="v(a) v(z)"
color="4 6 8"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -14,7 +14,7 @@ L 18 900 -580 910 -580 {}
L 18 880 -530 900 -580 {}
L 18 880 -530 880 -450 {}
L 18 900 -580 900 -400 {}
B 2 1200 -860 1880 -550 {flags=1
B 2 1200 -860 1880 -550 {flags=graph
y1 = -60
y2 = 60
divy = 12
@ -24,7 +24,7 @@ divx=10
node="outp outm vpp vnn x1.vboost x0.vboost"
color="4 5 6 12 8 10" unitx=m
}
B 2 1200 -530 1880 -340 {flags=1
B 2 1200 -530 1880 -340 {flags=graph
y1 = 0
y2 = 12
divy = 6
@ -33,7 +33,7 @@ x2=0.03
divx=10
node="i(v.x1.vu) i(v.x0.vu) i(v.x1.vd) i(v.x0.vd)"
color="11 12 13 14" unitx=m}
B 2 1200 -330 1880 -140 {flags=1
B 2 1200 -330 1880 -140 {flags=graph
y1 = 0
y2 = .05
divy = 5

View File

@ -18,7 +18,7 @@ L 4 410 -150 570 -150 {}
L 4 570 -170 570 -150 {}
L 4 570 -170 690 -170 {}
L 7 1090 -260 2520 -260 {}
B 2 260 -1080 720 -920 {flags=1
B 2 260 -1080 720 -920 {flags=graph
y1 = 0
y2 = 0.93
divy = 5
@ -30,7 +30,7 @@ unitx=n
node="cal saout"
color="4 5"
}
B 2 260 -1220 720 -1090 {flags=1
B 2 260 -1220 720 -1090 {flags=graph
y1 = 0.647719
y2 = 0.652802
divy = 5

View File

@ -38,7 +38,7 @@ L 8 790 -530 790 -510 {}
L 8 770 -610 790 -610 {}
L 8 790 -610 807.5 -620 {}
L 8 810 -610 830 -610 {}
B 2 1110 -950 1530 -800 {flags=1
B 2 1110 -950 1530 -800 {flags=graph
y1 = 0
y2 = 20
divy = 5
@ -48,7 +48,7 @@ x2=0.0002
divx=9
node="v(led) v(sw)"
color="11 18" unitx=m subdivx=4}
B 2 1110 -790 1530 -660 {flags=1
B 2 1110 -790 1530 -660 {flags=graph
y1 = 0
y2 = 20
divy = 6
@ -57,7 +57,7 @@ x1=0
x2=0.0002
divx=8
node="v(panel)" unitx=m}
B 2 1110 -650 1530 -520 {flags=1
B 2 1110 -650 1530 -520 {flags=graph
y1 = 0
y2 = 4
divy = 4

View File

@ -4,7 +4,7 @@ K {}
V {}
S {}
E {}
B 2 580 -140 1200 -30 {flags=1
B 2 580 -140 1200 -30 {flags=graph
y1 = 0
y2 = 2
divy = 2
@ -15,7 +15,7 @@ comm="example of using tcl to replace the path
with $path variable automatically"
node="tcleval(v($\{path\}ldcp_ref) v($\{path\}ldprechref))"
color=12\\ 5\\ 13}
B 2 580 -230 1200 -140 {flags=1
B 2 580 -230 1200 -140 {flags=graph
y1 = 0
y2 = 2
divy = 2
@ -26,7 +26,7 @@ comm="example of using tcl to replace the path
with $path variable automatically"
node="tcleval(v($\{path\}ldcp_ref) v($\{path\}ldcpb))"
color=12\\ 5\\ 8}
B 2 580 -320 1200 -230 {flags=1
B 2 580 -320 1200 -230 {flags=graph
y1 = 0
y2 = 2
divy = 2

View File

@ -4,7 +4,7 @@ K {}
V {}
S {}
E {}
B 2 380 -820 1060 -660 {flags=1
B 2 380 -820 1060 -660 {flags=graph
y1 = 0
y2 = 2
divy = 4
@ -13,7 +13,7 @@ x2=3.4e-07
divx=8
node="v(xsa[0].ldqi) v(xsa[0].ldqib) v(xsa[0].ldsali)"
color="12\\ 5\\ 8\\ 11"}
B 2 380 -940 1060 -830 {flags=1
B 2 380 -940 1060 -830 {flags=graph
y1 = 0
y2 = 2
divy = 2
@ -22,7 +22,7 @@ x2=3.4e-07
divx=8
node="v(ldcp) v(ldprech)"
color=12\\ 5\\ 8}
B 2 380 -650 1060 -510 {flags=1
B 2 380 -650 1060 -510 {flags=graph
y1 = 0
y2 = 2
divy = 2

View File

@ -27,7 +27,7 @@ L 8 1150 -160 1180 -160 {}
L 8 1180 -160 1180 -120 {}
L 8 1180 -120 1300 -120 {}
L 8 820 -120 950 -120 {}
B 2 1840 -540 2890 -400 {flags=3
B 2 1840 -540 2890 -400 {flags=graph_unlocked
y1 = -0.048929
y2 = 0.999755
divy = 3
@ -41,7 +41,7 @@ ldbl[2] ldbl[18] ldbl[34]
"
color="8 9 10 11 12 13 14 15 16 17 18" unitx=n
}
B 2 1840 -1160 2890 -1000 {flags=3
B 2 1840 -1160 2890 -1000 {flags=graph_unlocked
digital=0
y1 = -0.021
y2 = 1.5
@ -55,7 +55,7 @@ node="ldcp ldyms[4] ldyms[5] ldyms[6] ldymsref"
color="6 12 13 14 15"
unitx=n
}
B 2 1840 -400 2890 -240 {flags=3
B 2 1840 -400 2890 -240 {flags=graph_unlocked
y1 = -0.0072
y2 = 1.6
divy = 3
@ -70,15 +70,15 @@ ldwl[7] ldwl[8] ldwl[9]"
color="4 5 4 5 4 5 4 5 4 5 4 5"
unitx=n
}
B 2 1840 -1000 2890 -540 {flags=3
B 2 1840 -1000 2890 -540 {flags=graph_unlocked
digital=1
y1 = 0
y2 = 1.6
ypos1=0.0694741
ypos2=2.61557
divy = 1
x1=1.41996e-07
x2=2.02558e-07
x1=1.39863e-07
x2=2.00425e-07
divx=12
subdivx=4
node="
@ -100,7 +100,7 @@ color="18 4 15 4 15 4 15 4 18 15 4 18 4 15 4 15 4 15 4 15 4 15 4 15 4 15"
unitx=n
ypos1=-2.20115 ypos2=2.79884
}
B 2 1840 -1300 2890 -1160 {flags=3
B 2 1840 -1300 2890 -1160 {flags=graph_unlocked
y1 = -0.022
y2 = 1.6
divy = 4
@ -111,7 +111,7 @@ unitx=n
node="xsa[0].ldqib xsa[5].ldqib xsa[0].ldsali xctrl.ldq_b"
color="4 4 5 12 "
}
B 2 1840 -240 2890 0 {flags=3
B 2 1840 -240 2890 0 {flags=graph_unlocked
y1 = -0.0559946
y2 = 0.0205097
divy = 5