Skip to content

Commit 4760d8f

Browse files
authored
Merge pull request #196 from EionRobb/websocket-updates
Fix a couple of websocket crashes.
2 parents 88517ee + a554d59 commit 4760d8f

File tree

6 files changed

+212
-16
lines changed

6 files changed

+212
-16
lines changed

.github/workflows/cross.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: Cross compile for Windows
2+
on:
3+
- push
4+
- pull_request
5+
jobs:
6+
build:
7+
name: build
8+
runs-on: ubuntu-latest
9+
permissions:
10+
id-token: write
11+
contents: write
12+
attestations: write
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up MinGW
18+
run: |
19+
sudo apt update
20+
sudo apt install -y gcc-mingw-w64-i686-win32
21+
22+
- name: Load Pidgin from cache
23+
id: pidgin-cache
24+
uses: actions/cache@v4
25+
with:
26+
path: pidgin
27+
key: pidgin-2.10.11
28+
29+
- name: Download Pidgin
30+
if: steps.pidgin-cache.outputs.cache-hit != 'true'
31+
run: |
32+
curl --http1.1 -L https://sourceforge.net/projects/pidgin/files/Pidgin/2.10.11/pidgin-2.10.11.tar.bz2/download -o pidgin.tar.bz2
33+
tar -xf pidgin.tar.bz2
34+
mv pidgin-2.10.11 pidgin
35+
curl --http1.1 -L https://sourceforge.net/projects/pidgin/files/Pidgin/2.10.11/pidgin-2.10.11-win32-bin.zip/download -o pidgin-win32bin.zip
36+
unzip pidgin-win32bin.zip
37+
cp pidgin-2.10.11-win32bin/libpurple.dll pidgin/libpurple/
38+
39+
- name: Load Win32 deps from cache
40+
id: win32-cache
41+
uses: actions/cache@v4
42+
with:
43+
path: win32-dev
44+
key: win32-dev
45+
46+
- name: Setup WinPidgin build
47+
if: steps.win32-cache.outputs.cache-hit != 'true'
48+
run: |
49+
mkdir win32-dev
50+
curl --http1.1 -L https://download.gnome.org/binaries/win32/glib/2.28/glib-dev_2.28.8-1_win32.zip -o glib-dev.zip
51+
unzip glib-dev.zip -d win32-dev/glib-2.28.8
52+
curl --http1.1 -L https://download.gnome.org/binaries/win32/dependencies/gettext-runtime-dev_0.18.1.1-2_win32.zip -o gettext-runtime.zip
53+
unzip gettext-runtime.zip -d win32-dev/glib-2.28.8
54+
curl --http1.1 -L https://download.gnome.org/binaries/win32/dependencies/zlib-dev_1.2.5-2_win32.zip -o zlib-dev.zip
55+
unzip zlib-dev.zip -d win32-dev/glib-2.28.8
56+
57+
ls win32-dev/
58+
59+
- name: make
60+
run: |
61+
export WIN32_CC=i686-w64-mingw32-gcc
62+
export WIN32_DEV_TOP=win32-dev
63+
export PIDGIN_TREE_TOP=pidgin
64+
make libslack.dll
65+
66+
- name: archive
67+
if: ${{ !env.ACT }}
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: plugin
71+
path: lib*.dll
72+
73+
- name: release
74+
if: ${{ !env.ACT }}
75+
uses: ncipollo/release-action@v1
76+
with:
77+
artifacts: lib*.dll
78+
tag: nightly-${{ github.sha }}
79+
name: Nightly ${{ github.sha }}
80+
allowUpdates: true
81+
makeLatest: true
82+
83+
- name: attest
84+
if: ${{ !env.ACT }}
85+
uses: actions/attest-build-provenance@v1
86+
with:
87+
subject-path: lib*.dll

.github/workflows/linux-arm64.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Linux ARM64
2+
on:
3+
- push
4+
- pull_request
5+
jobs:
6+
build:
7+
name: build
8+
runs-on: ubuntu-24.04-arm
9+
permissions:
10+
id-token: write
11+
contents: write
12+
attestations: write
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: install deps
18+
run: |
19+
sudo apt update
20+
sudo apt install -y libglib2.0-dev gettext
21+
# We only need these to build, not to run. Skip the dependency check.
22+
sudo apt download libpurple0t64 libpurple-dev
23+
sudo dpkg --force-depends -i libpurple0t64*.deb libpurple-dev*.deb
24+
25+
- name: make
26+
run: |
27+
make
28+
file libslack.so
29+
mv libslack.so libslack_arm64.so
30+
31+
- name: archive
32+
if: ${{ !env.ACT }}
33+
uses: actions/upload-artifact@v4
34+
with:
35+
name: plugin
36+
path: lib*.so
37+
38+
- name: release
39+
if: ${{ !env.ACT }}
40+
uses: ncipollo/release-action@v1
41+
with:
42+
artifacts: lib*.so
43+
tag: nightly-${{ github.sha }}
44+
name: Nightly ${{ github.sha }}
45+
allowUpdates: true
46+
makeLatest: true
47+
48+
- name: attest
49+
if: ${{ !env.ACT }}
50+
uses: actions/attest-build-provenance@v1
51+
with:
52+
subject-path: lib*.so

.github/workflows/linux.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Linux
2+
on:
3+
- push
4+
- pull_request
5+
jobs:
6+
build:
7+
name: build
8+
runs-on: ubuntu-latest
9+
permissions:
10+
id-token: write
11+
contents: write
12+
attestations: write
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: install deps
18+
run: |
19+
sudo apt update
20+
sudo apt install -y libglib2.0-dev gettext
21+
# We only need these to build, not to run. Skip the dependency check.
22+
sudo apt download libpurple0t64 libpurple-dev
23+
sudo dpkg --force-depends -i libpurple0t64*.deb libpurple-dev*.deb
24+
- name: make
25+
run: make
26+
27+
- name: archive
28+
if: ${{ !env.ACT }}
29+
uses: actions/upload-artifact@v4
30+
with:
31+
name: plugin
32+
path: lib*.so
33+
34+
- name: release
35+
if: ${{ !env.ACT }}
36+
uses: ncipollo/release-action@v1
37+
with:
38+
artifacts: lib*.so
39+
tag: nightly-${{ github.sha }}
40+
name: Nightly ${{ github.sha }}
41+
allowUpdates: true
42+
makeLatest: true
43+
44+
- name: attest
45+
if: ${{ !env.ACT }}
46+
uses: actions/attest-build-provenance@v1
47+
with:
48+
subject-path: lib*.so

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
name: build
88
runs-on: ubuntu-latest
99
steps:
10-
- uses: actions/checkout@v2
10+
- uses: actions/checkout@v4
1111
- run: sudo apt-get install libpurple-dev
1212
- name: make
1313
#env:

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ endif
3535
CC = $(WIN32_DEV_TOP)/mingw-4.7.2/bin/gcc
3636

3737
DATA_ROOT_DIR_PURPLE:="$(PROGFILES32)/Pidgin"
38-
PLUGIN_DIR_PURPLE:="$(DATA_ROOT_DIR_PURPLE)/plugins"
38+
PLUGIN_DIR_PURPLE:="$(PROGFILES32)/Pidgin/plugins"
3939
CFLAGS = \
4040
-g \
4141
-O2 \
@@ -88,7 +88,7 @@ json.%: json-parser/json.%
8888
$(LIBNAME): $(C_OBJS)
8989
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
9090

91-
.PHONY: install install-user
91+
.PHONY: install install-user install-win32
9292
install: $(LIBNAME)
9393
install -d $(PLUGIN_DIR_PURPLE)
9494
install $(LIBNAME) $(PLUGIN_DIR_PURPLE)
@@ -97,6 +97,12 @@ install: $(LIBNAME)
9797
install -m 0644 img/slack$$z.png $(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/$$z/slack.png ; \
9898
done
9999

100+
install-win32: $(LIBNAME)
101+
install $(LIBNAME) $(PLUGIN_DIR_PURPLE)
102+
for z in 16 22 48 ; do \
103+
install -m 0644 img/slack$$z.png $(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/$$z/slack.png ; \
104+
done
105+
100106
install-user: $(LIBNAME)
101107
install -d $(HOME)/.purple/plugins
102108
install $(LIBNAME) $(HOME)/.purple/plugins

purple-websocket.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,19 @@ static inline guchar *buffer_incr(struct buffer *b, size_t n) {
6868
}
6969

7070
void purple_websocket_abort(PurpleWebsocket *ws) {
71+
if (ws == NULL)
72+
return;
73+
7174
if (ws->ssl_connection != NULL)
7275
purple_ssl_close(ws->ssl_connection);
7376

7477
if (ws->connection != NULL)
7578
purple_proxy_connect_cancel(ws->connection);
7679

77-
purple_debug_misc("websocket", "removing input %d\n", ws->inpa);
80+
purple_debug_misc("websocket", "removing input %u\n", ws->inpa);
7881
if (ws->inpa > 0)
7982
purple_input_remove(ws->inpa);
8083

81-
if (ws->fd >= 0)
82-
close(ws->fd);
83-
8484
g_free(ws->key);
8585
g_free(ws->output.buf);
8686
g_free(ws->input.buf);
@@ -105,6 +105,7 @@ static const char *skip_lws(const char *s) {
105105
s += 3;
106106
break;
107107
}
108+
return NULL;
108109
case '\n':
109110
case '\0':
110111
return NULL;
@@ -129,11 +130,11 @@ static const char *find_header_content(const char *data, const char *name) {
129130

130131
static gboolean ws_read_headers(PurpleWebsocket *ws, const char *headers) {
131132
const char *upgrade = skip_lws(find_header_content(headers, "Upgrade"));
132-
if (upgrade && (g_ascii_strncasecmp(upgrade, "websocket", 9) || skip_lws(upgrade+9)))
133+
if (upgrade && (g_ascii_strncasecmp(upgrade, "websocket", 9) != 0 || skip_lws(upgrade+9)))
133134
upgrade = NULL;
134135

135136
const char *connection = find_header_content(headers, "Connection");
136-
while ((connection = skip_lws(connection)) && g_ascii_strncasecmp(connection, "Upgrade", 7))
137+
while ((connection = skip_lws(connection)) && g_ascii_strncasecmp(connection, "Upgrade", 7) != 0)
137138
while (*connection++ != ',' && (connection = skip_lws(connection)));
138139
if (connection) {
139140
const char *e = skip_lws(connection+7);
@@ -150,14 +151,14 @@ static gboolean ws_read_headers(PurpleWebsocket *ws, const char *headers) {
150151
g_free(k);
151152
gchar *b = g_base64_encode(s, l);
152153
l = strlen(b);
153-
if (strncmp(accept, b, l) || skip_lws(accept+l))
154+
if (strncmp(accept, b, l) != 0 || skip_lws(accept+l))
154155
accept = NULL;
155156
g_free(b);
156157
}
157158

158159
/* TODO: Sec-WebSocket-Extensions, Sec-WebSocket-Protocol */
159160

160-
if (strncmp(headers, "HTTP/1.1 101 ", 13) || !upgrade || !connection || !accept) {
161+
if (strncmp(headers, "HTTP/1.1 101 ", 13) != 0 || !upgrade || !connection || !accept) {
161162
ws_error(ws, headers);
162163
return FALSE;
163164
}
@@ -249,6 +250,7 @@ static size_t ws_read_message(PurpleWebsocket *ws) {
249250
break;
250251
default:
251252
ws_error(ws, "Unknown frame op");
253+
return 0;
252254
}
253255
return off;
254256
}
@@ -281,7 +283,7 @@ static gboolean ws_input(PurpleWebsocket *ws) {
281283
return FALSE;
282284
}
283285

284-
if (cond)
286+
if (cond != 0)
285287
ws->inpa = purple_input_add(ws->fd, cond, ws_input_cb, ws);
286288
return TRUE;
287289
}
@@ -290,9 +292,9 @@ static void ws_input_cb(gpointer data, G_GNUC_UNUSED gint source, PurpleInputCon
290292
PurpleWebsocket *ws = data;
291293

292294
if (cond & PURPLE_INPUT_WRITE) {
293-
ssize_t len = ws->output.off >= ws->output.len ? 0 :
295+
gssize len = ws->output.off >= ws->output.len ? 0 :
294296
ws->ssl_connection
295-
? (ssize_t)purple_ssl_write(ws->ssl_connection, ws->output.buf + ws->output.off, ws->output.len - ws->output.off)
297+
? purple_ssl_write(ws->ssl_connection, ws->output.buf + ws->output.off, ws->output.len - ws->output.off)
296298
: write(ws->fd, ws->output.buf + ws->output.off, ws->output.len - ws->output.off);
297299

298300
if (len < 0) {
@@ -315,8 +317,8 @@ static void ws_input_cb(gpointer data, G_GNUC_UNUSED gint source, PurpleInputCon
315317

316318
while (cond & PURPLE_INPUT_READ) {
317319
g_return_if_fail(ws->input.off < ws->input.len);
318-
ssize_t len = ws->ssl_connection
319-
? (ssize_t)purple_ssl_read(ws->ssl_connection, ws->input.buf + ws->input.off, ws->input.siz - ws->input.off)
320+
gssize len = ws->ssl_connection
321+
? purple_ssl_read(ws->ssl_connection, ws->input.buf + ws->input.off, ws->input.siz - ws->input.off)
320322
: read(ws->fd, ws->input.buf + ws->input.off, ws->input.siz - ws->input.off);
321323

322324
if (len < 0) {
@@ -382,6 +384,7 @@ static void ws_input_cb(gpointer data, G_GNUC_UNUSED gint source, PurpleInputCon
382384
}
383385

384386
void purple_websocket_send(PurpleWebsocket *ws, PurpleWebsocketOp op, const guchar *msg, size_t len) {
387+
g_return_if_fail(ws);
385388
g_return_if_fail(ws->connected && !(ws->closed & PURPLE_INPUT_WRITE));
386389
g_return_if_fail(!(op & ~WS_OP_MASK));
387390
gboolean buf = ws->output.len;

0 commit comments

Comments
 (0)