/*
* Solaris X consolidation configuration for Parfait static analysis
* This file provides additional information about functions that Parfait
* can use to make more accurate analysis.
*/
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
include 'std.conf';
/* Local copy until added to parfait's std.conf (Bug 14121100) */
asprintf(p,const fmt,args...) : printf(fmt,args), noescape {
if (result >= 0) {
*p == new(result);
}
}
vasprintf(p,const fmt,va) : noescape {
if (result >= 0) {
*p == new(result);
}
}
/* Local copy until added to parfait's std.conf (Bug 14121213) */
strndup(const s, n) : noescape {
if ( result != 0 ) {
result == new(undefined);
strlen(result) == PRE ( strlen(s) < n ? strlen(s) : n);
}
}
/* Define custom bug types for common precondition assertions */
bugtype "null-pointer-deref-call-X"(ptr) : "null-pointer-deref" {
name="Null Pointer Dereference in X function";
priority="error";
enabled="true";
message="Null pointer dereference in call to ", callee_name(), ". Pointer ", name(ptr), " may be dereferenced";
}
/*************************************************************************
* Client side functions
*/
/** libX11 **/
bugtype "X-resource-leak"(xid) {
name="X Resource Leak";
priority="error";
enabled="true";
message="Leaked X Resource ", name(xid);
}
resource <x-resource> {
name="X Resource";
"X-resource-leak"(resource): noleak(resource);
resource == 0 => !isa(resource);
}
/* Listed pretty much in same order as <X11/Xlib.h> */
/* Todo: XLoadQueryFont...XNewModifiermap */
XCreateImage(const display, v, dp, f, o, data, w, h, bp, bpl) {
"null-pointer-deref-call-X"(display) : display != 0;
if (result != 0) {
result == new(undefined);
}
}
XDestroyImage(p) { /* actually in <X11/Xutil.h> */
"null-pointer-deref-call-X"(p) : p != 0;
delete(p);
}
/* Todo: XInitImage, XGetImage, XGetSubImage */
XOpenDisplay(const d) {
if (result != 0) {
result == new(undefined);
}
}
XFetchBuffer(d, n, b) {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
*n == size(result);
result == new(*n);
}
}
XFetchBytes(d, n) : XFetchBuffer(d, n, 0);
XGetAtomName(d, a) {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
result == new(undefined);
}
}
/* Todo: XGetAtomNames, XGetDefault, XDisplayName, XKeysymToString,
XInternAtom, XInternAtoms */
XCopyColormapAndFree(d, c) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XCreateColormap(d, w, v, a) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XCreatePixmapCursor(d, s, m, fg, bg, x, y) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XCreateGlyphCursor(d, sf, mf, sc, mc, fg, bg) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XCreateFontCursor(d, s) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XLoadFont(d, c) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XCreateGC(d, dr, vm, v) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
result == new(112); /* sizeof(struct _XGC) */
}
}
/* Todo: XGContextFromGC, XFlushGC */
XCreatePixmap(d, dr, w, h, dp) {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XCreateBitmapFromData(d, dr, dt, w, h) {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XCreatePixmapFromBitmapData(d, dr, dt, w, h, fg, bg, dp) {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
XCreateSimpleWindow(d,p,x,y,w,h,bw,b,bg) {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
/* Todo: XGetSelectionOwner */
XCreateWindow(d,p,x,y,w,h,bw,dp,c,v,vm,a) {
"null-pointer-deref-call-X"(d) : d != 0;
result != 0;
init<x-resource>(result);
}
/* Todo: XListInstalledColormaps, XListFonts, XListFontsWithInfo, XGetFontPath */
XListExtensions(d, n) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
result == new(undefined); /* n * char* + extension strings */
}
}
XListProperties(d, w, n) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
result == new(n * 4);
}
}
XListHosts(d, n, s) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
result == new(undefined); /* n * char* + extension strings */
}
}
XKeycodeToKeysym(d, k, i) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
}
XLookupKeysym(e, i) : noescape {
"null-pointer-deref-call-X"(e) : e != 0;
}
XGetKeyboardMapping(d, fk, kc, ks) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
result == new(kc * ks);
}
}
XStringToKeysym(s) : noescape {
"null-pointer-deref-call-X"(s) : s != 0;
}
XMaxRequestSize(d) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
}
XExtendedMaxRequestSize(d) : XMaxRequestSize(d);
XScreenResourceString(d) : XMaxRequestSize(d);
XDisplayMotionBufferSize(d) : XMaxRequestSize(d);
XVisualIdFromVisual(v) : noescape {
/* Todo: visual resource id? */
"null-pointer-deref-call-X"(v) : v != 0;
}
XLockDisplay(d) : XMaxRequestSize(d);
XUnlockDisplay(d) : XMaxRequestSize(d);
XAddExtension(d) {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
result == new(128);
}
}
XInitExtension(d, n) : XAddExtension(d);
XFindOnExtensionList(s, n) {
"null-pointer-deref-call-X"(s) : s != 0;
}
/* these are routines for which there are also macros */
XDefaultRootWindow(d) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
}
XRootWindow(d, n) : XDefaultRootWindow(d);
XRootWindowOfScreen(s) : XDefaultRootWindow(s);
XDefaultVisual(d, n) : XDefaultRootWindow(d);
XDefaultVisualOfScreen(s) : XDefaultRootWindow(s);
XDefaultGC(d, n) : XDefaultRootWindow(d);
XDefaultGCOfScreen(s) : XDefaultRootWindow(s);
XBlackPixel(d, n) : XDefaultRootWindow(d);
XWhitePixel(d, n) : XDefaultRootWindow(d);
XBlackPixelOfScreen(s) : XDefaultRootWindow(s);
XWhitePixelOfScreen(s) : XDefaultRootWindow(s);
XNextRequest(d) : XDefaultRootWindow(d);
XLastKnownRequestProcessed(d) : XDefaultRootWindow(d);
XServerVendor(d) : XDefaultRootWindow(d);
XDisplayString(d) : XDefaultRootWindow(d);
XDefaultColormap(d, n) : noescape {
/* Todo: colormap resource id? */
"null-pointer-deref-call-X"(d) : d != 0;
}
XDefaultColormapOfScreen(s) : XDefaultColormap(s, 0);
XDisplayOfScreen(s) : XDefaultRootWindow(s);
XScreenOfDisplay(d, n) : XDefaultRootWindow(d);
XDefaultScreenOfDisplay(d) : XDefaultRootWindow(d);
XEventMaskOfScreen(s) : XDefaultRootWindow(s);
XScreenNumberOfScreen(s) : XDefaultRootWindow(s);
/* Todo: XSetErrorHandler, XSetIOErrorHandler */
XListPixmapFormats(d, c) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
"null-pointer-deref-call-X"(c) : c != 0;
if (result != 0) {
result == new(c * 12); /* sizeof(XPixmapFormatValues) */
}
}
XListDepths(d, s, c) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
"null-pointer-deref-call-X"(c) : c != 0;
if (result != 0) {
result == new(c * 4); /* sizeof(int) */
}
}
/* Todo: ICCCM routines - XReconfigureWMWindow...XSetWMColormapWindows,
XSetTransientForHint */
XFreeStringList(l) : free(l);
XActivateScreenSaver(d) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
}
XAddHost(d, h) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
"null-pointer-deref-call-X"(h) : h != 0;
}
XAddHosts(d, h, n) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
"null-pointer-deref-call-X"(h) : h != 0;
}
/* Todo: XAddToExtensionList...XClearWindow */
XCloseDisplay(d) {
"null-pointer-deref-call-X"(d) : d != 0;
delete(d);
}
/* Todo: XConfigureWindow...XDeleteProperty */
XDestroyWindow(d, w) {
"null-pointer-deref-call-X"(d) : d != 0;
destroy<x-resource>(w);
}
XDestroySubwindows(d, w) : XDestroyWindow(d, w); /* Todo: subwindows? */
/* Todo: XDoesBackingStore...XDisplayHeightMM */
XDisplayKeycodes(d, min, max) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
min >= 8;
max <= 255;
}
/* Todo: XDisplayPlanes...XEventsQueued */
XFetchName(d, w, name) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
if (name != 0) {
name == new(undefined);
}
}
/* Todo: XFillArcs...XForceScreenSaver */
XFree(p) : free(p);
XFreeColormap(d, c) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
destroy<x-resource>(c);
}
/* Todo: XFreeColors */
XFreeCursor(d, c) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
destroy<x-resource>(c);
}
XFreeExtensionList(l) : free(l);
XFreeFont(d, f) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
destroy<x-resource>(f);
}
/* Todo: XFreeFontInfo */
XFreeFontNames(l) : free(l);
XFreeFontPath(l) : free(l);
XFreeGC(d, gc) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
destroy<x-resource>(gc);
}
XFreeModifierMap(m) : free(m);
XFreePixmap(d, p) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
destroy<x-resource>(p);
}
/* Todo: XGeometry...XGetGeometry */
XGetIconName(d, w, name) : XFetchName(d, w, name);
/* Todo: XGetInputFocus...XGetTransientForHint */
XGetWindowProperty(d, w, p, lo, ll, del, rt, at, af, n, bar, prop) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
if (prop != 0) {
prop == new(undefined);
}
}
/* Todo: XGetWindowAttributes...XQueryColors */
XQueryExtension(d, n, op, ev, er) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
if (result != 0) {
op >= 128;
op <= 255;
}
}
/* Todo: XQueryKeymap...XQueryTextExtents16 */
XQueryTree(d, w, r, p, c, nc) : noescape {
"null-pointer-deref-call-X"(d) : d != 0;
"null-pointer-deref-call-X"(c) : c != 0;
if (result != 0) {
c == new(nc * 4);
}
}
/* Todo: XRaiseWindow...XRemoveFromSaveSet */
XRemoveHost(d, h) : XAddHost(d, h);
XRemoveHosts(d, h, n) : XAddHosts(d, h, n);
/* Todo: XReparentWindow...XFreeEventData */
/* Allocation functions from <X11/Xutil.h> */
XAllocClassHint() : malloc(size(result));
XAllocIconSize() : malloc(size(result));
XAllocSizeHints() : malloc(size(result));
XAllocStandardColormap() : malloc(size(result));
XAllocWMHints() : malloc(size(result));
/** libXt
* Functions from Xt's Alloc.c - like libc ones, except exit on failure,
* instead of return NULL
*/
XtAsprintf(p,const fmt,args...) : printf(fmt,args), noescape {
*p == new(result);
}
XtMalloc(s) {
result == new(s);
}
XtRealloc(p,s) {
delete(p);
result == new(s);
}
XtCalloc(n,s) {
result == new(n*s);
}
XtFree(p) : free(p);
/*************************************************************************
* Server side functions
*/
/* include/misc.h: byte swapping */
/* XXX - does not work! */
bugtype "wrong-size-swap"(ptr,funcsize) {
name="Wrong size Xserver swap function used";
priority="error";
enabled="true";
message="Wrong size swap function used: ", callee_name(), " expects ", funcsize, "-byte variable, got ", size(ptr),"-byte ", name(ptr), " instead.";
}
swap_uint32(x) : noescape {
"wrong-size-swap"(x,4): size(*x) == 4;
}
swap_uint16(x) : noescape {
"wrong-size-swap"(x,2): size(*x) == 4;
}
SwapLongs(x,count) : noescape {
"wrong-size-swap"(x,4): size(x) == 4;
}
SwapShorts(x,count) : noescape {
"wrong-size-swap"(x,2): size(x) == 4;
}
/* dix/pixmap.c */
AllocatePixmap(const pScreen, pixDataSize) : noescape {
if (result != 0) {
result == new(pixDataSize);
}
}
FreePixmap(p) : free(p);
/* dix/region.c */
RegionCreate(const rect, s) {
result == new(12); /* sizeof struct pixman_region16 */
}
RegionDestroy(p) : free(p);
/* fb/fbpixmap.c */
fbCreatePixmapBpp(const pS, w, h, d, b, ht) {
if (result != 0) {
result == new(w*h);
}
}
fbCreatePixmap(const pS, w, h, d, ht) : fbCreatePixmapBpp(pS, w, h, d, d, ht);
fbDestroyPixmap(p) : FreePixmap(p);
/* os/log.c: logging functions */
LogWrite(verb, const fmt, args...) : printf(fmt, args), noescape;
LogMessageVerb(type, verb, const fmt, args...) : printf(fmt, args), noescape;
LogMessage(type, const fmt, args...) : printf(fmt, args), noescape;
FatalError(const fmt, args...) : printf(fmt, args), noescape, exit;
ErrorF(const fmt, args...) : printf(fmt, args), noescape;
AbortServer(): exit;
/* os/utils.c: allocation & other helpers */
Xalloc(s) : malloc(s);
XNFalloc(s) {
result == new(s);
}
Xcalloc(s) : calloc(1,s);
XNFcalloc(s) : XNFalloc(s);
Xrealloc(p, s) : realloc(p, s);
XNFrealloc(p, s) : realloc(p, s);
Xfree(p) : free(p);
Xstrdup(const s) : noescape {
if ( s == 0 ) {
result == 0;
} else {
if( result != 0 ) {
result == new(strlen(s)+1);
strlen(result) == strlen(s);
}
}
}
XNFstrdup(const s) : noescape {
if ( s == 0 ) {
result == 0;
} else {
result == new(strlen(s)+1);
strlen(result) == strlen(s);
}
}
OsAbort() : abort();
Fopen(f, m) : fopen(f, m);
Fclose(p) : fclose(p);
/* os/xprintf.c: allocating printf wrappers/variants */
Xvasprintf(p, fmt, va) : vasprintf(p, fmt, va);
Xasprintf(p, fmt, args...) : asprintf(p, fmt, args);
XNFvasprintf(p, fmt, va) : noescape {
*p == new(result);
}
XNFasprintf(p, fmt, args...) : noescape, printf(fmt, args) {
*p == new(result);
}
Xvprintf(fmt, va) : noescape {
if (result != 0) {
result == new(undefined);
}
}
Xprintf(fmt, args...) : noescape, printf(fmt, args) {
if (result != 0) {
result == new(undefined);
}
}
XNFvprintf(fmt, va) : noescape {
result == new(undefined);
}
XNFprintf(fmt, args...) : noescape, printf(fmt, args) {
result == new(undefined);
}