#include "trace.h"
#include "sysemu/sysemu.h"
#include "qemu/error-report.h"
+#include "qemu/option.h"
#include "qemu/sockets.h"
#include "qemu/timer.h"
#include "qemu/acl.h"
#include "qemu/config-file.h"
-#include "qapi/qmp/qerror.h"
-#include "qapi/qmp/types.h"
-#include "qmp-commands.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-ui.h"
#include "ui/input.h"
#include "qapi-event.h"
#include "crypto/hash.h"
vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
if (vs->audio_cap) {
- int freq = vs->as.freq;
- /* We don't limit freq when reading settings from client, so
- * it could be upto MAX_INT in size. 48khz is a sensible
- * upper bound for trustworthy clients */
int bps;
- if (freq > 48000) {
- freq = 48000;
- }
switch (vs->as.fmt) {
default:
case AUD_FMT_U8:
bps = 4;
break;
}
- offset += freq * bps * vs->as.nchannels;
+ offset += vs->as.freq * bps * vs->as.nchannels;
}
/* Put a floor of 1MB on offset, so that if we have a large pending
VncState *vs = opaque;
if (condition & G_IO_IN) {
if (vnc_client_read(vs) < 0) {
- return TRUE;
+ goto end;
}
}
if (condition & G_IO_OUT) {
vnc_client_write(vs);
}
+end:
+ if (vs->disconnecting) {
+ if (vs->ioc_tag != 0) {
+ g_source_remove(vs->ioc_tag);
+ }
+ vs->ioc_tag = 0;
+ }
return TRUE;
}
* handshake, or from the job thread's VncState clone
*/
if (vs->throttle_output_offset != 0 &&
- vs->output.offset > (vs->throttle_output_offset *
- VNC_THROTTLE_OUTPUT_LIMIT_SCALE)) {
+ (vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) >
+ vs->throttle_output_offset) {
trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
vs->throttle_output_offset);
vnc_disconnect_start(vs);
if (vs->ioc != NULL && vs->output.offset) {
vnc_client_write_locked(vs);
}
+ if (vs->disconnecting) {
+ if (vs->ioc_tag != 0) {
+ g_source_remove(vs->ioc_tag);
+ }
+ vs->ioc_tag = 0;
+ }
vnc_unlock_output(vs);
}
static void press_key(VncState *vs, int keysym)
{
- int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
+ int keycode = keysym2scancode(vs->vd->kbd_layout, keysym,
+ false, false, false) & SCANCODE_KEYMASK;
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
static void key_event(VncState *vs, int down, uint32_t sym)
{
+ bool shift = vs->modifiers_state[0x2a] || vs->modifiers_state[0x36];
+ bool altgr = vs->modifiers_state[0xb8];
+ bool ctrl = vs->modifiers_state[0x1d] || vs->modifiers_state[0x9d];
int keycode;
int lsym = sym;
lsym = lsym - 'A' + 'a';
}
- keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
+ keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
+ shift, altgr, ctrl) & SCANCODE_KEYMASK;
trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
do_key_event(vs, down, keycode, sym);
}
{
int i;
uint16_t limit;
+ uint32_t freq;
VncDisplay *vd = vs->vd;
if (data[0] > 3) {
vnc_client_error(vs);
break;
}
- vs->as.freq = read_u32(data, 6);
+ freq = read_u32(data, 6);
+ /* No official limit for protocol, but 48khz is a sensible
+ * upper bound for trustworthy clients, and this limit
+ * protects calculations involving 'vs->as.freq' later.
+ */
+ if (freq > 48000) {
+ VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
+ vnc_client_error(vs);
+ break;
+ }
+ vs->as.freq = freq;
break;
default:
VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
isWebsock ? "vnc-ws-server" : "vnc-server");
qio_channel_set_delay(QIO_CHANNEL(cioc), false);
vnc_connect(vd, cioc, false, isWebsock);
- object_unref(OBJECT(cioc));
}
static const DisplayChangeListenerOps dcl_ops = {