Fix some memory safety issues

7e0661619255acae0e853029e4c773054b49bf28
Alexis Sellier committed ago 1 parent 53030e41
swm.c +13 -5
1861 1861
        if (!locked && cursor_mode != CURSOR_NORMAL && cursor_mode != CURSOR_PRESSED) {
1862 1862
            if (cursor_mode == CURSOR_RESIZE)
1863 1863
                client_set_resizing(grabc, 0);
1864 1864
            wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
1865 1865
            cursor_mode = CURSOR_NORMAL;
1866 -
            /* Move the window to the workspace on its new display. */
1866 +
            /* Move the window to the workspace on its new display. The
1867 +
             * cursor can sit outside every output (on a layout edge or in a
1868 +
             * gap); keep the window on its current display in that case. */
1867 1869
            selmon = point_to_monitor(cursor->x, cursor->y);
1868 -
            set_monitor(grabc, selmon, 0);
1870 +
            set_monitor(grabc, selmon ? selmon : grabc->mon, 0);
1869 1871
            remember_client(grabc);
1870 1872
            grabc = nullptr;
1871 1873
            return;
1872 1874
        }
1873 1875
        cursor_mode = CURSOR_NORMAL;
2130 2132
        client_get_geometry(c, &geom);
2131 2133
        swm_box_reconcile_commit(
2132 2134
            (struct swm_box *)&c->geom, geom.width, geom.height, c->bw, c->resize_edges
2133 2135
        );
2134 2136
    }
2135 -
    if (c->resize) {
2137 +
    if (c->resize && c->mon) {
2136 2138
        uint32_t resize_serial = c->resize;
2137 2139
        int      latest        = resize_serial <= c->surface.xdg->current.configure_serial;
2138 2140
2139 2141
        apply_bounds(c, &c->mon->w);
2140 2142
        resize_apply(c);
2141 2143
2142 2144
        if (latest)
2143 2145
            c->resize = 0;
2144 2146
        else
2145 2147
            c->geom = c->pending_geom;
2148 +
    } else if (c->resize) {
2149 +
        /* The client lost its display with a resize in flight; settle the
2150 +
         * resize once a display is available again. */
2146 2151
    } else {
2147 2152
        resize(c, c->geom, c->is_floating && !c->is_fullscreen);
2148 2153
    }
2149 2154
    if (!c->resize)
2150 2155
        c->resize_edges = WLR_EDGE_NONE;
2767 2772
2768 2773
/* Return the nearest enabled display in the requested direction. */
2769 2774
monitor_t *direction_to_monitor(enum wlr_direction dir) {
2770 2775
    struct wlr_output *next;
2771 2776
2777 +
    if (!selmon)
2778 +
        return nullptr;
2779 +
2772 2780
    if (!wlr_output_layout_get(output_layout, selmon->wlr_output))
2773 2781
        return selmon;
2774 2782
2775 2783
    if ((next = wlr_output_layout_adjacent_output(
2776 2784
             output_layout, dir, selmon->wlr_output, selmon->m.x, selmon->m.y
2898 2906
2899 2907
/* Select the next enabled display and focus its top window. */
2900 2908
void focus_monitor(const arg_t *arg) {
2901 2909
    int i = 0, nmons = wl_list_length(&mons);
2902 2910
2903 -
    if (nmons) {
2911 +
    if (selmon && nmons) {
2904 2912
        do /* Skip disabled displays. */
2905 2913
            selmon = direction_to_monitor(arg->i);
2906 2914
        while (!selmon->wlr_output->enabled && i++ < nmons);
2907 2915
    }
2908 2916
    focus_client(focus_top(selmon), 1);
6011 6019
        wlr_xwayland_surface_configure(
6012 6020
            c->surface.xwayland, event->x, event->y, event->width, event->height
6013 6021
        );
6014 6022
        return;
6015 6023
    }
6016 -
    if ((c->is_floating && c != grabc) || !c->mon->ws || !c->mon->ws->lt->arrange) {
6024 +
    if ((c->is_floating && c != grabc) || !c->mon || !c->mon->ws || !c->mon->ws->lt->arrange) {
6017 6025
        resize(
6018 6026
            c,
6019 6027
            (struct wlr_box){ .x      = event->x - c->bw,
6020 6028
                              .y      = event->y - c->bw,
6021 6029
                              .width  = event->width + c->bw * 2,
util.c +3 -0
30 30
size_t env_expand(char *output, size_t capacity, const char *input) {
31 31
    const char *value;
32 32
    size_t      i = 0, len, out = 0, start;
33 33
    char        name[MAX_ENV_SIZE];
34 34
35 +
    if (!capacity)
36 +
        return 0;
37 +
35 38
    while (input[i]) {
36 39
        if (input[i] != '$') {
37 40
            if (out + 1 >= capacity)
38 41
                return 0;
39 42
            output[out++] = input[i];