~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/fb/fbpixmap.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Id: fbpixmap.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
 
3
 *
 
4
 * Copyright � 1998 Keith Packard
 
5
 *
 
6
 * Permission to use, copy, modify, distribute, and sell this software and its
 
7
 * documentation for any purpose is hereby granted without fee, provided that
 
8
 * the above copyright notice appear in all copies and that both that
 
9
 * copyright notice and this permission notice appear in supporting
 
10
 * documentation, and that the name of Keith Packard not be used in
 
11
 * advertising or publicity pertaining to distribution of the software without
 
12
 * specific, written prior permission.  Keith Packard makes no
 
13
 * representations about the suitability of this software for any purpose.  It
 
14
 * is provided "as is" without express or implied warranty.
 
15
 *
 
16
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
18
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
19
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
20
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
21
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
22
 * PERFORMANCE OF THIS SOFTWARE.
 
23
 */
 
24
/* $XFree86: xc/programs/Xserver/fb/fbpixmap.c,v 1.11 2002/09/16 18:05:34 eich Exp $ */
 
25
 
 
26
#include "fb.h"
 
27
#ifdef IN_MODULE
 
28
#include "xf86_ansic.h"
 
29
#endif
 
30
 
 
31
PixmapPtr
 
32
fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp)
 
33
{
 
34
    PixmapPtr   pPixmap;
 
35
    int         datasize;
 
36
    int         paddedWidth;
 
37
    int         adjust;
 
38
    int         base;
 
39
 
 
40
    paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
 
41
    datasize = height * paddedWidth;
 
42
#ifdef PIXPRIV
 
43
    base = pScreen->totalPixmapSize;
 
44
#else
 
45
    base = sizeof (PixmapRec);
 
46
#endif
 
47
    adjust = 0;
 
48
    if (base & 7)
 
49
        adjust = 8 - (base & 7);
 
50
    datasize += adjust;
 
51
#ifdef FB_DEBUG
 
52
    datasize += 2 * paddedWidth;
 
53
#endif
 
54
    pPixmap = AllocatePixmap(pScreen, datasize);
 
55
    if (!pPixmap)
 
56
        return NullPixmap;
 
57
    pPixmap->drawable.type = DRAWABLE_PIXMAP;
 
58
    pPixmap->drawable.class = 0;
 
59
    pPixmap->drawable.pScreen = pScreen;
 
60
    pPixmap->drawable.depth = depth;
 
61
    pPixmap->drawable.bitsPerPixel = bpp;
 
62
    pPixmap->drawable.id = 0;
 
63
    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 
64
    pPixmap->drawable.x = 0;
 
65
    pPixmap->drawable.y = 0;
 
66
    pPixmap->drawable.width = width;
 
67
    pPixmap->drawable.height = height;
 
68
    pPixmap->devKind = paddedWidth;
 
69
    pPixmap->refcnt = 1;
 
70
    pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust);
 
71
#ifdef FB_DEBUG
 
72
    pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
 
73
    fbInitializeDrawable (&pPixmap->drawable);
 
74
#endif
 
75
 
 
76
    return pPixmap;
 
77
}
 
78
 
 
79
PixmapPtr
 
80
fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth)
 
81
{
 
82
    int bpp;
 
83
    bpp = BitsPerPixel (depth);
 
84
#ifdef FB_SCREEN_PRIVATE
 
85
    if (bpp == 32 && depth <= 24)
 
86
        bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
 
87
#endif
 
88
    return fbCreatePixmapBpp (pScreen, width, height, depth, bpp);
 
89
}
 
90
 
 
91
Bool
 
92
fbDestroyPixmap (PixmapPtr pPixmap)
 
93
{
 
94
    if(--pPixmap->refcnt)
 
95
        return TRUE;
 
96
    xfree(pPixmap);
 
97
    return TRUE;
 
98
}
 
99
 
 
100
#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2)                       \
 
101
if (((rx1) < (rx2)) && ((ry1) < (ry2)) &&                       \
 
102
    (!((reg)->data->numRects &&                                 \
 
103
       ((r-1)->y1 == (ry1)) &&                                  \
 
104
       ((r-1)->y2 == (ry2)) &&                                  \
 
105
       ((r-1)->x1 <= (rx1)) &&                                  \
 
106
       ((r-1)->x2 >= (rx2)))))                                  \
 
107
{                                                               \
 
108
    if ((reg)->data->numRects == (reg)->data->size)             \
 
109
    {                                                           \
 
110
        miRectAlloc(reg, 1);                                    \
 
111
        fr = REGION_BOXPTR(reg);                                \
 
112
        r = fr + (reg)->data->numRects;                         \
 
113
    }                                                           \
 
114
    r->x1 = (rx1);                                              \
 
115
    r->y1 = (ry1);                                              \
 
116
    r->x2 = (rx2);                                              \
 
117
    r->y2 = (ry2);                                              \
 
118
    (reg)->data->numRects++;                                    \
 
119
    if(r->x1 < (reg)->extents.x1)                               \
 
120
        (reg)->extents.x1 = r->x1;                              \
 
121
    if(r->x2 > (reg)->extents.x2)                               \
 
122
        (reg)->extents.x2 = r->x2;                              \
 
123
    r++;                                                        \
 
124
}
 
125
 
 
126
/* Convert bitmap clip mask into clipping region. 
 
127
 * First, goes through each line and makes boxes by noting the transitions
 
128
 * from 0 to 1 and 1 to 0.
 
129
 * Then it coalesces the current line with the previous if they have boxes
 
130
 * at the same X coordinates.
 
131
 */
 
132
RegionPtr
 
133
fbPixmapToRegion(PixmapPtr pPix)
 
134
{
 
135
    register RegionPtr  pReg;
 
136
    FbBits              *pw, w;
 
137
    register int        ib;
 
138
    int                 width, h, base, rx1 = 0, crects;
 
139
    FbBits              *pwLineEnd;
 
140
    int                 irectPrevStart, irectLineStart;
 
141
    register BoxPtr     prectO, prectN;
 
142
    BoxPtr              FirstRect, rects, prectLineStart;
 
143
    Bool                fInBox, fSame;
 
144
    register FbBits     mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1);
 
145
    FbBits              *pwLine;
 
146
    int                 nWidth;
 
147
    
 
148
    pReg = REGION_CREATE(pPix->drawable.pScreen, NULL, 1);
 
149
    if(!pReg)
 
150
        return NullRegion;
 
151
    FirstRect = REGION_BOXPTR(pReg);
 
152
    rects = FirstRect;
 
153
 
 
154
    pwLine = (FbBits *) pPix->devPrivate.ptr;
 
155
    nWidth = pPix->devKind >> (FB_SHIFT-3);
 
156
 
 
157
    width = pPix->drawable.width;
 
158
    pReg->extents.x1 = width - 1;
 
159
    pReg->extents.x2 = 0;
 
160
    irectPrevStart = -1;
 
161
    for(h = 0; h < pPix->drawable.height; h++)
 
162
    {
 
163
        pw = pwLine;
 
164
        pwLine += nWidth;
 
165
        irectLineStart = rects - FirstRect;
 
166
        /* If the Screen left most bit of the word is set, we're starting in
 
167
         * a box */
 
168
        if(*pw & mask0)
 
169
        {
 
170
            fInBox = TRUE;
 
171
            rx1 = 0;
 
172
        }
 
173
        else
 
174
            fInBox = FALSE;
 
175
        /* Process all words which are fully in the pixmap */
 
176
        pwLineEnd = pw + (width >> FB_SHIFT);
 
177
        for (base = 0; pw < pwLineEnd; base += FB_UNIT)
 
178
        {
 
179
            w = *pw++;
 
180
            if (fInBox)
 
181
            {
 
182
                if (!~w)
 
183
                    continue;
 
184
            }
 
185
            else
 
186
            {
 
187
                if (!w)
 
188
                    continue;
 
189
            }
 
190
            for(ib = 0; ib < FB_UNIT; ib++)
 
191
            {
 
192
                /* If the Screen left most bit of the word is set, we're
 
193
                 * starting a box */
 
194
                if(w & mask0)
 
195
                {
 
196
                    if(!fInBox)
 
197
                    {
 
198
                        rx1 = base + ib;
 
199
                        /* start new box */
 
200
                        fInBox = TRUE;
 
201
                    }
 
202
                }
 
203
                else
 
204
                {
 
205
                    if(fInBox)
 
206
                    {
 
207
                        /* end box */
 
208
                        ADDRECT(pReg, rects, FirstRect,
 
209
                                rx1, h, base + ib, h + 1);
 
210
                        fInBox = FALSE;
 
211
                    }
 
212
                }
 
213
                /* Shift the word VISUALLY left one. */
 
214
                w = FbScrLeft(w, 1);
 
215
            }
 
216
        }
 
217
        if(width & FB_MASK)
 
218
        {
 
219
            /* Process final partial word on line */
 
220
            w = *pw++;
 
221
            for(ib = 0; ib < (width & FB_MASK); ib++)
 
222
            {
 
223
                /* If the Screen left most bit of the word is set, we're
 
224
                 * starting a box */
 
225
                if(w & mask0)
 
226
                {
 
227
                    if(!fInBox)
 
228
                    {
 
229
                        rx1 = base + ib;
 
230
                        /* start new box */
 
231
                        fInBox = TRUE;
 
232
                    }
 
233
                }
 
234
                else
 
235
                {
 
236
                    if(fInBox)
 
237
                    {
 
238
                        /* end box */
 
239
                        ADDRECT(pReg, rects, FirstRect,
 
240
                                rx1, h, base + ib, h + 1);
 
241
                        fInBox = FALSE;
 
242
                    }
 
243
                }
 
244
                /* Shift the word VISUALLY left one. */
 
245
                w = FbScrLeft(w, 1);
 
246
            }
 
247
        }
 
248
        /* If scanline ended with last bit set, end the box */
 
249
        if(fInBox)
 
250
        {
 
251
            ADDRECT(pReg, rects, FirstRect,
 
252
                    rx1, h, base + (width & FB_MASK), h + 1);
 
253
        }
 
254
        /* if all rectangles on this line have the same x-coords as
 
255
         * those on the previous line, then add 1 to all the previous  y2s and 
 
256
         * throw away all the rectangles from this line 
 
257
         */
 
258
        fSame = FALSE;
 
259
        if(irectPrevStart != -1)
 
260
        {
 
261
            crects = irectLineStart - irectPrevStart;
 
262
            if(crects == ((rects - FirstRect) - irectLineStart))
 
263
            {
 
264
                prectO = FirstRect + irectPrevStart;
 
265
                prectN = prectLineStart = FirstRect + irectLineStart;
 
266
                fSame = TRUE;
 
267
                while(prectO < prectLineStart)
 
268
                {
 
269
                    if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
 
270
                    {
 
271
                          fSame = FALSE;
 
272
                          break;
 
273
                    }
 
274
                    prectO++;
 
275
                    prectN++;
 
276
                }
 
277
                if (fSame)
 
278
                {
 
279
                    prectO = FirstRect + irectPrevStart;
 
280
                    while(prectO < prectLineStart)
 
281
                    {
 
282
                        prectO->y2 += 1;
 
283
                        prectO++;
 
284
                    }
 
285
                    rects -= crects;
 
286
                    pReg->data->numRects -= crects;
 
287
                }
 
288
            }
 
289
        }
 
290
        if(!fSame)
 
291
            irectPrevStart = irectLineStart;
 
292
    }
 
293
    if (!pReg->data->numRects)
 
294
        pReg->extents.x1 = pReg->extents.x2 = 0;
 
295
    else
 
296
    {
 
297
        pReg->extents.y1 = REGION_BOXPTR(pReg)->y1;
 
298
        pReg->extents.y2 = REGION_END(pReg)->y2;
 
299
        if (pReg->data->numRects == 1)
 
300
        {
 
301
            xfree(pReg->data);
 
302
            pReg->data = (RegDataPtr)NULL;
 
303
        }
 
304
    }
 
305
#ifdef DEBUG
 
306
    if (!miValidRegion(pReg))
 
307
        FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
 
308
#endif
 
309
    return(pReg);
 
310
}
 
311
 
 
312
#ifdef FB_DEBUG
 
313
 
 
314
#ifndef WIN32
 
315
#include <stdio.h>
 
316
#else
 
317
#include <dbg.h>
 
318
#endif
 
319
 
 
320
static Bool
 
321
fbValidateBits (FbStip *bits, int stride, FbStip data)
 
322
{
 
323
    while (stride--)
 
324
    {
 
325
        if (*bits != data)
 
326
        {
 
327
#ifdef WIN32
 
328
            NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)",
 
329
                        bits, *bits, data));
 
330
#else
 
331
            fprintf (stderr, "fbValidateBits failed\n");
 
332
#endif
 
333
            return FALSE;
 
334
        }
 
335
        bits++;
 
336
    }
 
337
}
 
338
 
 
339
void
 
340
fbValidateDrawable (DrawablePtr pDrawable)
 
341
{
 
342
    FbStip      *bits, *first, *last;
 
343
    int         stride, bpp;
 
344
    int         xoff, yoff;
 
345
    int         height;
 
346
    Bool        failed;
 
347
    
 
348
    if (pDrawable->type != DRAWABLE_PIXMAP)
 
349
        pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable);
 
350
    fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
 
351
    first = bits - stride;
 
352
    last = bits + stride * pDrawable->height;
 
353
    if (!fbValidateBits (first, stride, FB_HEAD_BITS) ||
 
354
        !fbValidateBits (last, stride, FB_TAIL_BITS))
 
355
        fbInitializeDrawable(pDrawable);
 
356
}
 
357
 
 
358
void
 
359
fbSetBits (FbStip *bits, int stride, FbStip data)
 
360
{
 
361
    while (stride--)
 
362
        *bits++ = data;
 
363
}
 
364
 
 
365
void
 
366
fbInitializeDrawable (DrawablePtr pDrawable)
 
367
{
 
368
    FbStip  *bits, *first, *last;
 
369
    int     stride, bpp;
 
370
    int     xoff, yoff;
 
371
    
 
372
    fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
 
373
    first = bits - stride;
 
374
    last = bits + stride * pDrawable->height;
 
375
    fbSetBits (first, stride, FB_HEAD_BITS);
 
376
    fbSetBits (last, stride, FB_TAIL_BITS);
 
377
}
 
378
#endif /* FB_DEBUG */