links

lynx-like text mode web browser
git clone anongit@rnpnr.xyz:links.git
Log | Files | Refs | Feed | README | LICENSE

Commit: 4bd7f0e5d8d44d2b96f8606cac26490124af9dc6
Parent: 95248811b04fb31e96e1b2820b5aec28b2fdb097
Author: 0x766F6964
Date:   Thu, 21 Nov 2019 08:18:52 -0700

merge relevant changes from links-2.20(.2)

zstd support was not added

Diffstat:
MChangeLog | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcookies.c | 4++--
Mdip.c | 256++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mdither.c | 4++--
Mhtml.c | 27++++++++++++++++++---------
Mhttp.c | 25++++++++++++++++++++-----
Mimg.c | 115++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mjpeg.c | 20++++++--------------
Mkbd.c | 64+++++++++++++++++++++++++++++++++++++++++-----------------------
Mlanguage.inc | 2+-
Mlinks.h | 50++++++++++++++++++++++++--------------------------
Mlistedit.c | 2+-
Msched.c | 4+++-
Mselect.c | 2+-
Msession.c | 6+++++-
Msuffix.inc | 128++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mterminal.c | 27++++++++++++++++++++++++---
Murl.c | 45++++++++++++++++++++++++++++++++++++++++++++-
Mview.c | 6+++++-
Mx.c | 7+++----
20 files changed, 583 insertions(+), 291 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,83 @@ +=== RELEASE 2.20.2 === + +Wed Sep 18 18:39:07 CEST 2019 mikulas: + + If the user runs links on a framebuffer and switch to a differnt + framebuffer, links would incorrectly respond to mouse clicks. + +=== RELEASE 2.20.1 === + +Sun Sep 1 09:02:57 CEST 2019 mikulas: + + Fixed an error "ERROR: event_base_loop failed: Bad file descriptor" + if the user quits the master instance on OpenBSD. + + OpenBSD uses an old libevent-1.4.15 and it doesn't handle calling + event_reinit from event handler. + + libevent-2.1.11 also doesn't allow calling event_reinit from event + handler, so it is fixed as well. + +=== RELEASE 2.20 === + +Mon Aug 26 18:21:43 CEST 2019 mikulas: + + Security bug fixed: when links was connected to tor, it would send real + dns requests outside the tor network when the displayed page contains + <link rel="dns-prefetch" href="http://host.domain/">. + + This bug is present in links-2.15 to links-2.19. + + Found by Shi Tian <shitian@cock.li> + +Sat Aug 24 15:21:03 CEST 2019 Shi Tian <shitian@cock.li>: + + Fix a crash if: + External fonts are used + Rendering is optimized for LCD + The document contains some characters with zero width + +Thu Aug 22 18:47:06 CEST 2019 mikulas: + + Accept file urls in the form file://localhost/usr/bin/ or + file://hostname/usr/bin/ according to RFC 8089 + +Wed Aug 21 19:50:14 CEST 2019 mikulas: + + Report errors using dialog boxes on OS/2 and Windows because + the standard output may not be visible + +Sat Aug 17 10:20:45 CEST 2019 mikulas: + + Fixed a memory leak of the SSL structure + +Sun Aug 4 15:01:06 CEST 2019 mikulas: + + Try to open the file "/dev/input/mice" and use it instead of gpm. + (the user must be in the "input" group) + This results in smooth mouse movement on the framebuffer. + +Sat Aug 3 18:20:54 CEST 2019 mikulas: + + Report "Lynx/Links" user agent when searching on Google so that + Google returns non-css page + +Sat Apr 27 19:17:07 CEST 2019 mikulas: + + Support the zstd compression algorithm + +Tue Apr 23 21:19:31 CEST 2019 Luc Schrijvers <begasus@gmail.com>, Leorize <leorize+oss@disroot.org>, Francois Revol: + + Haiku support + +Sun Apr 21 19:32:26 CEST 2019 mikulas: + + Fix mouse dragging not being reported in xterm + +Sun Apr 7 20:18:20 CEST 2019 mikulas: + + Use proper cookie expiry + === RELEASE 2.19 === Sun Mar 31 15:59:40 CEST 2019 mikulas diff --git a/cookies.c b/cookies.c @@ -175,12 +175,12 @@ int is_path_prefix(unsigned char *d, unsigned char *s) return d[dl - 1] == '/' || !s[dl] || s[dl] == '/' || s[dl] == POST_CHAR || s[dl] == '?' || s[dl] == '&'; } -int cookie_expired(struct cookie *c) /* parse_http_date is broken */ +int cookie_expired(struct cookie *c) { time_t t; errno = 0; EINTRLOOPX(t, time(NULL), (time_t)-1); - return 0 && (c->expires && c->expires < t); + return c->expires && c->expires < t; } void add_cookies(unsigned char **s, int *l, unsigned char *url) diff --git a/dip.c b/dip.c @@ -114,8 +114,7 @@ typedef double scale_t; * black or 255 is black doesn't matter. */ -static void add_col_gray(unsigned *restrict col_buf, unsigned char *restrict ptr, int - line_skip, int n, unsigned weight) +static void add_col_gray(unsigned *restrict col_buf, unsigned char *restrict ptr, size_t line_skip, size_t n, unsigned weight) { for (;n;n--){ *col_buf+=weight*(*ptr); @@ -125,8 +124,7 @@ static void add_col_gray(unsigned *restrict col_buf, unsigned char *restrict ptr } /* We assume unsigned short holds at least 16 bits. */ -static void add_row_gray(unsigned *restrict row_buf, unsigned char *restrict ptr, int n, - unsigned weight) +static void add_row_gray(unsigned *restrict row_buf, unsigned char *restrict ptr, size_t n, unsigned weight) { for (;n;n--){ *row_buf+=weight**ptr; @@ -138,7 +136,7 @@ static void add_row_gray(unsigned *restrict row_buf, unsigned char *restrict ptr /* line_skip is in pixels. The column contains the whole pixels (R G B) * We assume unsigned short holds at least 16 bits. */ static void add_col_color(scale_t *restrict col_buf, unsigned short *restrict ptr, - int line_skip, int n, ulonglong weight) + size_t line_skip, size_t n, ulonglong weight) { if (!weight) return; { @@ -156,7 +154,7 @@ static void add_col_color(scale_t *restrict col_buf, unsigned short *restrict pt /* n is in pixels. pixel is 3 unsigned shorts in series */ /* We assume unsigned short holds at least 16 bits. */ static void add_row_color(scale_t *restrict row_buf, unsigned short *restrict ptr, - int n, ulonglong weight) + size_t n, ulonglong weight) { if (!weight) return; { @@ -173,7 +171,7 @@ static void add_row_color(scale_t *restrict row_buf, unsigned short *restrict pt /* We assume unsigned holds at least 32 bits */ static void emit_and_bias_col_gray(unsigned *restrict col_buf, unsigned char *restrict out, - int line_skip, int n, unsigned weight) + size_t line_skip, size_t n, unsigned weight) { unsigned half=weight>>1; @@ -186,7 +184,7 @@ static void emit_and_bias_col_gray(unsigned *restrict col_buf, unsigned char *re /* We assume unsigned holds at least 32 bits */ static void emit_and_bias_row_gray(unsigned *restrict row_buf, unsigned char *restrict out, - int n, unsigned weight) + size_t n, unsigned weight) { unsigned half=weight>>1; @@ -197,13 +195,13 @@ static void emit_and_bias_row_gray(unsigned *restrict row_buf, unsigned char *re } /* We assume unsigned holds at least 32 bits */ -static void bias_buf_gray(unsigned *restrict col_buf, int n, unsigned half) +static void bias_buf_gray(unsigned *restrict col_buf, size_t n, unsigned half) { for (;n;n--) *col_buf++=half; } /* We assume unsigned holds at least 32 bits */ -static void bias_buf_color(scale_t *restrict col_buf, int n, scale_t half) +static void bias_buf_color(scale_t *restrict col_buf, size_t n, scale_t half) { for (;n;n--){ col_buf[0]=half; @@ -220,7 +218,7 @@ static void bias_buf_color(scale_t *restrict col_buf, int n, scale_t half) /* We assume unsigned holds at least 32 bits */ /* We assume unsigned short holds at least 16 bits. */ static void emit_and_bias_col_color(scale_t *restrict col_buf, - unsigned short *restrict out, int line_skip, int n, unsigned weight) + unsigned short *restrict out, size_t line_skip, size_t n, unsigned weight) { scale_t half=(scale_t)weight / 2; scale_t inv_weight = (scale_t)1 / weight; @@ -245,7 +243,7 @@ static void emit_and_bias_col_color(scale_t *restrict col_buf, /* We assume unsigned holds at least 32 bits */ /* We assume unsigned short holds at least 16 bits. */ static void emit_and_bias_row_color(scale_t *restrict row_buf, - unsigned short *restrict out, int n, unsigned weight) + unsigned short *restrict out, size_t n, unsigned weight) { scale_t half = (scale_t)weight / 2; scale_t inv_weight = (scale_t)1 / weight; @@ -266,18 +264,17 @@ static void emit_and_bias_row_color(scale_t *restrict row_buf, /* For enlargement only -- does linear filtering. * Allocates output and frees input. * We assume unsigned holds at least 32 bits */ -static void enlarge_gray_horizontal(unsigned char *in, int ix, int y, - unsigned char ** out, int ox) +static void enlarge_gray_horizontal(unsigned char *in, size_t ix, size_t y, unsigned char ** out, size_t ox) { unsigned *col_buf; - int total; - int out_pos,in_pos,in_begin,in_end; - unsigned half=(ox-1)>>1; + size_t total; + size_t out_pos,in_pos,in_begin,in_end; + unsigned half = (ox - 1) >> 1; unsigned char *outptr; unsigned char *inptr; - if (ox && (unsigned)ox * (unsigned)y / (unsigned)ox != (unsigned)y) overalloc(); - if ((unsigned)ox * (unsigned)y > INT_MAX) overalloc(); + if (ox && ox * y / ox != y) overalloc(); + if (ox * y > INT_MAX) overalloc(); outptr = xmalloc(ox * y); inptr=in; *out=outptr; @@ -291,7 +288,7 @@ static void enlarge_gray_horizontal(unsigned char *in, int ix, int y, free(in); }else{ total=(ix-1)*(ox-1); - if ((unsigned)y > INT_MAX / sizeof(*col_buf)) overalloc(); + if (y > INT_MAX / sizeof(*col_buf)) overalloc(); col_buf = xmalloc(y * sizeof(*col_buf)); bias_buf_gray(col_buf, y, half); out_pos=0; @@ -299,9 +296,9 @@ static void enlarge_gray_horizontal(unsigned char *in, int ix, int y, again: in_begin=in_pos; in_end=in_pos+ox-1; - add_col_gray(col_buf,inptr, ix, y, in_end-out_pos); - add_col_gray(col_buf,inptr+1, ix, y, out_pos-in_begin); - emit_and_bias_col_gray(col_buf,outptr,ox,y,ox-1); + add_col_gray(col_buf, inptr, ix, y, in_end - out_pos); + add_col_gray(col_buf, inptr + 1, ix, y, out_pos - in_begin); + emit_and_bias_col_gray(col_buf, outptr, ox, y, ox - 1); outptr++; out_pos+=ix-1; if (out_pos>in_end){ @@ -323,14 +320,14 @@ static void enlarge_gray_horizontal(unsigned char *in, int ix, int y, * Frees input and allocates output. * We assume unsigned holds at least 32 bits */ -static void enlarge_color_horizontal(unsigned short *in, int ix, int y, - unsigned short **outa, int ox) +static void enlarge_color_horizontal(unsigned short *in, size_t ix, size_t y, + unsigned short **outa, size_t ox) { - int alloc_size; + size_t alloc_size; scale_t *col_buf; - int a; - unsigned skip=3*ix; - unsigned oskip=3*ox; + size_t a; + size_t skip = 3 * ix; + size_t oskip = 3 * ox; unsigned short *out; if (!in) { @@ -342,8 +339,8 @@ static void enlarge_color_horizontal(unsigned short *in, int ix, int y, *outa=in; return; } - if (ox && (unsigned)ox * (unsigned)y / (unsigned)ox != (unsigned)y) overalloc(); - if ((unsigned)ox * (unsigned)y > INT_MAX / 3 / sizeof(*out)) overalloc(); + if (ox && ox * y / ox != y) overalloc(); + if (ox * y > INT_MAX / 3 / sizeof(*out)) overalloc(); out = xmalloc(sizeof(*out) * 3 * ox * y); *outa=out; if (!out) { @@ -361,24 +358,24 @@ static void enlarge_color_horizontal(unsigned short *in, int ix, int y, return; } - if ((unsigned)y > (INT_MAX) / 3 / sizeof(*col_buf)) + if (y > INT_MAX / 3 / sizeof(*col_buf)) overalloc(); - alloc_size = (int)(y*3*sizeof(*col_buf)); + alloc_size = y * 3 * sizeof(*col_buf); alloc_size = (alloc_size) & ~(0); if (alloc_size > INT_MAX) overalloc(); col_buf = xmalloc(alloc_size); { scale_t *thread_col_buf; - int out_idx; + ssize_t out_idx; thread_col_buf = (scale_t *)((char *)col_buf); bias_buf_color(thread_col_buf, y, (scale_t)(ox - 1) / 2); for (out_idx = 0; out_idx <= ox - 1; out_idx++) { ulonglong out_pos, in_pos, in_end; - int in_idx; + size_t in_idx; out_pos = (ulonglong)out_idx * (ix - 1); if (out_idx) - in_idx = (int)((out_pos - 1) / (ox - 1)); + in_idx = (out_pos - 1) / (ox - 1); else in_idx = 0; in_pos = (ulonglong)in_idx * (ox - 1); @@ -402,12 +399,11 @@ static void enlarge_color_horizontal(unsigned short *in, int ix, int y, /* Works for both enlarging and diminishing. Linear resample, no low pass. * Automatically mem_frees the "in" and allocates "out". */ /* We assume unsigned holds at least 32 bits */ -static void scale_gray_horizontal(unsigned char *in, int ix, int y, - unsigned char **out, int ox) +static void scale_gray_horizontal(unsigned char *in, size_t ix, size_t y, unsigned char **out, size_t ox) { unsigned *col_buf; - int total=ix*ox; - int out_pos,in_pos,in_begin,in_end,out_end; + size_t total = ix * ox; + size_t out_pos, in_pos, in_begin, in_end, out_end; unsigned char *outptr; unsigned char *inptr; @@ -418,14 +414,14 @@ static void scale_gray_horizontal(unsigned char *in, int ix, int y, *out=in; return; } - if (ox && (unsigned)ox * (unsigned)y / (unsigned)ox != (unsigned)y) overalloc(); - if ((unsigned)ox * (unsigned)y > INT_MAX) overalloc(); + if (ox && ox * y / ox != y) overalloc(); + if (ox * y > INT_MAX) overalloc(); outptr = xmalloc(ox * y); inptr=in; *out=outptr; - if ((unsigned)y > INT_MAX / sizeof(*col_buf)) overalloc(); + if (y > INT_MAX / sizeof(*col_buf)) overalloc(); col_buf = xmalloc(y * sizeof(*col_buf)); - bias_buf_gray(col_buf, y, ix>>1); + bias_buf_gray(col_buf, y, ix >> 1); out_pos=0; in_pos=0; again: @@ -434,14 +430,14 @@ static void scale_gray_horizontal(unsigned char *in, int ix, int y, out_end=out_pos+ix; if (in_begin<out_pos)in_begin=out_pos; if (in_end>out_end)in_end=out_end; - add_col_gray(col_buf,inptr,ix,y,in_end-in_begin); + add_col_gray(col_buf, inptr, ix, y, in_end - in_begin); in_end=in_pos+ox; if (out_end>=in_end){ in_pos=in_end; inptr++; } if (out_end<=in_end){ - emit_and_bias_col_gray(col_buf,outptr,ox,y,ix); + emit_and_bias_col_gray(col_buf, outptr, ox, y, ix); out_pos=out_pos+ix; outptr++; } @@ -458,13 +454,12 @@ static void scale_gray_horizontal(unsigned char *in, int ix, int y, * Frees ina and allocates outa. * If ox*3<=ix, and display_optimize, performs optimization for LCD. */ -static void scale_color_horizontal(unsigned short *in, int ix, int y, - unsigned short **outa, int ox) +static void scale_color_horizontal(unsigned short *in, size_t ix, size_t y, unsigned short **outa, size_t ox) { - int alloc_size; + size_t alloc_size; scale_t *col_buf; - unsigned skip=3*ix; - unsigned oskip=3*ox; + size_t skip = 3 * ix; + size_t oskip = 3 * ox; unsigned short *out; if (!in) { @@ -480,8 +475,8 @@ static void scale_color_horizontal(unsigned short *in, int ix, int y, enlarge_color_horizontal(in,ix,y,outa,ox); return; } - if (ox && (unsigned)ox * (unsigned)y / (unsigned)ox != (unsigned)y) overalloc(); - if ((unsigned)ox * (unsigned)y > INT_MAX / 3 / sizeof(*out)) overalloc(); + if (ox && ox * y / ox != y) overalloc(); + if (ox * y > INT_MAX / 3 / sizeof(*out)) overalloc(); out = xmalloc(sizeof(*out) * 3 * ox * y); *outa=out; if (!out) { @@ -489,24 +484,24 @@ static void scale_color_horizontal(unsigned short *in, int ix, int y, return; } - if ((unsigned)y > (INT_MAX) / 3 / sizeof(*col_buf)) + if (y > INT_MAX / 3 / sizeof(*col_buf)) overalloc(); - alloc_size = (int)(y*3*sizeof(*col_buf)); + alloc_size = y * 3 * sizeof(*col_buf); alloc_size = (alloc_size) & ~(0); if (alloc_size > INT_MAX) overalloc(); col_buf = xmalloc(alloc_size); { scale_t *thread_col_buf; - int out_idx; + size_t out_idx; thread_col_buf = (scale_t *)((char *)col_buf); bias_buf_color(thread_col_buf, y, (scale_t)ix / 2); for (out_idx = 0; out_idx < ox; out_idx++) { ulonglong out_pos, out_end, in_pos; - int in_idx; + size_t in_idx; out_pos = (ulonglong)out_idx * ix; out_end = out_pos + ix; - in_idx = (int)(out_pos / ox); + in_idx = out_pos / ox; in_pos = (ulonglong)in_idx * ox; do { ulonglong in_begin, in_end; @@ -532,19 +527,18 @@ static void scale_color_horizontal(unsigned short *in, int ix, int y, /* For magnification only. Does linear filtering. */ /* We assume unsigned holds at least 32 bits */ -static void enlarge_gray_vertical(unsigned char *in, int x, int iy, - unsigned char ** out ,int oy) +static void enlarge_gray_vertical(unsigned char *in, size_t x, size_t iy, unsigned char ** out, size_t oy) { unsigned *row_buf; - int total; - int out_pos,in_pos,in_begin,in_end; - int half=(oy-1)>>1; + size_t total; + size_t out_pos, in_pos, in_begin, in_end; + unsigned int half = (oy - 1) >> 1; unsigned char *outptr; unsigned char *inptr; if (iy==1){ - if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); - if ((unsigned)x * (unsigned)oy > INT_MAX) overalloc(); + if (x && x * oy / x != oy) overalloc(); + if (x * oy > INT_MAX) overalloc(); outptr = xmalloc(oy * x); *out=outptr; for(;oy;oy--,outptr+=x) @@ -554,13 +548,13 @@ static void enlarge_gray_vertical(unsigned char *in, int x, int iy, else if (iy==oy){ *out=in; }else{ - if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); - if ((unsigned)x * (unsigned)oy > INT_MAX) overalloc(); - outptr = xmalloc(oy*x); + if (x && x * oy / x != oy) overalloc(); + if (x * oy > INT_MAX) overalloc(); + outptr = xmalloc(oy * x); inptr=in; *out=outptr; total=(iy-1)*(oy-1); - if ((unsigned)x > INT_MAX / sizeof(*row_buf)) overalloc(); + if (x > INT_MAX / sizeof(*row_buf)) overalloc(); row_buf = xmalloc(x * sizeof(*row_buf)); bias_buf_gray(row_buf, x, half); out_pos=0; @@ -568,9 +562,9 @@ static void enlarge_gray_vertical(unsigned char *in, int x, int iy, again: in_begin=in_pos; in_end=in_pos+oy-1; - add_row_gray(row_buf, inptr, x, in_end-out_pos); - add_row_gray(row_buf, inptr+x, x, out_pos-in_begin); - emit_and_bias_row_gray(row_buf, outptr, x, oy-1); + add_row_gray(row_buf, inptr, x, in_end - out_pos); + add_row_gray(row_buf, inptr + x, x, out_pos - in_begin); + emit_and_bias_row_gray(row_buf, outptr, x, oy - 1); outptr+=x; out_pos+=iy-1; if (out_pos>in_end){ @@ -588,10 +582,9 @@ static void enlarge_gray_vertical(unsigned char *in, int x, int iy, /* For magnification only. Does linear filtering */ /* We assume unsigned holds at least 32 bits */ -static void enlarge_color_vertical(unsigned short *in, int x, int iy, - unsigned short **outa ,int oy) +static void enlarge_color_vertical(unsigned short *in, size_t x, size_t iy, unsigned short **outa, size_t oy) { - int alloc_size; + size_t alloc_size; scale_t *row_buf; unsigned short *out; @@ -605,8 +598,8 @@ static void enlarge_color_vertical(unsigned short *in, int x, int iy, return; } /* Rivendell */ - if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); - if ((unsigned)x * (unsigned)oy > INT_MAX / 3 / sizeof(*out)) overalloc(); + if (x && x * oy / x != oy) overalloc(); + if (x * oy > INT_MAX / 3 / sizeof(*out)) overalloc(); out = xmalloc(sizeof(*out) * 3 * oy * x); *outa=out; if (!out) { @@ -622,24 +615,24 @@ static void enlarge_color_vertical(unsigned short *in, int x, int iy, return; } - if ((unsigned)x > (INT_MAX) / 3 / sizeof(*row_buf)) + if (x > (INT_MAX) / 3 / sizeof(*row_buf)) overalloc(); - alloc_size = (int)(x*3*sizeof(*row_buf)); + alloc_size = x * 3 * sizeof(*row_buf); alloc_size = (alloc_size) & ~(0); if (alloc_size > INT_MAX) overalloc(); row_buf = xmalloc(alloc_size); { scale_t *thread_row_buf; - int out_idx; + size_t out_idx; thread_row_buf = (scale_t *)((char *)row_buf); bias_buf_color(thread_row_buf,x,(scale_t)(oy-1) / 2); for (out_idx = 0; out_idx <= oy - 1; out_idx++) { ulonglong out_pos, in_pos, in_end; - int in_idx; + size_t in_idx; out_pos = (ulonglong)out_idx * (iy - 1); if (out_idx) - in_idx = (int)((out_pos - 1) / (oy - 1)); + in_idx = (out_pos - 1) / (oy - 1); else in_idx = 0; in_pos = (ulonglong)in_idx * (oy - 1); @@ -663,12 +656,11 @@ static void enlarge_color_vertical(unsigned short *in, int x, int iy, /* Both enlarges and diminishes. Linear filtering. * Automatically allocates output and frees input. * We assume unsigned holds at least 32 bits */ -static void scale_gray_vertical(unsigned char *in, int x, int iy, - unsigned char **out ,int oy) +static void scale_gray_vertical(unsigned char *in, size_t x, size_t iy, unsigned char **out, size_t oy) { unsigned *row_buf; - int total=iy*oy; - int out_pos,in_pos,in_begin,in_end,out_end; + size_t total = iy * oy; + size_t out_pos, in_pos, in_begin, in_end, out_end; unsigned char *outptr; unsigned char *inptr; @@ -681,14 +673,14 @@ static void scale_gray_vertical(unsigned char *in, int x, int iy, *out=in; return; } - if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); - if ((unsigned)x * (unsigned)oy > INT_MAX) overalloc(); + if (x && x * oy / x != oy) overalloc(); + if (x * oy > INT_MAX) overalloc(); outptr = xmalloc(x * oy); inptr=in; *out=outptr; - if ((unsigned)x > INT_MAX / sizeof(*row_buf)) overalloc(); - row_buf=mem_calloc(x*sizeof(*row_buf)); - bias_buf_gray(row_buf, x, iy>>1); + if (x > INT_MAX / sizeof(*row_buf)) overalloc(); + row_buf = mem_calloc(x * sizeof(*row_buf)); + bias_buf_gray(row_buf, x, iy >> 1); out_pos=0; in_pos=0; again: @@ -697,14 +689,14 @@ static void scale_gray_vertical(unsigned char *in, int x, int iy, out_end=out_pos+iy; if (in_begin<out_pos)in_begin=out_pos; if (in_end>out_end)in_end=out_end; - add_row_gray(row_buf,inptr,x,in_end-in_begin); + add_row_gray(row_buf, inptr, x, in_end - in_begin); in_end=in_pos+oy; if (out_end>=in_end){ in_pos=in_end; inptr+=x; } if (out_end<=in_end){ - emit_and_bias_row_gray(row_buf,outptr,x,iy); + emit_and_bias_row_gray(row_buf, outptr, x, iy); out_pos=out_pos+iy; outptr+=x; } @@ -721,10 +713,9 @@ static void scale_gray_vertical(unsigned char *in, int x, int iy, We assume unsigned short can hold at least 16 bits. We assume unsigned holds at least 32 bits. */ -static void scale_color_vertical(unsigned short *in, int x, int iy, - unsigned short **outa, int oy) +static void scale_color_vertical(unsigned short *in, size_t x, size_t iy, unsigned short **outa, size_t oy) { - int alloc_size; + size_t alloc_size; scale_t *row_buf; unsigned short *out; @@ -741,32 +732,32 @@ static void scale_color_vertical(unsigned short *in, int x, int iy, enlarge_color_vertical(in,x,iy,outa,oy); return; } - if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); - if ((unsigned)x * (unsigned)oy > INT_MAX / 3 / sizeof(*out)) overalloc(); + if (x && x * oy / x != oy) overalloc(); + if (x * oy > INT_MAX / 3 / sizeof(*out)) overalloc(); out = xmalloc(sizeof(*out) * 3 * oy * x); *outa=out; if (!out) { free(in); return; } - if ((unsigned)x > (INT_MAX) / 3 / sizeof(*row_buf)) + if (x > INT_MAX / 3 / sizeof(*row_buf)) overalloc(); - alloc_size = (int)(x*3*sizeof(*row_buf)); + alloc_size = x * 3 * sizeof(*row_buf); alloc_size = (alloc_size) & ~(0); if (alloc_size > INT_MAX) overalloc(); row_buf = xmalloc(alloc_size); { scale_t *thread_row_buf; - int out_idx; + size_t out_idx; thread_row_buf = (scale_t *)((char *)row_buf); bias_buf_color(thread_row_buf,x,(scale_t)iy / 2); for (out_idx = 0; out_idx < oy; out_idx++) { ulonglong out_pos, out_end, in_pos; - int in_idx; + size_t in_idx; out_pos = (ulonglong)out_idx * iy; out_end = out_pos + iy; - in_idx = (int)(out_pos / oy); + in_idx = out_pos / oy; in_pos = (ulonglong)in_idx * oy; do { ulonglong in_begin, in_end; @@ -795,16 +786,15 @@ static void scale_color_vertical(unsigned short *in, int x, int iy, * pass or bilinear filtering. Automatically mem_frees the "in". * Automatically allocates "out". */ -static void scale_gray(unsigned char *in, int ix, int iy, - unsigned char **out, int ox, int oy) +static void scale_gray(unsigned char *in, size_t ix, size_t iy, unsigned char **out, size_t ox, size_t oy) { unsigned char *intermediate_buffer; if (!ix||!iy){ free(in); - if (ox && (unsigned)ox * (unsigned)oy / (unsigned)ox != (unsigned)oy) overalloc(); - if ((unsigned)ox * (unsigned)oy > INT_MAX) overalloc(); - *out=mem_calloc(ox*oy); + if (ox && ox * oy / ox != oy) overalloc(); + if (ox * oy > INT_MAX) overalloc(); + *out = mem_calloc(ox * oy); return; } if (ix*oy<ox*iy){ @@ -822,15 +812,14 @@ static void scale_gray(unsigned char *in, int ix, int iy, * Allocates output and frees input * We assume unsigned short holds at least 16 bits. */ -void scale_color(unsigned short *in, int ix, int iy, unsigned short **out, - int ox, int oy) +void scale_color(unsigned short *in, size_t ix, size_t iy, unsigned short **out, size_t ox, size_t oy) { unsigned short *intermediate_buffer; if (!ix||!iy){ free(in); - if (ox && (unsigned)ox * (unsigned)oy / (unsigned)ox != (unsigned)oy) overalloc(); - if ((unsigned)ox * (unsigned)oy > INT_MAX / 3 / sizeof(**out)) overalloc(); + if (ox && ox * oy / ox != oy) overalloc(); + if (ox * oy > INT_MAX / 3 / sizeof(**out)) overalloc(); *out = mem_calloc(ox * oy * sizeof(**out) * 3); return; } @@ -846,8 +835,7 @@ void scale_color(unsigned short *in, int ix, int iy, unsigned short **out, /* Fills a block with given color. length is number of pixels. pixel is a * tribyte. 24 bits per pixel. */ -void mix_one_color_24(unsigned char *restrict dest, int length, - unsigned char r, unsigned char g, unsigned char b) +void mix_one_color_24(unsigned char *restrict dest, size_t length, unsigned char r, unsigned char g, unsigned char b) { for (;length;length--){ dest[0]=r; @@ -861,7 +849,7 @@ void mix_one_color_24(unsigned char *restrict dest, int length, * tribyte. 48 bits per pixel. * We assume unsigned short holds at least 16 bits. */ -void mix_one_color_48(unsigned short *restrict dest, int length, +void mix_one_color_48(unsigned short *restrict dest, size_t length, unsigned short r, unsigned short g, unsigned short b) { for (;length;length--){ @@ -880,7 +868,7 @@ void mix_one_color_48(unsigned short *restrict dest, int length, * We assume unsigned short holds at least 16 bits. */ static void mix_two_colors(unsigned short *restrict dest, unsigned char *restrict alpha, - int length ,unsigned short r0, unsigned short g0, unsigned short b0, + size_t length, unsigned short r0, unsigned short g0, unsigned short b0, unsigned short r255, unsigned short g255, unsigned short b255) { unsigned char mask, cmask; @@ -909,13 +897,13 @@ static void mix_two_colors(unsigned short *restrict dest, unsigned char *restric /* We assume unsigned short holds at least 16 bits. */ void agx_and_uc_32_to_48_table(unsigned short *restrict dest, - const unsigned char *restrict src, int lenght, unsigned short *restrict table, + const unsigned char *restrict src, size_t length, unsigned short *restrict table, unsigned short rb, unsigned short gb, unsigned short bb) { unsigned char alpha, calpha; unsigned short ri, gi, bi; - for (;lenght;lenght--) + for (; length; length--) { ri=table[src[0]]; gi=table[src[1]+256]; @@ -949,7 +937,7 @@ void agx_and_uc_32_to_48_table(unsigned short *restrict dest, */ /* We assume unsigned short holds at least 16 bits. */ void agx_and_uc_32_to_48(unsigned short *restrict dest, - const unsigned char *restrict src, int lenght, float red_gamma, + const unsigned char *restrict src, size_t length, float red_gamma, float green_gamma, float blue_gamma, unsigned short rb, unsigned short gb, unsigned short bb) { @@ -958,7 +946,7 @@ void agx_and_uc_32_to_48(unsigned short *restrict dest, unsigned short ri,gi,bi; const float inv_255=(float)(1/255.); - for (;lenght;lenght--) + for (; length; length--) { r=src[0]; g=src[1]; @@ -1000,7 +988,7 @@ void agx_and_uc_32_to_48(unsigned short *restrict dest, */ /* We assume unsigned short holds at least 16 bits. */ void agx_and_uc_64_to_48(unsigned short *restrict dest, - const unsigned short *restrict src, int lenght, float red_gamma, + const unsigned short *restrict src, size_t length, float red_gamma, float green_gamma, float blue_gamma, unsigned short rb, unsigned short gb, unsigned short bb) { @@ -1009,7 +997,7 @@ void agx_and_uc_64_to_48(unsigned short *restrict dest, unsigned short ri,gi,bi; const float inv_65535=(float)(1/65535.); - for (;lenght;lenght--) + for (; length; length--) { r=src[0]; g=src[1]; @@ -1051,13 +1039,13 @@ void agx_and_uc_64_to_48(unsigned short *restrict dest, * in linear monitor output photon space. alpha 255 means full image no background. * We assume unsigned short holds at least 16 bits. */ void agx_and_uc_64_to_48_table(unsigned short *restrict dest, - const unsigned short *restrict src, int lenght, unsigned short *restrict gamma_table, + const unsigned short *restrict src, size_t length, unsigned short *restrict gamma_table, unsigned short rb, unsigned short gb, unsigned short bb) { unsigned short alpha, calpha; unsigned short ri,gi,bi; - for (;lenght;lenght--) + for (; length; length--) { ri=gamma_table[*src]; gi=gamma_table[src[1]+65536]; @@ -1089,13 +1077,13 @@ void agx_and_uc_64_to_48_table(unsigned short *restrict dest, * dest. src and dest may be identical and it will work. * We assume unsigned short holds at least 16 bits. */ void agx_48_to_48(unsigned short *restrict dest, - const unsigned short *restrict src, int lenght, float red_gamma, + const unsigned short *restrict src, size_t length, float red_gamma, float green_gamma, float blue_gamma) { float a; const float inv_65535=(float)(1/65535.); - for (;lenght;lenght--,src+=3,dest+=3) + for (; length; length--, src += 3, dest += 3) { a = src[0]; a*=inv_65535; @@ -1117,9 +1105,9 @@ void agx_48_to_48(unsigned short *restrict dest, * dest. src and dest may be identical and it will work. * We assume unsigned short holds at least 16 bits. */ void agx_48_to_48_table(unsigned short *restrict dest, - const unsigned short *restrict src, int lenght, unsigned short *restrict table) + const unsigned short *restrict src, size_t length, unsigned short *restrict table) { - for (;lenght;lenght--,src+=3,dest+=3) + for (; length; length--, src += 3, dest += 3) { dest[0]=table[*src]; dest[1]=table[src[1]+65536]; @@ -1131,14 +1119,14 @@ void agx_48_to_48_table(unsigned short *restrict dest, * number of triples. output is input powered to the given gamma, passed into * dest. src and dest may be identical and it will work. * We assume unsigned short holds at least 16 bits. */ -void agx_24_to_48(unsigned short *restrict dest, const unsigned char *restrict src, int - lenght, float red_gamma, float green_gamma, float +void agx_24_to_48(unsigned short *restrict dest, const unsigned char *restrict src, + size_t length, float red_gamma, float green_gamma, float blue_gamma) { float a; const float inv_255=(float)(1/255.); - for (;lenght;lenght--,src+=3,dest+=3) + for (; length; length--, src += 3, dest += 3) { a=*src; a*=inv_255; @@ -1214,10 +1202,10 @@ void make_gamma_table(struct cached_image *cimg) } /* We assume unsigned short holds at least 16 bits. */ -void agx_24_to_48_table(unsigned short *restrict dest, const unsigned char *restrict src, int - lenght, unsigned short *restrict table) +void agx_24_to_48_table(unsigned short *restrict dest, const unsigned char *restrict src, + size_t length, unsigned short *restrict table) { - for (;lenght;lenght--,src+=3,dest+=3) + for (; length; length--, src += 3, dest += 3) { dest[0]=table[src[0]]; dest[1]=table[src[1]+256]; diff --git a/dither.c b/dither.c @@ -186,7 +186,7 @@ int slow_fpu = -1; int r,g,b,o,rt,gt,bt,y,x;\ unsigned char *restrict outp=out->data;\ int *restrict bptr;\ - int skip=out->skip-SKIP_CODE;\ + ssize_t skip = out->skip - SKIP_CODE;\ \ o=0;o=o; /*warning go away */\ switch(out->x){\ @@ -222,7 +222,7 @@ int slow_fpu = -1; unsigned short ir, ig, ib;\ int rt,gt,bt,o,x,y;\ unsigned char *restrict outp=out->data;\ - int skip=out->skip-SKIP_CODE;\ + ssize_t skip = out->skip - SKIP_CODE;\ \ o=0;o=o; /*warning go away */\ for (y=out->y;y;y--){\ diff --git a/html.c b/html.c @@ -1027,17 +1027,19 @@ static void html_img(unsigned char *a) ismap = format_.link && (F || !has_attr(a, cast_uchar "usemap")) && has_attr(a, cast_uchar "ismap"); free(format_.image); format_.image = NULL; - if ((s = get_url_val_img(a, cast_uchar "data-full")) - || (s = get_url_val_img(a, cast_uchar "data-normal")) - || (s = get_url_val_img(a, cast_uchar "data-src")) - || (s = get_url_val_img(a, cast_uchar "data-defer-src")) + if ((s = get_url_val_img(a, cast_uchar "data-defer-src")) + || (s = get_url_val_img(a, cast_uchar "data-delay-url")) + || (s = get_url_val_img(a, cast_uchar "data-full")) + || (s = get_url_val_img(a, cast_uchar "data-lazy")) + || (s = get_url_val_img(a, cast_uchar "data-lazy-src")) || (s = get_url_val_img(a, cast_uchar "data-li-src")) + || (s = get_url_val_img(a, cast_uchar "data-normal")) || (s = get_url_val_img(a, cast_uchar "data-original")) || (s = get_url_val_img(a, cast_uchar "data-small")) - || (s = get_url_val_img(a, cast_uchar "data-lazy")) - || (s = get_url_val_img(a, cast_uchar "data-lazy-src")) - || (s = get_url_val_img(a, cast_uchar "src")) || (s = get_url_val_img(a, cast_uchar "data-source")) + || (s = get_url_val_img(a, cast_uchar "data-src")) + || (s = get_url_val_img(a, cast_uchar "data-thumb")) + || (s = get_url_val_img(a, cast_uchar "src")) || (s = get_url_val_img(a, cast_uchar "dynsrc")) || (s = get_url_val_img(a, cast_uchar "data")) || (s = get_url_val_img(a, cast_uchar "content")) @@ -2670,7 +2672,8 @@ static void html_meta(unsigned char *a) if (!strcmp(cast_const_char prop, "og:image")) { unsigned char *host = get_host_name(format_.href_base); if (host) { - if (strstr(cast_const_char host, "flickr.") + if (strstr(cast_const_char host, "facebook.") + || strstr(cast_const_char host, "flickr.") || strstr(cast_const_char host, "imgur.") || strstr(cast_const_char host, "instagram.") || strstr(cast_const_char host, "mastadon.") @@ -2742,7 +2745,13 @@ static void html_link(unsigned char *a) } if (!casestrcmp(name, cast_uchar "dns-prefetch")) { unsigned char *pre_url, *host; + if (dmp || *proxies.socks_proxy || proxies.only_proxies) + goto skip; pre_url = join_urls(format_.href_base, url); + if (get_proxy_string(pre_url) || is_noproxy_url(pre_url)) { + free(pre_url); + goto skip; + } host = get_host_name(pre_url); free(pre_url); free(host); @@ -2843,7 +2852,7 @@ static struct element_info elements[] = { {"BUTTON", html_button, 0, 0}, {"META", html_meta, 0, 1}, - {"LINK", html_link, 1, 1}, + {"LINK", html_link, 0, 1}, {"IFRAME", html_iframe, 1, 1}, {"FRAME", html_frame, 1, 1}, {"FRAMESET", html_frameset, 1, 0}, diff --git a/http.c b/http.c @@ -24,7 +24,7 @@ struct http_connection_info { static void http_send_header(struct connection *c); static void http_get_header(struct connection *c); static void test_restart(struct connection *c); -static void add_user_agent(unsigned char **hdr, int *l); +static void add_user_agent(unsigned char **hdr, int *l, const char *url); static void add_referer(unsigned char **hdr, int *l, unsigned char *url, unsigned char *prev_url); static void add_accept(unsigned char **hdr, int *l); static void add_accept_encoding(unsigned char **hdr, int *l, unsigned char *url, struct connection *c); @@ -330,13 +330,15 @@ added_connect: add_to_str(&hdr, &l, h); free(h); if ((h = get_port_str(host))) { - add_chr_to_str(&hdr, &l, ':'); - add_to_str(&hdr, &l, h); + if (strcmp(cast_char h, c->ssl ? "443" : "80")) { + add_chr_to_str(&hdr, &l, ':'); + add_to_str(&hdr, &l, h); + } free(h); } add_to_str(&hdr, &l, cast_uchar "\r\n"); } - add_user_agent(&hdr, &l); + add_user_agent(&hdr, &l, info->https_forward ? NULL : cast_char host); if (proxy) add_proxy_auth_string(&hdr, &l, c->url); if (!info->https_forward) { @@ -394,12 +396,25 @@ static void test_restart(struct connection *c) } } -static void add_user_agent(unsigned char **hdr, int *l) +static void add_user_agent(unsigned char **hdr, int *l, const char *url) { add_to_str(hdr, l, cast_uchar "User-Agent: "); if (SCRUB_HEADERS) add_to_str(hdr, l, cast_uchar "Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0\r\n"); else if (!(*http_options.header.fake_useragent)) { + /* + * Google started to return css-styled page for searches. + * It returns non-css page if the user agent begins with Lynx. + */ + if (url && (casestrstr(cast_uchar url, cast_uchar "/www.google.") + || casestrstr(cast_uchar url, cast_uchar "/google.")) + && strstr(url, "/search?") + && (strstr(url, "?q=") + || strstr(url, "&q=")) + && !strstr(url, "?tbm=isch") + && !strstr(url, "&tbm=isch")) + add_to_str(hdr, l, cast_uchar("Lynx/")); + add_to_str(hdr, l, cast_uchar("Links (" VERSION "; ")); add_to_str(hdr, l, system_name); add_to_str(hdr, l, cast_uchar "; "); diff --git a/img.c b/img.c @@ -22,11 +22,13 @@ static struct g_object_image *global_goi; struct cached_image *global_cimg; int end_callback_hit; -static int is_image_size_sane(int x, int y) +static int is_image_size_sane(ssize_t x, ssize_t y) { - unsigned a = (unsigned)x * (unsigned)y * 6; - if (y && a / (unsigned)y / 6 != (unsigned)x) - return 0; + size_t a; + if (x < 0 || y < 0) return 0; + if (x >= INT_MAX || y >= INT_MAX) return 0; + a = x * y * (drv->depth & 7); + if (y && a / y / (drv->depth & 7) != x) return 0; return a < INT_MAX; } @@ -114,48 +116,50 @@ void img_destruct_cached_image(struct cached_image *cimg) * Input may be 0. In this case output=0. * If input is >0 the output is also >0. */ -static int img_scale_h(unsigned scale, int in){ - int out; +static size_t img_scale_h(unsigned scale, ssize_t in) +{ + ssize_t out; /* We assume unsigned long holds at least 32 bits */ unsigned long pre; if (in<=0) return in; pre=((unsigned long)(aspect<65536UL?65536UL:aspect)*scale+128)>>8; - out=(int)(((unsigned long)in*pre+12800UL)/25600UL); + out = (in * pre + 12800UL) / 25600UL; if (out<1) out=1; return out; } -static int img_scale_v(unsigned scale, int in){ - int out; +static ssize_t img_scale_v(unsigned scale, ssize_t in) +{ + ssize_t out; unsigned long divisor; if (in<=0) return in; divisor=(100*(aspect>=65536UL?65536UL:aspect)+128)>>8; - out=(int)(((unsigned long)in*(scale*256)+(divisor>>1))/divisor); + out = (in * (scale * 256) + (divisor >> 1)) / divisor; if (out<1) out=1; return out; } /* Returns height (pixels) for prescribed width (pixels). Honours aspect. */ -static int width2height(double width_px, double width_mm, double height_mm) +static ssize_t width2height(double width_px, double width_mm, double height_mm) { - int height_px; + ssize_t height_px; if (width_px<=0) return 0; - height_px=(int)((height_mm*width_px*65536)/(aspect*width_mm)); + height_px = (height_mm * width_px * 65536) / (aspect * width_mm); if (height_px<1) height_px=1; return height_px; } /* Returns width (pixels) for prescribed height (pixels). Honours aspect. */ -static int height2width(double height_px, double width_mm, double height_mm) +static ssize_t height2width(double height_px, double width_mm, double height_mm) { - int width_px; + ssize_t width_px; if (height_px<=0) return 0; - width_px=(int)((width_mm*height_px*aspect)/(65536*height_mm)); + width_px = (width_mm * height_px * aspect) / (65536 * height_mm); if (width_px<1) width_px=1; return width_px; @@ -256,18 +260,18 @@ int header_dimensions_known(struct cached_image *cimg) if (cimg->strip_optimized){ struct bitmap tmpbmp; unsigned short *buf_16; - int i; + ssize_t i; - tmpbmp.x=cimg->width; - tmpbmp.y=1; + tmpbmp.x = cimg->width; + tmpbmp.y = 1; /* No buffer, bitmap is valid from the very beginning */ - cimg->bmp.x=cimg->width; - cimg->bmp.y=cimg->height; + cimg->bmp.x = cimg->width; + cimg->bmp.y = cimg->height; if (drv->get_empty_bitmap(&(cimg->bmp))) { cimg->dregs = NULL; goto skip_img; } - if ((unsigned)cimg->width > INT_MAX / sizeof(*buf_16) / 3) overalloc(); + if (cimg->width > INT_MAX / sizeof(*buf_16) / 3) overalloc(); buf_16 = xmalloc(sizeof(*buf_16) * 3 * cimg->width); round_color_sRGB_to_48(&red, &green, &blue , cimg->background_color); @@ -275,7 +279,8 @@ int header_dimensions_known(struct cached_image *cimg) /* The skip is uninitialized here and is read by dither_start * but is not used in any malicious way so it doesn't matter */ - tmpbmp.data=cimg->bmp.data; + tmpbmp.data = cimg->bmp.data; + tmpbmp.skip = cimg->bmp.skip; cimg->dregs=dither_images?dither_start(buf_16,&tmpbmp):NULL; tmpbmp.data=(unsigned char *)tmpbmp.data+cimg->bmp.skip; if (cimg->dregs) @@ -301,9 +306,9 @@ int header_dimensions_known(struct cached_image *cimg) }else { cimg->rows_added=1; cimg->bmp_used=0; - if (cimg->width && (unsigned)cimg->width * (unsigned)cimg->height / (unsigned)cimg->width != (unsigned)cimg->height) overalloc(); - if ((unsigned)cimg->width * (unsigned)cimg->height > (unsigned)INT_MAX / cimg->buffer_bytes_per_pixel) overalloc(); - cimg->buffer = xmalloc((size_t)cimg->width * (size_t)cimg->height * (size_t)cimg->buffer_bytes_per_pixel); + if (cimg->width && cimg->width * cimg->height / cimg->width != cimg->height) overalloc(); + if (cimg->width * cimg->height > INT_MAX / cimg->buffer_bytes_per_pixel) overalloc(); + cimg->buffer = xmalloc(cimg->width * cimg->height * cimg->buffer_bytes_per_pixel); if (!cimg->buffer) return 1; if (cimg->buffer_bytes_per_pixel==4 @@ -349,7 +354,7 @@ int header_dimensions_known(struct cached_image *cimg) /* Fills "tmp" buffer with the resulting data and does not free the input * buffer. May be called only in states 12 and 14 of cimg */ -static unsigned short *buffer_to_16(unsigned short *tmp, struct cached_image *cimg, unsigned char *buffer, int height) +static unsigned short *buffer_to_16(unsigned short *tmp, struct cached_image *cimg, unsigned char *buffer, ssize_t height) { unsigned short red, green, blue; @@ -431,41 +436,38 @@ static unsigned short *buffer_to_16(unsigned short *tmp, struct cached_image *ci * commited. * height must be >=1 !!! */ -void buffer_to_bitmap_incremental(struct cached_image *cimg - ,unsigned char *buffer, int height, int yoff, int *dregs, int use_strip) +void buffer_to_bitmap_incremental(struct cached_image *cimg, unsigned char *buffer, ssize_t height, ssize_t yoff, int *dregs, int use_strip) { #define max_height 16 /* max_height must be at least 1 */ unsigned short *tmp; struct bitmap tmpbmp; - int add1=0, add2; + ssize_t add1 = 0, add2; - if ((unsigned)cimg->width > INT_MAX / max_height / 3 / sizeof(*tmp)) overalloc(); - tmp = xmalloc(cimg->width*(height<max_height?height:max_height)*3*sizeof(*tmp)); + if (cimg->width > INT_MAX / max_height / 3 / sizeof(*tmp)) overalloc(); + tmp = xmalloc(cimg->width * (height < max_height ? height : max_height) * 3 * sizeof(*tmp)); /* Prepare a fake bitmap for dithering */ - tmpbmp.x=cimg->width; + tmpbmp.x = cimg->width; if (!use_strip){ tmpbmp.data=(unsigned char *)cimg->bmp.data+cimg->bmp.skip*yoff; add1=cimg->bmp.skip*max_height; } add2=cimg->buffer_bytes_per_pixel*cimg->width*max_height; not_enough: - tmpbmp.y=height<max_height?height:max_height; + tmpbmp.y = height < max_height ? height : max_height; if (use_strip) { - tmpbmp.data=drv->prepare_strip(&(cimg->bmp),yoff,tmpbmp.y); + tmpbmp.data = drv->prepare_strip(&cimg->bmp, yoff, tmpbmp.y); if (!tmpbmp.data) goto prepare_failed; } tmpbmp.skip=cimg->bmp.skip; buffer_to_16(tmp, cimg, buffer, tmpbmp.y); - if (dregs){ + if (dregs) dither_restart(tmp, &tmpbmp, dregs); - } - else { + else (*round_fn)(tmp, &tmpbmp); - } if (use_strip) { prepare_failed: - drv->commit_strip(&(cimg->bmp),yoff,tmpbmp.y); + drv->commit_strip(&cimg->bmp, yoff, tmpbmp.y); } height-=tmpbmp.y; if (!height) goto end; @@ -492,7 +494,8 @@ end: static void buffer_to_bitmap(struct cached_image *cimg) { unsigned short *tmp = NULL, *tmp1; - int ix, iy, ox, oy, gonna_be_smart; + ssize_t ix, iy, ox, oy; + int gonna_be_smart; int *dregs; if (!cimg->rows_added) return; @@ -506,10 +509,10 @@ static void buffer_to_bitmap(struct cached_image *cimg) if (ix==ox&&iy==oy) gonna_be_smart=1; else{ gonna_be_smart=0; - if (ix && (unsigned)ix * (unsigned)iy / (unsigned)ix != (unsigned)iy) overalloc(); - if ((unsigned)ix * (unsigned)iy > INT_MAX / sizeof(*tmp) / 3) overalloc(); - tmp = xmalloc(ix*iy*3*sizeof(*tmp)); - if (tmp) buffer_to_16(tmp,cimg,cimg->buffer,iy); + if (ix && ix * iy / ix != iy) overalloc(); + if (ix * iy > INT_MAX / sizeof(*tmp) / 3) overalloc(); + tmp = xmalloc(ix * iy * 3 * sizeof(*tmp)); + if (tmp) buffer_to_16(tmp, cimg, cimg->buffer, iy); if (!cimg->decoder) { free(cimg->buffer); cimg->buffer = NULL; @@ -523,8 +526,8 @@ static void buffer_to_bitmap(struct cached_image *cimg) } } if (cimg->bmp_used) drv->unregister_bitmap(&cimg->bmp); - cimg->bmp.x=ox; - cimg->bmp.y=oy; + cimg->bmp.x = ox; + cimg->bmp.y = oy; if (drv->get_empty_bitmap(&(cimg->bmp))) { if (!gonna_be_smart) free(tmp); @@ -532,8 +535,8 @@ static void buffer_to_bitmap(struct cached_image *cimg) } if (gonna_be_smart){ if (dither_images) { - if ((unsigned)cimg->width > INT_MAX / 3 / sizeof(*dregs)) overalloc(); - dregs = mem_calloc(sizeof(*dregs)*3*cimg->width); + if (cimg->width > INT_MAX / 3 / sizeof(*dregs)) overalloc(); + dregs = mem_calloc(sizeof(*dregs) * 3 * cimg->width); } else { dregs = NULL; } @@ -783,8 +786,18 @@ static int img_process_download(struct g_object_image *goi, struct f_data_c *fda img_end(cimg); } } else if (!chopped) { - if (fdatac && f_is_finished(fdatac->f_data)) { - refresh_image(fdatac, &goi->goti.go, 2000); + if (fdatac) { + if (f_is_finished(fdatac->f_data)) { + refresh_image(fdatac, &goi->goti.go, 2000); + } else { + /* + * Fix a bug - if we have a text file with html and built-in image using + * the data:// url. If we press '\' to toggle the view from text to + * html, the image is not displayed correctly. We need to reset + * fdatac->done to force re-parse. + */ + fdatac->done = 0; + } } } return chopped; diff --git a/jpeg.c b/jpeg.c @@ -334,26 +334,18 @@ susp0: case 3: /* jpeg_read_scanlines */ /* color */ - while (global_cinfo->output_scanline - <global_cinfo->output_height){ + 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; + for (a = 0; a < 16; a++) { + deco->scanlines[a] = cimg->buffer + ((size_t)global_cinfo->output_scanline + a) * global_cinfo->output_width * cimg->buffer_bytes_per_pixel; } - if ((lines= - jpeg_read_scanlines( - global_cinfo,deco->scanlines,1))){ + if ((lines = jpeg_read_scanlines(global_cinfo, deco->scanlines, 1))) { /* Some lines were written into cimg buffer */ - cimg->rows_added=1; - + cimg->rows_added = 1; fix_data(deco, lines); - }else{ + } else { /* No lines have been written into cimg * buffer */ /* We are suspended and we want more data */ diff --git a/kbd.c b/kbd.c @@ -6,7 +6,7 @@ #include "links.h" #define OUT_BUF_SIZE 10240 -#define IN_BUF_SIZE 16 +#define IN_BUF_SIZE 64 #define USE_TWIN_MOUSE 1 #define BRACKETED_PASTE 2 @@ -321,8 +321,8 @@ void handle_trm(int sock_out, void *init_string, int init_len) queue_event(itrm, (unsigned char *)init_string, init_len); itrm->orig_title = get_window_title(); set_window_title(cast_uchar "Links"); - send_init_sequence(1, itrm->flags); itrm->mouse_h = NULL; + send_init_sequence(1, itrm->flags); } int unblock_itrm(int fd) @@ -563,7 +563,8 @@ static int process_queue(struct itrm *itrm) xterm_button = itrm->kqueue[el] - ' '; el += 5; } else { - int x = 0, y = 0, b = 0, button; + int x = 0, y = 0, b = 0; + int button; unsigned char ch; if (c == 'M') { /* Legacy mouse protocol: \e[Mbxy whereas b, x and y are raw bytes, offset by 32. */ @@ -571,52 +572,69 @@ static int process_queue(struct itrm *itrm) b = itrm->kqueue[el++] - ' '; x = itrm->kqueue[el++] - ' '; y = itrm->kqueue[el++] - ' '; - } else /* c == '<' */ { + } else if (c == '<') { /* SGR 1006 mouse extension: \e[<b;x;yM where b, x and y are in decimal, no longer offset by 32, and the trailing letter is 'm' instead of 'M' for mouse release so that the released button is reported. */ + int eel; + eel = el; while (1) { if (el == itrm->qlen) goto ret; + if (el - eel >= 9) goto l1; ch = itrm->kqueue[el++]; if (ch == ';') break; if (ch < '0' || ch > '9') goto l1; - b = 10 * b + ch - '0'; + b = 10 * b + (ch - '0'); } + eel = el; while (1) { if (el == itrm->qlen) goto ret; + if (el - eel >= 9) goto l1; ch = itrm->kqueue[el++]; if (ch == ';') break; if (ch < '0' || ch > '9') goto l1; - x = 10 * x + ch - '0'; + x = 10 * x + (ch - '0'); } + eel = el; while (1) { if (el == itrm->qlen) goto ret; + if (el - eel >= 9) goto l1; ch = itrm->kqueue[el++]; if (ch == 'M' || ch == 'm') break; if (ch < '0' || ch > '9') goto l1; - y = 10 * y + ch - '0'; + y = 10 * y + (ch - '0'); } - /* Encode a release event the legacy way. */ - if (ch == 'm') b |= 3; + } else { + break; } x--; y--; if (x < 0 || y < 0 || b < 0) break; - if ((b & ~0x1f) == 0x00) button = B_DOWN; - else if ((b & ~0x1f) == 0x20) button = B_DRAG; - else { - button = -1; - goto skip_button; - } - button |= b & 3; - if ((b & 3) == 3) { - if (xterm_button == -1) - xterm_button = B_LEFT; - button = B_UP; - button |= xterm_button; + if (c == 'M' && b == 3) button = B_UP; + else if (c == '<' && ch == 'm') button = B_UP; + else if ((b & 0x20) == 0x20) button = B_DRAG, b &= ~0x20; + else button = B_DOWN; + if (b == 0) button |= B_LEFT; + else if (b == 1) button |= B_MIDDLE; + else if (b == 2) button |= B_RIGHT; + else if (b == 3 && xterm_button >= 0) button |= xterm_button; + else if (b == 0x40) button |= B_WHEELUP; + else if (b == 0x41) button |= B_WHEELDOWN; + else if (b == 0x42) button |= B_WHEELLEFT; + else if (b == 0x43) button |= B_WHEELRIGHT; + else if (b == 0x80) button |= B_FOURTH; + else if (b == 0x81) button |= B_FIFTH; + else if (b == 0x82) button |= B_SIXTH; + else break; + if ((b == 0x80 || b == 0x81 || b == 0x82) && (button & BM_ACT) == B_DOWN && xterm_button == (button & BM_BUTT)) { + /* xterm has a bug that it reports down events for both click and release */ + button &= ~BM_ACT; + button |= B_UP; } - xterm_button = button & BM_BUTT; - skip_button: + if ((button & BM_ACT) == B_DOWN) + xterm_button = button & BM_BUTT; + if ((button & BM_ACT) == B_UP) + xterm_button = -1; ev.b = button; ev.x = x; ev.y = y; diff --git a/language.inc b/language.inc @@ -670,7 +670,7 @@ static const struct { { "O" }, { "F" }, { "C" }, - { "M" }, + { "I" }, { "A" }, { "E" }, { "B" }, diff --git a/links.h b/links.h @@ -4,7 +4,7 @@ * This file is a part of the Links program, released under GPL. */ -#define LINKS_COPYRIGHT "(C) 1999 - 2018 Mikulas Patocka\n(C) 2000 - 2018 Petr Kulhavy, Karel Kulhavy, Martin Pergel" +#define LINKS_COPYRIGHT "(C) 1999 - 2019 Mikulas Patocka\n(C) 2000 - 2019 Petr Kulhavy, Karel Kulhavy, Martin Pergel" #include <dirent.h> #include <errno.h> @@ -419,7 +419,6 @@ extern int sh_line; void set_handlers_file_line(int, void (*)(void *), void (*)(void *), void *); #define set_handlers(a, b, c, d) (sh_file = (unsigned char *)__FILE__, sh_line = __LINE__, set_handlers_file_line(a, b, c, d)) void clear_events(int, int); -extern pid_t signal_pid; extern int signal_pipe[2]; void install_signal_handler(int, void (*)(void *), void *, int); void interruptible_signal(int sig, int in); @@ -697,6 +696,7 @@ struct status { list_entry_last }; +int is_noproxy_url(unsigned char *url); unsigned char *get_proxy_string(unsigned char *url); unsigned char *get_proxy(unsigned char *url); int is_proxy_url(unsigned char *url); @@ -1016,7 +1016,7 @@ void *lru_lookup(struct lru *cache, void *templ, struct lru_entry **row); */ struct bitmap { int x, y; /* Dimensions */ - int skip; /* Byte distance between vertically consecutive pixels */ + ssize_t skip; /* Byte distance between vertically consecutive pixels */ void *data; /* Pointer to room for topleft pixel */ void *flags; /* Allocation flags for the driver */ }; @@ -1047,6 +1047,7 @@ struct graphics_device { void (*resize_handler)(struct graphics_device *dev); void (*keyboard_handler)(struct graphics_device *dev, int key, int flags); void (*mouse_handler)(struct graphics_device *dev, int x, int y, int buttons); + void (*extra_handler)(struct graphics_device *dev, int type, unsigned char *string); }; struct driver_param; @@ -1305,37 +1306,36 @@ int g_char_width(struct style *style, unsigned ch); unsigned short ags_8_to_16(unsigned char input, float gamma); unsigned char ags_16_to_8(unsigned short input, float gamma); unsigned short ags_16_to_16(unsigned short input, float gamma); -void agx_24_to_48(unsigned short *restrict dest, const unsigned char *restrict src, int - lenght, float red_gamma, float green_gamma, float - blue_gamma); +void agx_24_to_48(unsigned short *restrict dest, const unsigned char *restrict src, + size_t length, float red_gamma, float green_gamma, float blue_gamma); void make_gamma_table(struct cached_image *cimg); -void agx_24_to_48_table(unsigned short *restrict dest, const unsigned char *restrict src - ,int lenght, unsigned short *restrict gamma_table); +void agx_24_to_48_table(unsigned short *restrict dest, const unsigned char *restrict src, + size_t length, unsigned short *restrict gamma_table); void agx_48_to_48_table(unsigned short *restrict dest, - const unsigned short *restrict src, int lenght, unsigned short *restrict table); + const unsigned short *restrict src, size_t length, unsigned short *restrict table); void agx_48_to_48(unsigned short *restrict dest, - const unsigned short *restrict src, int lenght, float red_gamma, + const unsigned short *restrict src, size_t length, float red_gamma, float green_gamma, float blue_gamma); void agx_and_uc_32_to_48_table(unsigned short *restrict dest, - const unsigned char *restrict src, int lenght, unsigned short *restrict table, + const unsigned char *restrict src, size_t length, unsigned short *restrict table, unsigned short rb, unsigned short gb, unsigned short bb); void agx_and_uc_32_to_48(unsigned short *restrict dest, - const unsigned char *restrict src, int lenght, float red_gamma, + const unsigned char *restrict src, size_t length, float red_gamma, float green_gamma, float blue_gamma, unsigned short rb, unsigned short gb, unsigned short bb); void agx_and_uc_64_to_48_table(unsigned short *restrict dest, - const unsigned short *restrict src, int lenght, unsigned short *restrict gamma_table, + const unsigned short *restrict src, size_t length, unsigned short *restrict gamma_table, unsigned short rb, unsigned short gb, unsigned short bb); void agx_and_uc_64_to_48(unsigned short *restrict dest, - const unsigned short *restrict src, int lenght, float red_gamma, + const unsigned short *restrict src, size_t length, float red_gamma, float green_gamma, float blue_gamma, unsigned short rb, unsigned short gb, unsigned short bb); -void mix_one_color_48(unsigned short *restrict dest, int length, +void mix_one_color_48(unsigned short *restrict dest, size_t length, unsigned short r, unsigned short g, unsigned short b); -void mix_one_color_24(unsigned char *restrict dest, int length, +void mix_one_color_24(unsigned char *restrict dest, size_t length, unsigned char r, unsigned char g, unsigned char b); -void scale_color(unsigned short *in, int ix, int iy, unsigned short **out, - int ox, int oy); +void scale_color(unsigned short *in, size_t ix, size_t iy, unsigned short **out, + size_t ox, size_t oy); void update_aspect(void); void flush_bitmaps(int flush_font, int flush_images, int redraw_all); @@ -1438,10 +1438,12 @@ enum ev { EV_INIT, EV_KBD, EV_MOUSE, + EV_EXTRA, EV_REDRAW, EV_RESIZE, EV_ABORT }; +#define EV_EXTRA_OPEN_URL EV_INIT enum evh { EVH_NOT_PROCESSED, @@ -1577,9 +1579,6 @@ void flush_terminal(struct terminal *); void set_window_pos(struct window *, int, int, int, int); void t_redraw(struct graphics_device *, struct rect *); -void t_resize(struct graphics_device *); -void t_kbd(struct graphics_device *, int, int); -void t_mouse(struct graphics_device *, int, int, int); #endif @@ -2108,7 +2107,7 @@ struct cached_image { int background_color; /* nezaokrouhlene pozadi: * sRGB, (r<<16)+(g<<8)+b */ unsigned char *url; - int wanted_xw, wanted_yw; /* This is what is written in the alt. + ssize_t wanted_xw, wanted_yw; /* This is what is written in the alt. If some dimension is omitted, then it's <0. This is what was requested when the image was created. */ @@ -2118,10 +2117,10 @@ struct cached_image { unsigned aspect; /* What aspect ratio the image is for. But the PNG aspect is ignored :( */ - int xww, yww; /* This is the resulting dimensions on the screen + ssize_t xww, yww; /* This is the resulting dimensions on the screen measured in screen pixels. */ - int width, height; /* From image header. + ssize_t width, height; /* From image header. * If the buffer is allocated, * it is always allocated to width*height. * If the buffer is NULL then width and height @@ -3018,8 +3017,7 @@ extern struct cached_image *global_cimg; int header_dimensions_known(struct cached_image *cimg); void img_end(struct cached_image *cimg); void compute_background_8(struct cached_image *cimg, unsigned char rgb[3]); -void buffer_to_bitmap_incremental(struct cached_image *cimg - ,unsigned char *buffer, int height, int yoff, int *dregs, int use_strip); +void buffer_to_bitmap_incremental(struct cached_image *cimg, unsigned char *buffer, ssize_t height, ssize_t yoff, int *dregs, int use_strip); /* Below is external interface provided by img.c */ struct g_part; diff --git a/listedit.c b/listedit.c @@ -1719,7 +1719,7 @@ static int list_event_handler(struct dialog_data *dlg, struct links_event *ev) break; default: - internal("Unknown event received: %d", ev->ev); + break; } return EVENT_NOT_PROCESSED; diff --git a/sched.c b/sched.c @@ -295,6 +295,7 @@ static void del_connection(struct connection *c) trim_cache_entry(ce); free(c->url); free(c->prev_url); + free(c->ssl); free(c); } @@ -322,6 +323,7 @@ void add_keepalive_socket(struct connection *c, uttime timeout, int protocol_dat k->add_time = get_absolute_time(); k->protocol_data = protocol_data; k->ssl = c->ssl; + c->ssl = NULL; memcpy(&k->last_lookup_state, &c->last_lookup_state, sizeof(struct lookup_state)); add_to_list(keepalive_connections, k); del: @@ -448,7 +450,7 @@ static int try_to_suspend_connection(struct connection *c, unsigned char *ho) return -1; } -static int is_noproxy_url(unsigned char *url) +int is_noproxy_url(unsigned char *url) { unsigned char *host = get_host_name(url); if (!proxies.only_proxies) { diff --git a/select.c b/select.c @@ -578,7 +578,7 @@ struct signal_handler { static volatile int signal_mask[NUM_SIGNALS]; static volatile struct signal_handler signal_handlers[NUM_SIGNALS]; -pid_t signal_pid; +static pid_t signal_pid; int signal_pipe[2]; static void got_signal(int sig) diff --git a/session.c b/session.c @@ -1525,7 +1525,7 @@ struct f_data *cached_format_html(struct f_data_c *fd, struct object_request *rq } }) {}; if (ses) { - if (report_status || !fd->f_data || fd->f_data->time_to_get >= DISPLAY_FORMATTING_STATUS) + if (report_status || !fd->f_data || fd->f_data->time_to_get >= DISPLAY_FORMATTING_STATUS || (rq->ce && rq->ce->length >= 1000000)) print_progress(ses, TEXT_(T_FORMATTING_DOCUMENT)); } detach_f_data(&fd->f_data); @@ -2997,6 +2997,10 @@ void win_func(struct window *win, struct links_event *ev, int fw) move_session_to_front(ses); send_event(ses, ev); break; + case EV_EXTRA: + if (ev->x == EV_EXTRA_OPEN_URL) + goto_url(ses, (unsigned char *)ev->b); + break; default: die("session.c win_func(): unknown event\n"); } diff --git a/suffix.inc b/suffix.inc @@ -15,6 +15,7 @@ static const char *domain_suffix[] = { "*.compute.estate", "*.cryptonomic.net", "*.dapps.earth", + "*.dweb.link", "*.elb.amazonaws.com", "*.elb.amazonaws.com.cn", "*.er", @@ -32,8 +33,10 @@ static const char *domain_suffix[] = { "*.kobe.jp", "*.kunden.ortsinfo.at", "*.landing.myjino.ru", + "*.lcl.dev", "*.magentosite.cloud", "*.mm", + "*.moonscale.io", "*.nagoya.jp", "*.nom.br", "*.np", @@ -51,6 +54,7 @@ static const char *domain_suffix[] = { "*.sensiosite.cloud", "*.spectrum.myjino.ru", "*.statics.cloud", + "*.stg.dev", "*.stolos.io", "*.telebit.xyz", "*.transurl.be", @@ -59,6 +63,7 @@ static const char *domain_suffix[] = { "*.triton.zone", "*.uberspace.de", "*.vps.myjino.ru", + "*.webhare.dev", "*.ye", "*.yokohama.jp", "0.bg", @@ -340,6 +345,7 @@ static const char *domain_suffix[] = { "anan.tokushima.jp", "anani.br", "ancona.it", + "and.mom", "and.museum", "andasuolo.no", "andebu.no", @@ -387,9 +393,11 @@ static const char *domain_suffix[] = { "api.stdlib.com", "apigee.io", "app", + "app.banzaicloud.io", "app.lmpm.com", "app.os.fedoraproject.org", "app.os.stg.fedoraproject.org", + "app.render.com", "appchizi.com", "apple", "applicationcloud.io", @@ -452,6 +460,7 @@ static const char *domain_suffix[] = { "arts.ro", "arts.ve", "artsandcrafts.museum", + "arvo.network", "as", "as.us", "asago.hyogo.jp", @@ -566,11 +575,13 @@ static const char *domain_suffix[] = { "az", "az.us", "azerbaijan.su", + "azimuth.network", "azumino.nagano.jp", "azure", "azure-mobile.net", "azurecontainer.io", "azurewebsites.net", + "b-data.io", "b.bg", "b.br", "b.se", @@ -594,6 +605,7 @@ static const char *domain_suffix[] = { "balashov.su", "balat.no", "bale.museum", + "balena-devices.com", "balestrand.no", "ballangen.no", "ballooning.aero", @@ -625,6 +637,7 @@ static const char *domain_suffix[] = { "barrel-of-knowledge.info", "barrell-of-knowledge.info", "barsy.bg", + "barsy.ca", "barsy.club", "barsy.co.uk", "barsy.de", @@ -655,6 +668,7 @@ static const char *domain_suffix[] = { "basel.museum", "bashkiria.ru", "bashkiria.su", + "basicserver.io", "basilicata.it", "basketball", "baths.museum", @@ -752,6 +766,7 @@ static const char *domain_suffix[] = { "biz.cy", "biz.dk", "biz.et", + "biz.gl", "biz.id", "biz.ki", "biz.ls", @@ -872,7 +887,6 @@ static const char *domain_suffix[] = { "bmw", "bn", "bn.it", - "bnl", "bnpparibas", "bnr.la", "bo", @@ -917,6 +931,7 @@ static const char *domain_suffix[] = { "bozen-sudtirol.it", "bozen-suedtirol.it", "bozen.it", + "bpl.biz", "bplaced.com", "bplaced.de", "bplaced.net", @@ -1004,6 +1019,7 @@ static const char *domain_suffix[] = { "ca.na", "ca.us", "caa.aero", + "caa.li", "cab", "cable-modem.org", "cadaques.museum", @@ -1048,6 +1064,7 @@ static const char *domain_suffix[] = { "cargo.aero", "carrara-massa.it", "carraramassa.it", + "carrd.co", "carrier.museum", "cars", "cartier", @@ -1069,6 +1086,7 @@ static const char *domain_suffix[] = { "catering", "catering.aero", "catholic", + "catholic.edu.au", "caxias.br", "cb.it", "cba", @@ -1269,12 +1287,15 @@ static const char *domain_suffix[] = { "cloud.goog", "cloud.metacentrum.cz", "cloud66.ws", + "cloud66.zone", "cloudaccess.host", "cloudaccess.net", "cloudapp.net", + "cloudapps.digital", "cloudcontrolapp.com", "cloudcontrolled.com", "cloudeity.net", + "cloudera.site", "cloudfront.net", "cloudfunctions.net", "cloudns.asia", @@ -1312,6 +1333,7 @@ static const char *domain_suffix[] = { "co.at", "co.bb", "co.bi", + "co.bn", "co.business", "co.bw", "co.ca", @@ -1387,6 +1409,7 @@ static const char *domain_suffix[] = { "cody.museum", "coffee", "cog.mi.us", + "col.ng", "coldwar.museum", "collection.museum", "college", @@ -1500,7 +1523,6 @@ static const char *domain_suffix[] = { "com.re", "com.ro", "com.ru", - "com.rw", "com.sa", "com.sb", "com.sc", @@ -1549,6 +1571,7 @@ static const char *domain_suffix[] = { "condos", "conf.au", "conf.lv", + "conf.se", "conference.aero", "construction", "consulado.st", @@ -1572,6 +1595,7 @@ static const char *domain_suffix[] = { "coop.mv", "coop.mw", "coop.py", + "coop.rw", "coop.tt", "cooperativa.bo", "copenhagen.museum", @@ -1588,6 +1612,7 @@ static const char *domain_suffix[] = { "coupon", "coupons", "courses", + "cpa", "cpa.pro", "cq.cn", "cr", @@ -1596,6 +1621,7 @@ static const char *domain_suffix[] = { "crafting.xyz", "crafts.museum", "cranbrook.museum", + "crd.co", "creation.museum", "credit", "creditcard", @@ -1650,6 +1676,7 @@ static const char *domain_suffix[] = { "czeladz.pl", "czest.pl", "d.bg", + "d.gv.vc", "d.se", "dabur", "dad", @@ -1752,6 +1779,7 @@ static const char *domain_suffix[] = { "direct", "directory", "discount", + "discourse.group", "discover", "discovery.museum", "dish", @@ -1792,7 +1820,6 @@ static const char *domain_suffix[] = { "doesntexist.com", "doesntexist.org", "dog", - "doha", "dolls.museum", "domains", "dominic.ua", @@ -1849,6 +1876,7 @@ static const char *domain_suffix[] = { "dyn.cosidns.de", "dyn.ddnss.de", "dyn.home-webserver.de", + "dyn53.io", "dynalias.com", "dynalias.net", "dynalias.org", @@ -2011,7 +2039,6 @@ static const char *domain_suffix[] = { "edu.qa", "edu.rs", "edu.ru", - "edu.rw", "edu.sa", "edu.sb", "edu.sc", @@ -2039,8 +2066,10 @@ static const char *domain_suffix[] = { "edu.zm", "education", "education.museum", + "education.tas.edu.au", "educational.museum", "educator.aero", + "edugit.org", "edunet.tn", "ee", "ee.eu.org", @@ -2095,6 +2124,7 @@ static const char *domain_suffix[] = { "enna.it", "enonic.io", "ens.tn", + "enterprisecloud.nu", "enterprises", "entertainment.aero", "entomology.museum", @@ -2102,6 +2132,7 @@ static const char *domain_suffix[] = { "environmentalconservation.museum", "epilepsy.museum", "epson", + "eq.edu.au", "equipment", "equipment.aero", "ericsson", @@ -2243,6 +2274,7 @@ static const char *domain_suffix[] = { "film", "film.hu", "film.museum", + "fin.ci", "fin.ec", "fin.tn", "final", @@ -2264,6 +2296,7 @@ static const char *domain_suffix[] = { "firm.ht", "firm.in", "firm.nf", + "firm.ng", "firm.ro", "firm.ve", "firmdale", @@ -2316,6 +2349,10 @@ static const char *domain_suffix[] = { "for-our.info", "for-some.biz", "for-the.biz", + "for.men", + "for.mom", + "for.one", + "for.sale", "force.museum", "ford", "forde.no", @@ -2347,6 +2384,7 @@ static const char *domain_suffix[] = { "franziskaner.museum", "fredrikstad.no", "free", + "free.hr", "freebox-os.com", "freebox-os.fr", "freeboxos.com", @@ -2536,6 +2574,7 @@ static const char *domain_suffix[] = { "gateway.museum", "gaular.no", "gausdal.no", + "gay", "gb", "gb.com", "gb.net", @@ -2553,10 +2592,12 @@ static const char *domain_suffix[] = { "geek.nz", "geekgalaxy.com", "geelvinck.museum", + "gehirn.ne.jp", "geisei.kochi.jp", "gemological.museum", "gen.in", "gen.mi.us", + "gen.ng", "gen.nz", "gen.tr", "genkai.saga.jp", @@ -2609,6 +2650,7 @@ static const char *domain_suffix[] = { "gle", "gleeze.com", "gliding.aero", + "glitch.me", "gliwice.pl", "global", "global.prod.fastly.net", @@ -2701,7 +2743,6 @@ static const char *domain_suffix[] = { "gouv.ht", "gouv.km", "gouv.ml", - "gouv.rw", "gouv.sn", "gov", "gov.ac", @@ -2909,6 +2950,7 @@ static const char *domain_suffix[] = { "gushikami.okinawa.jp", "gv.ao", "gv.at", + "gv.vc", "gw", "gwangju.kr", "gwiddle.co.uk", @@ -3171,7 +3213,6 @@ static const char *domain_suffix[] = { "honbetsu.hokkaido.jp", "honda", "honefoss.no", - "honeywell", "hongo.hiroshima.jp", "honjo.akita.jp", "honjo.saitama.jp", @@ -3203,6 +3244,8 @@ static const char *domain_suffix[] = { "hr", "hr.eu.org", "hs.kr", + "hs.run", + "hs.zone", "hsbc", "ht", "hu", @@ -3320,6 +3363,7 @@ static const char *domain_suffix[] = { "in-vpn.net", "in-vpn.org", "in.eu.org", + "in.london", "in.na", "in.net", "in.ni", @@ -3420,7 +3464,6 @@ static const char *domain_suffix[] = { "int.ni", "int.pt", "int.ru", - "int.rw", "int.tj", "int.tt", "int.ve", @@ -3436,6 +3479,7 @@ static const char *domain_suffix[] = { "investments", "inzai.chiba.jp", "io", + "iobb.net", "ip6.arpa", "ipifony.net", "ipiranga", @@ -3534,9 +3578,9 @@ static const char *domain_suffix[] = { "isahaya.nagasaki.jp", "ise.mie.jp", "isehara.kanagawa.jp", - "iselect", "isen.kagoshima.jp", "isernia.it", + "iserv.dev", "isesaki.gunma.jp", "ishigaki.okinawa.jp", "ishikari.hokkaido.jp", @@ -3731,6 +3775,7 @@ static const char *domain_suffix[] = { "k12.wa.us", "k12.wi.us", "k12.wy.us", + "kaas.gg", "kadena.okinawa.jp", "kadogawa.miyazaki.jp", "kadoma.osaka.jp", @@ -3905,6 +3950,7 @@ static const char *domain_suffix[] = { "kherson.ua", "khmelnitskiy.ua", "khmelnytskyi.ua", + "khplay.nl", "ki", "kia", "kibichuo.okayama.jp", @@ -3926,6 +3972,7 @@ static const char *domain_suffix[] = { "kin.okinawa.jp", "kinder", "kindle", + "kinghost.net", "kinko.kagoshima.jp", "kinokawa.wakayama.jp", "kira.aichi.jp", @@ -4149,6 +4196,7 @@ static const char *domain_suffix[] = { "la-spezia.it", "la.us", "laakesvuemie.no", + "lab.ms", "labor.museum", "labour.museum", "lacaixa", @@ -4218,6 +4266,7 @@ static const char *domain_suffix[] = { "leka.no", "leksvik.no", "lel.br", + "lelux.site", "lenug.su", "lenvik.no", "lerdal.no", @@ -4341,6 +4390,11 @@ static const char *domain_suffix[] = { "lodi.it", "lodingen.no", "loft", + "loginline.app", + "loginline.dev", + "loginline.io", + "loginline.services", + "loginline.site", "loginto.me", "logistics.aero", "logoip.com", @@ -4352,6 +4406,7 @@ static const char *domain_suffix[] = { "lombardy.it", "lomza.pl", "london", + "london.cloudapps.digital", "london.museum", "londrina.br", "loppa.no", @@ -4381,6 +4436,7 @@ static const char *domain_suffix[] = { "ltd.gi", "ltd.hk", "ltd.lk", + "ltd.ng", "ltd.ua", "ltd.uk", "ltda", @@ -4569,6 +4625,7 @@ static const char *domain_suffix[] = { "meldal.no", "melhus.no", "meloy.no", + "members.linode.com", "meme", "memorial", "memorial.museum", @@ -4784,6 +4841,7 @@ static const char *domain_suffix[] = { "mn.us", "mo", "mo-i-rana.no", + "mo-siemens.io", "mo.cn", "mo.it", "mo.us", @@ -5116,6 +5174,7 @@ static const char *domain_suffix[] = { "nc", "nc.tr", "nc.us", + "nctu.me", "nd.us", "ne", "ne.jp", @@ -5298,7 +5357,10 @@ static const char *domain_suffix[] = { "nflfan.org", "nfshost.com", "ng", + "ng.city", "ng.eu.org", + "ng.ink", + "ng.school", "ngo", "ngo.lk", "ngo.ph", @@ -5312,6 +5374,7 @@ static const char *domain_suffix[] = { "ni", "nic.in", "nic.tj", + "nic.za", "nichinan.miyazaki.jp", "nichinan.tottori.jp", "nico", @@ -5384,6 +5447,7 @@ static const char *domain_suffix[] = { "noboribetsu.hokkaido.jp", "noda.chiba.jp", "noda.iwate.jp", + "nodebalancer.linode.com", "nodum.co", "nodum.io", "nogata.fukuoka.jp", @@ -5495,12 +5559,10 @@ static const char *domain_suffix[] = { "nu", "nu.ca", "nu.it", - "nuernberg.museum", "numata.gunma.jp", "numata.hokkaido.jp", "numazu.shizuoka.jp", "nuoro.it", - "nuremberg.museum", "nv.us", "nx.cn", "ny.us", @@ -5509,8 +5571,10 @@ static const char *domain_suffix[] = { "nyc.museum", "nym.by", "nym.bz", + "nym.ec", "nym.gr", "nym.gy", + "nym.hk", "nym.ie", "nym.kz", "nym.la", @@ -5560,7 +5624,11 @@ static const char *domain_suffix[] = { "odo.br", "oe.yamagata.jp", "of.by", + "of.fashion", + "of.football", + "of.london", "of.no", + "of.work", "off", "off.ai", "office", @@ -5656,6 +5724,7 @@ static const char *domain_suffix[] = { "on-the-web.tv", "on-web.fr", "on.ca", + "on.fashion", "onagawa.miyagi.jp", "one", "ong", @@ -5673,6 +5742,8 @@ static const char *domain_suffix[] = { "ono.hyogo.jp", "onojo.fukuoka.jp", "onomichi.hiroshima.jp", + "onred.one", + "onrender.com", "ontario.museum", "onthewifi.com", "onyourside", @@ -5821,6 +5892,7 @@ static const char *domain_suffix[] = { "org.ro", "org.rs", "org.ru", + "org.rw", "org.sa", "org.sb", "org.sc", @@ -5864,6 +5936,7 @@ static const char *domain_suffix[] = { "orland.no", "orskog.no", "orsta.no", + "orx.biz", "os.hedmark.no", "os.hordaland.no", "osaka", @@ -6103,6 +6176,7 @@ static const char *domain_suffix[] = { "pomorze.pl", "poniatowa.pl", "ponpes.id", + "pony.club", "pordenone.it", "porn", "porsanger.no", @@ -6183,6 +6257,7 @@ static const char *domain_suffix[] = { "pru", "prudential", "pruszkow.pl", + "prvcy.page", "przeworsk.pl", "ps", "psc.br", @@ -6200,6 +6275,7 @@ static const char *domain_suffix[] = { "public.museum", "publishproxy.com", "pubol.museum", + "pubtls.org", "pueblo.bo", "pug.it", "puglia.it", @@ -6226,6 +6302,7 @@ static const char *domain_suffix[] = { "qld.gov.au", "qpon", "qsl.br", + "qualifioapp.com", "quebec", "quebec.museum", "quest", @@ -6314,6 +6391,8 @@ static const char *domain_suffix[] = { "rep.kp", "repair", "repbody.aero", + "repl.co", + "repl.run", "report", "republican", "res.aero", @@ -6634,6 +6713,7 @@ static const char *domain_suffix[] = { "sch.ng", "sch.qa", "sch.sa", + "sch.so", "sch.zm", "schaeffler", "schlesisches.museum", @@ -6647,6 +6727,7 @@ static const char *domain_suffix[] = { "school.na", "school.nz", "school.za", + "schools.nsw.edu.au", "schule", "schwarz", "schweiz.museum", @@ -6867,6 +6948,7 @@ static const char *domain_suffix[] = { "shop.pl", "shop.ro", "shop.th", + "shopitsite.com", "shopping", "shouji", "show", @@ -6953,6 +7035,7 @@ static const char *domain_suffix[] = { "so.it", "sobetsu.hokkaido.jp", "soc.lk", + "soc.srcf.net", "soccer", "sochi.su", "social", @@ -7034,9 +7117,11 @@ static const char *domain_suffix[] = { "ssl.origin.cdn77-secure.org", "st", "st.no", + "stackhero-network.com", "stada", "stadt.museum", "stage.nodeart.io", + "staging.onred.one", "stalbans.museum", "stalowa-wola.pl", "stange.no", @@ -7044,7 +7129,6 @@ static const char *domain_suffix[] = { "star", "starachowice.pl", "stargard.pl", - "starhub", "starnberg.museum", "starostwo.gov.pl", "stat.no", @@ -7072,6 +7156,7 @@ static const char *domain_suffix[] = { "stokke.no", "stor-elvdal.no", "storage", + "storage.yandexcloud.net", "stord.no", "stordal.no", "store", @@ -7281,6 +7366,7 @@ static const char *domain_suffix[] = { "taxi", "taxi.br", "tc", + "tc.br", "tci", "tcm.museum", "tcp4.me", @@ -7335,6 +7421,7 @@ static const char *domain_suffix[] = { "theater.museum", "theatre", "theworkpc.com", + "thingdustdata.com", "thruhere.net", "tiaa", "tickets", @@ -7379,6 +7466,7 @@ static const char *domain_suffix[] = { "to.gov.br", "to.it", "to.leg.br", + "to.work", "toba.mie.jp", "tobe.ehime.jp", "tobetsu.hokkaido.jp", @@ -7556,9 +7644,11 @@ static const char *domain_suffix[] = { "trust.museum", "trustee.museum", "trv", + "trycloudflare.com", "trysil.no", "ts.it", "tselinograd.su", + "tsk.tr", "tsu.mie.jp", "tsubame.niigata.jp", "tsubata.ishikawa.jp", @@ -7633,6 +7723,7 @@ static const char *domain_suffix[] = { "u2-local.xnbay.com", "u2.xnbay.com", "ua", + "ua.rs", "ubank", "ube.yamaguchi.jp", "uber.space", @@ -7655,6 +7746,7 @@ static const char *domain_suffix[] = { "ug.gov.pl", "ugim.gov.pl", "uhren.museum", + "ui.nabu.casa", "uji.kyoto.jp", "ujiie.tochigi.jp", "ujitawara.kyoto.jp", @@ -7662,6 +7754,7 @@ static const char *domain_suffix[] = { "uk.com", "uk.eu.org", "uk.net", + "uk0.bigv.io", "uki.kumamoto.jp", "ukiha.fukuoka.jp", "uklugs.org", @@ -7678,6 +7771,7 @@ static const char *domain_suffix[] = { "umig.gov.pl", "unazuki.toyama.jp", "undersea.museum", + "uni5.net", "unicom", "union.aero", "univ.sn", @@ -7730,7 +7824,10 @@ static const char *domain_suffix[] = { "uscountryestate.museum", "usculture.museum", "usdecorativearts.museum", + "user.aseinet.ne.jp", "user.party.eus", + "user.srcf.net", + "usercontent.jp", "usgarden.museum", "ushiku.ibaraki.jp", "ushistory.museum", @@ -7752,6 +7849,7 @@ static const char *domain_suffix[] = { "uvic.museum", "uw.gov.pl", "uwajima.ehime.jp", + "uwu.ai", "uy", "uy.com", "uz", @@ -7867,6 +7965,7 @@ static const char *domain_suffix[] = { "virginia.museum", "virtual-user.de", "virtual.museum", + "virtualserver.io", "virtualuser.de", "virtueeldomein.nl", "virtuel.museum", @@ -7895,6 +7994,7 @@ static const char *domain_suffix[] = { "vologda.su", "volvo", "volyn.ua", + "voorloper.cloud", "voss.no", "vossevangen.no", "vote", @@ -7917,6 +8017,7 @@ static const char *domain_suffix[] = { "wa.gov.au", "wa.us", "wada.nagano.jp", + "wafflecell.com", "wajiki.tokushima.jp", "wajima.ishikawa.jp", "wakasa.fukui.jp", @@ -7954,6 +8055,7 @@ static const char *domain_suffix[] = { "we.bs", "weather", "weatherchannel", + "web.app", "web.bo", "web.co", "web.do", @@ -7977,6 +8079,7 @@ static const char *domain_suffix[] = { "webhosting.be", "webredirect.org", "website", + "website.yandexcloud.net", "webspace.rocks", "wed", "wedding", @@ -8019,6 +8122,7 @@ static const char *domain_suffix[] = { "wloclawek.pl", "wme", "wmflabs.org", + "wnext.app", "wodzislaw.pl", "wolomin.pl", "wolterskluwer", @@ -8227,6 +8331,7 @@ static const char *domain_suffix[] = { "xn--hery-ira.nordland.no", "xn--hery-ira.xn--mre-og-romsdal-qqb.no", "xn--hgebostad-g3a.no", + "xn--hkkinen-5wa.fi", "xn--hmmrfeasta-s4ac.no", "xn--hnefoss-q1a.no", "xn--hobl-ira.no", @@ -8560,6 +8665,7 @@ static const char *domain_suffix[] = { "yanagawa.fukuoka.jp", "yanaizu.fukushima.jp", "yandex", + "yandexcloud.net", "yao.osaka.jp", "yaotsu.gifu.jp", "yasaka.nagano.jp", diff --git a/terminal.c b/terminal.c @@ -512,6 +512,12 @@ direct: #ifdef G +void t_redraw(struct graphics_device *, struct rect *); +static void t_resize(struct graphics_device *); +static void t_kbd(struct graphics_device *, int, int); +static void t_mouse(struct graphics_device *, int, int, int); +static void t_extra(struct graphics_device *, int, unsigned char *); + static struct term_spec gfx_term = { init_list_1st(NULL) "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, init_list_last(NULL) }; struct terminal *init_gfx_term(void (*root_window)(struct window *, struct links_event *, int), unsigned char *cwd, void *info, int len) @@ -552,6 +558,7 @@ struct terminal *init_gfx_term(void (*root_window)(struct window *, struct links dev->resize_handler = t_resize; dev->keyboard_handler = t_kbd; dev->mouse_handler = t_mouse; + dev->extra_handler = t_extra; { int *ptr; struct links_event ev = { EV_INIT, 0, 0, 0 }; @@ -577,7 +584,7 @@ void t_redraw(struct graphics_device *dev, struct rect *r) register_bottom_half(redraw_windows, term); } -void t_resize(struct graphics_device *dev) +static void t_resize(struct graphics_device *dev) { struct terminal *term = dev->user_data; struct window *win = NULL; @@ -592,7 +599,7 @@ void t_resize(struct graphics_device *dev) set_clip_area(dev, &dev->size); } -void t_kbd(struct graphics_device *dev, int key, int flags) +static void t_kbd(struct graphics_device *dev, int key, int flags) { struct terminal *term = dev->user_data; struct links_event ev = { EV_KBD, 0, 0, 0 }; @@ -621,7 +628,7 @@ void t_kbd(struct graphics_device *dev, int key, int flags) } } -void t_mouse(struct graphics_device *dev, int x, int y, int b) +static void t_mouse(struct graphics_device *dev, int x, int y, int b) { struct terminal *term = dev->user_data; struct links_event ev = { EV_MOUSE, 0, 0, 0 }; @@ -652,6 +659,20 @@ void t_mouse(struct graphics_device *dev, int x, int y, int b) next->handler(next, &ev, 0); } +static void t_extra(struct graphics_device *dev, int type, unsigned char *str) +{ + struct terminal *term = dev->user_data; + struct links_event ev = { EV_EXTRA, 0, 0, 0 }; + struct window *prev; + + ev.x = type; + ev.b = (long)str; + + if (list_empty(term->windows)) return; + prev = list_struct(term->windows.prev, struct window); + prev->handler(prev, &ev, 0); +} + #endif static void in_term(void *term_) diff --git a/url.c b/url.c @@ -491,18 +491,61 @@ static unsigned char *rewrite_url(unsigned char *n) return n; } +static int test_qualified_name(char *host, char *hostname) +{ + char *c; + if (!strcasecmp(host, hostname)) + return 1; + c = strchr(hostname, '.'); + if (c) { + *c = 0; + if (!strcasecmp(host, hostname)) + return 1; + } + return 0; +} + +static int is_local_host(char *host) +{ + if (!*host) + return 1; + if (!strcasecmp(host, "localhost")) + return 1; + { + int rs; + char n[4096]; + n[0] = 0; + EINTRLOOP(rs, gethostname(n, sizeof(n))); + n[sizeof(n) - 1] = 0; + if (!rs && strlen(n) < sizeof(n) - 1) { + if (test_qualified_name(host, n)) + return 1; + } + } + return 0; + +} + static void insert_wd(unsigned char **up, unsigned char *cwd) { unsigned char *u = *up; unsigned char *cw; unsigned char *url; + char *host; int url_l; + int i; if (!u || !cwd || !*cwd) return; if (casecmp(u, cast_uchar "file://", 7)) return; - if (dir_sep(u[7])) + for (i = 7; u[i] && !dir_sep(u[i]); i++); + host = cast_char memacpy(u + 7, i - 7); + if (is_local_host(host)) { + free(host); + memmove(u + 7, u + i, strlen(cast_const_char (u + i)) + 1); return; + } + free(host); url = init_str(); url_l = 0; add_bytes_to_str(&url, &url_l, u, 7); diff --git a/view.c b/view.c @@ -2709,7 +2709,11 @@ static int frame_ev(struct session *ses, struct f_data_c *fd, struct links_event if (lnl > 1) input_field(ses->term, NULL, TEXT_(T_GO_TO_LINK), TEXT_(T_ENTER_LINK_NUMBER), ses, NULL, lnl, d, 1, f_data->nlinks, check_number, 2, TEXT_(T_OK), goto_link_number, TEXT_(T_CANCEL), input_field_null); } else x = 0; - } else if (ev->ev == EV_MOUSE && (ev->b & BM_BUTT) <= B_RIGHT) { + } else if (ev->ev == EV_MOUSE && (ev->b & BM_BUTT) == B_WHEELUP) rep_ev(ses, fd, scroll, -1 - 5 * !ses->kbdprefix.rep); + else if (ev->ev == EV_MOUSE && (ev->b & BM_BUTT) == B_WHEELDOWN) rep_ev(ses, fd, scroll, 1 + 5 * !ses->kbdprefix.rep); + else if (ev->ev == EV_MOUSE && (ev->b & BM_BUTT) == B_WHEELLEFT) rep_ev(ses, fd, hscroll, -1 - 3 * !ses->kbdprefix.rep); + else if (ev->ev == EV_MOUSE && (ev->b & BM_BUTT) == B_WHEELRIGHT) rep_ev(ses, fd, hscroll, 1 + 3 * !ses->kbdprefix.rep); + else if (ev->ev == EV_MOUSE && (ev->b & BM_BUTT) <= B_RIGHT) { struct link *l = choose_mouse_link(fd, ev); if (l) { x = 1; diff --git a/x.c b/x.c @@ -73,7 +73,7 @@ static int x_default_window_width; static int x_default_window_height; static long (*x_get_color_function)(int); -static void x_translate_colors(unsigned char *data, int x, int y, int skip); +static void x_translate_colors(unsigned char *data, int x, int y, ssize_t skip); static void selection_request(XEvent *event); @@ -1043,8 +1043,8 @@ static int x_decode_button(int b) { switch (b) { case 1: return B_LEFT; - case 3: return B_RIGHT; case 2: return B_MIDDLE; + case 3: return B_RIGHT; case 4: return B_WHEELUP; case 5: return B_WHEELDOWN; case 6: return B_WHEELLEFT; @@ -1276,7 +1276,6 @@ static void x_process_events(void *data) ret:; } - /* returns pointer to string with driver parameter or NULL */ static unsigned char *x_get_driver_param(void) { @@ -1796,7 +1795,7 @@ static unsigned short *x_get_real_colors(void) return v; } -static void x_translate_colors(unsigned char *data, int x, int y, int skip) +static void x_translate_colors(unsigned char *data, int x, int y, ssize_t skip) { int i, j;