mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-31 22:25:25 -04:00
Compare commits
15 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
736d12ac67 | ||
|
|
0fa6f267f2 | ||
|
|
398e1297ee | ||
|
|
e35f1efb59 | ||
|
|
081f8af18a | ||
|
|
9099588de1 | ||
|
|
a834596d4c | ||
|
|
1d6fba989d | ||
|
|
832c7be742 | ||
|
|
86cfd575ca | ||
|
|
65ce8920e2 | ||
|
|
98d7bbee0a | ||
|
|
cd566cd232 | ||
|
|
504dbf2303 | ||
|
|
b26180dfea |
10 changed files with 194 additions and 77 deletions
|
|
@ -27,6 +27,7 @@
|
|||
#include "xcursor.h"
|
||||
#include "wayland-cursor.h"
|
||||
#include "wayland-client.h"
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -284,7 +285,8 @@ wl_cursor_create_from_xcursor_images(struct xcursor_images *images,
|
|||
{
|
||||
struct cursor *cursor;
|
||||
struct cursor_image *image;
|
||||
int i, size;
|
||||
size_t size;
|
||||
int i;
|
||||
|
||||
cursor = malloc(sizeof *cursor);
|
||||
if (!cursor)
|
||||
|
|
@ -314,7 +316,12 @@ wl_cursor_create_from_xcursor_images(struct xcursor_images *images,
|
|||
image->image.hotspot_y = images->images[i]->yhot;
|
||||
image->image.delay = images->images[i]->delay;
|
||||
|
||||
size = image->image.width * image->image.height * 4;
|
||||
size = (size_t) image->image.width * image->image.height * 4;
|
||||
if (size > INT_MAX) {
|
||||
free(image);
|
||||
break;
|
||||
}
|
||||
|
||||
image->offset = shm_pool_allocate(theme->pool, size);
|
||||
if (image->offset < 0) {
|
||||
free(image);
|
||||
|
|
@ -344,6 +351,8 @@ load_callback(struct xcursor_images *images, void *data)
|
|||
{
|
||||
struct wl_cursor_theme *theme = data;
|
||||
struct wl_cursor *cursor;
|
||||
struct wl_cursor **p;
|
||||
size_t s;
|
||||
|
||||
if (wl_cursor_theme_get_cursor(theme, images->name)) {
|
||||
xcursor_images_destroy(images);
|
||||
|
|
@ -353,15 +362,14 @@ load_callback(struct xcursor_images *images, void *data)
|
|||
cursor = wl_cursor_create_from_xcursor_images(images, theme);
|
||||
|
||||
if (cursor) {
|
||||
theme->cursor_count++;
|
||||
theme->cursors =
|
||||
realloc(theme->cursors,
|
||||
theme->cursor_count * sizeof theme->cursors[0]);
|
||||
s = theme->cursor_count + 1;
|
||||
p = realloc(theme->cursors, s * sizeof theme->cursors[0]);
|
||||
|
||||
if (theme->cursors == NULL) {
|
||||
theme->cursor_count--;
|
||||
if (p == NULL) {
|
||||
free(cursor);
|
||||
} else {
|
||||
theme->cursor_count = s;
|
||||
theme->cursors = p;
|
||||
theme->cursors[theme->cursor_count - 1] = cursor;
|
||||
}
|
||||
}
|
||||
|
|
@ -389,6 +397,9 @@ wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
|
|||
if (!theme)
|
||||
return NULL;
|
||||
|
||||
if (size < 0 || (size > 0 && INT_MAX / size / 4 < size))
|
||||
return NULL;
|
||||
|
||||
if (!name)
|
||||
name = "default";
|
||||
|
||||
|
|
|
|||
|
|
@ -259,6 +259,8 @@ xcursor_read_file_header(FILE *file)
|
|||
return NULL;
|
||||
if (!xcursor_read_uint(file, &head.ntoc))
|
||||
return NULL;
|
||||
if (head.header < XCURSOR_FILE_HEADER_LEN)
|
||||
return NULL;
|
||||
skip = head.header - XCURSOR_FILE_HEADER_LEN;
|
||||
if (skip)
|
||||
if (fseek(file, skip, SEEK_CUR) == EOF)
|
||||
|
|
@ -571,7 +573,7 @@ xcursor_build_theme_dir(const char *dir, const char *theme)
|
|||
* add space for any needed directory separators, one per component,
|
||||
* and one for the trailing null
|
||||
*/
|
||||
full_size = 1 + homelen + 1 + dirlen + 1 + themelen + 1;
|
||||
full_size = (size_t) 1 + homelen + 1 + dirlen + 1 + themelen + 1;
|
||||
full = malloc(full_size);
|
||||
if (!full)
|
||||
return NULL;
|
||||
|
|
@ -686,11 +688,15 @@ load_all_cursors_from_dir(const char *path, int size,
|
|||
void *user_data)
|
||||
{
|
||||
FILE *f;
|
||||
DIR *dir = opendir(path);
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
char *full;
|
||||
struct xcursor_images *images;
|
||||
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ if get_option('tests')
|
|||
test(
|
||||
'wayland-egl symbols check',
|
||||
find_program('wayland-egl-symbols-check'),
|
||||
depends: wayland_egl,
|
||||
env: [
|
||||
'WAYLAND_EGL_LIB=@0@'.format(wayland_egl_shared.full_path()),
|
||||
'NM=@0@'.format(nm_path)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
project(
|
||||
'wayland', 'c',
|
||||
version: '1.23.91',
|
||||
version: '1.24.0',
|
||||
license: 'MIT',
|
||||
meson_version: '>= 0.57.0',
|
||||
default_options: [
|
||||
|
|
|
|||
|
|
@ -1229,6 +1229,11 @@ wl_closure_invoke(struct wl_closure *closure, uint32_t flags,
|
|||
count + 2, &ffi_type_void, ffi_types);
|
||||
|
||||
implementation = target->implementation;
|
||||
if (!implementation) {
|
||||
wl_abort("Implementation of resource %d of %s is NULL\n",
|
||||
target->id, target->interface->name);
|
||||
}
|
||||
|
||||
if (!implementation[opcode]) {
|
||||
wl_abort("listener function for opcode %u of %s is NULL\n",
|
||||
opcode, target->interface->name);
|
||||
|
|
|
|||
|
|
@ -1564,6 +1564,28 @@ queue_event(struct wl_display *display, int len)
|
|||
id = p[0];
|
||||
opcode = p[1] & 0xffff;
|
||||
size = p[1] >> 16;
|
||||
|
||||
/*
|
||||
* If the message is larger than the maximum size of the
|
||||
* connection buffer, the connection buffer will fill to
|
||||
* its max size and stay there, with no message ever
|
||||
* successfully being processed. If the user of
|
||||
* libwayland-client uses a level-triggered event loop,
|
||||
* this will cause the client to enter a loop that
|
||||
* consumes CPU. To avoid this, immediately drop the
|
||||
* connection. Since the maximum size of a message should
|
||||
* not depend on the max buffer size chosen by the client,
|
||||
* always compare the message size against the
|
||||
* limit enforced by libwayland 1.22 and below (4096),
|
||||
* rather than the actual value the client chose.
|
||||
*/
|
||||
if (size > WL_MAX_MESSAGE_SIZE) {
|
||||
wl_log("Message length %u exceeds limit %d\n",
|
||||
size, WL_MAX_MESSAGE_SIZE);
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len < size)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1579,7 +1601,7 @@ queue_event(struct wl_display *display, int len)
|
|||
clock_gettime(CLOCK_REALTIME, &tp);
|
||||
time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
|
||||
|
||||
fprintf(stderr, "[%7u.%03u] discarded [%s]#%d.[event %d]"
|
||||
fprintf(stderr, "[%7u.%03u] discarded [%s]#%u.[event %d]"
|
||||
"(%d fd, %d byte)\n",
|
||||
time / 1000, time % 1000,
|
||||
zombie ? "zombie" : "unknown",
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@
|
|||
#define WL_CLOSURE_MAX_ARGS 20
|
||||
#define WL_BUFFER_DEFAULT_SIZE_POT 12
|
||||
#define WL_BUFFER_DEFAULT_MAX_SIZE (1 << WL_BUFFER_DEFAULT_SIZE_POT)
|
||||
#if WL_BUFFER_DEFAULT_MAX_SIZE < WL_MAX_MESSAGE_SIZE
|
||||
# error default buffer cannot hold maximum-sized message
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Argument types used in signatures.
|
||||
|
|
|
|||
|
|
@ -397,6 +397,29 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
|
|||
wl_connection_copy(connection, p, sizeof p);
|
||||
opcode = p[1] & 0xffff;
|
||||
size = p[1] >> 16;
|
||||
|
||||
/*
|
||||
* If the message is larger than the maximum size of the
|
||||
* connection buffer, the connection buffer will fill to
|
||||
* its max size and stay there, with no message ever
|
||||
* successfully being processed. Since libwayland-server
|
||||
* uses level-triggered epoll, it will cause the server to
|
||||
* enter a loop that consumes CPU. To avoid this,
|
||||
* immediately disconnect the client with a protocol
|
||||
* error. Since the maximum size of a message should not
|
||||
* depend on the buffer size chosen by the compositor,
|
||||
* always compare the message size against the
|
||||
* limit enforced by libwayland 1.22 and below (4096),
|
||||
* rather than the actual value the compositor chose.
|
||||
*/
|
||||
if (size > WL_MAX_MESSAGE_SIZE) {
|
||||
wl_resource_post_error(client->display_resource,
|
||||
WL_DISPLAY_ERROR_INVALID_METHOD,
|
||||
"message length %u exceeds %d",
|
||||
size, WL_MAX_MESSAGE_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (len < size)
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,14 @@ extern "C" {
|
|||
*/
|
||||
struct wl_object;
|
||||
|
||||
/**
|
||||
* The maximum size of a protocol message.
|
||||
*
|
||||
* If a message size exceeds this value, the connection will be dropped.
|
||||
* Servers will send an invalid_method error before disconnecting.
|
||||
*/
|
||||
#define WL_MAX_MESSAGE_SIZE 4096
|
||||
|
||||
/**
|
||||
* Protocol message signature
|
||||
*
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ tests_protocol_c = custom_target(
|
|||
output: 'tests-protocol.c'
|
||||
)
|
||||
|
||||
executable(
|
||||
exec_fd_leak_checker = executable(
|
||||
'exec-fd-leak-checker',
|
||||
'exec-fd-leak-checker.c',
|
||||
dependencies: test_runner_dep
|
||||
|
|
@ -96,78 +96,116 @@ if get_option('scanner')
|
|||
endif
|
||||
|
||||
tests = {
|
||||
'array-test': [],
|
||||
'client-test': [ wayland_server_protocol_h ],
|
||||
'display-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
tests_server_protocol_h,
|
||||
tests_client_protocol_c,
|
||||
tests_protocol_c,
|
||||
],
|
||||
'connection-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'event-loop-test': [ wayland_server_protocol_h ],
|
||||
'fixed-test': [],
|
||||
'interface-test': [ wayland_client_protocol_h ],
|
||||
'list-test': [],
|
||||
'map-test': [],
|
||||
'sanity-test' : [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'socket-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'queue-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'signal-test': [ wayland_server_protocol_h ],
|
||||
'newsignal-test': [
|
||||
# wayland-server.c is needed here to access wl_priv_* functions
|
||||
files('../src/wayland-server.c'),
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'resources-test': [ wayland_server_protocol_h ],
|
||||
'message-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'compositor-introspection-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'protocol-logger-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'headers-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
'headers-protocol-test.c',
|
||||
wayland_client_protocol_core_h,
|
||||
wayland_server_protocol_core_h,
|
||||
'headers-protocol-core-test.c',
|
||||
],
|
||||
'os-wrappers-test': [],
|
||||
'proxy-test': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'enum-validator-test': [],
|
||||
'array-test': {},
|
||||
'client-test': {
|
||||
'extra_sources': [ wayland_server_protocol_h ],
|
||||
},
|
||||
'display-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
tests_server_protocol_h,
|
||||
tests_client_protocol_c,
|
||||
tests_protocol_c,
|
||||
],
|
||||
},
|
||||
'connection-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
},
|
||||
'event-loop-test': {
|
||||
'extra_sources': [ wayland_server_protocol_h ],
|
||||
},
|
||||
'fixed-test': {},
|
||||
'interface-test': {
|
||||
'extra_sources': [ wayland_client_protocol_h ],
|
||||
},
|
||||
'list-test': {},
|
||||
'map-test': {},
|
||||
'sanity-test' : {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
'runtime_deps': [ exec_fd_leak_checker ],
|
||||
},
|
||||
'socket-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
},
|
||||
'queue-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
},
|
||||
'signal-test': {
|
||||
'extra_sources': [ wayland_server_protocol_h ],
|
||||
},
|
||||
'newsignal-test': {
|
||||
'extra_sources': [
|
||||
# wayland-server.c is needed here to access wl_priv_* functions
|
||||
files('../src/wayland-server.c'),
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
},
|
||||
'resources-test': {
|
||||
'extra_sources': [ wayland_server_protocol_h ],
|
||||
},
|
||||
'message-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
},
|
||||
'compositor-introspection-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
},
|
||||
'protocol-logger-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
},
|
||||
'headers-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
'headers-protocol-test.c',
|
||||
wayland_client_protocol_core_h,
|
||||
wayland_server_protocol_core_h,
|
||||
'headers-protocol-core-test.c',
|
||||
],
|
||||
},
|
||||
'os-wrappers-test': {
|
||||
'runtime_deps': [ exec_fd_leak_checker ],
|
||||
},
|
||||
'proxy-test': {
|
||||
'extra_sources': [
|
||||
wayland_client_protocol_h,
|
||||
wayland_server_protocol_h,
|
||||
],
|
||||
},
|
||||
'enum-validator-test': {},
|
||||
}
|
||||
|
||||
foreach test_name, test_extra_sources: tests
|
||||
foreach test_name, test_extras : tests
|
||||
test_extra_sources = test_extras.get('extra_sources', [])
|
||||
test_runtime_deps = test_extras.get('runtime_deps', [])
|
||||
test_sources = [ test_name + '.c' ] + test_extra_sources
|
||||
test_deps = [test_runner_dep, epoll_dep]
|
||||
bin = executable(test_name, test_sources, dependencies: test_deps)
|
||||
test(
|
||||
test_name,
|
||||
bin,
|
||||
depends: test_runtime_deps,
|
||||
env: [
|
||||
'TEST_SRC_DIR=@0@'.format(meson.current_source_dir()),
|
||||
'TEST_BUILD_DIR=@0@'.format(meson.current_build_dir()),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue