Fix several input validation errors in libX11 and libXpm. CVE-2023-43785 CVE-2023-43786 CVE-2023-43787 CVE-2023-43788 CVE-2023-43789
This commit is contained in:
parent
21df3bcb54
commit
e1ec829e63
11 changed files with 153 additions and 40 deletions
|
@ -28,6 +28,7 @@ in this Software without prior written authorization from The Open Group.
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
#include "Xlibint.h"
|
#include "Xlibint.h"
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifdef USE_DYNAMIC_XCURSOR
|
#ifdef USE_DYNAMIC_XCURSOR
|
||||||
void
|
void
|
||||||
|
@ -47,6 +48,16 @@ Pixmap XCreatePixmap (
|
||||||
Pixmap pid;
|
Pixmap pid;
|
||||||
register xCreatePixmapReq *req;
|
register xCreatePixmapReq *req;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force a BadValue X Error if the requested dimensions are larger
|
||||||
|
* than the X11 protocol has room for, since that's how callers expect
|
||||||
|
* to get notified of errors.
|
||||||
|
*/
|
||||||
|
if (width > USHRT_MAX)
|
||||||
|
width = 0;
|
||||||
|
if (height > USHRT_MAX)
|
||||||
|
height = 0;
|
||||||
|
|
||||||
LockDisplay(dpy);
|
LockDisplay(dpy);
|
||||||
GetReq(CreatePixmap, req);
|
GetReq(CreatePixmap, req);
|
||||||
req->drawable = d;
|
req->drawable = d;
|
||||||
|
|
|
@ -30,6 +30,7 @@ in this Software without prior written authorization from The Open Group.
|
||||||
#include <X11/Xlibint.h>
|
#include <X11/Xlibint.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "ImUtil.h"
|
#include "ImUtil.h"
|
||||||
|
|
||||||
static int _XDestroyImage(XImage *);
|
static int _XDestroyImage(XImage *);
|
||||||
|
@ -361,11 +362,20 @@ XImage *XCreateImage (
|
||||||
/*
|
/*
|
||||||
* compute per line accelerator.
|
* compute per line accelerator.
|
||||||
*/
|
*/
|
||||||
{
|
if (format == ZPixmap) {
|
||||||
if (format == ZPixmap)
|
if ((INT_MAX / bits_per_pixel) < width) {
|
||||||
|
Xfree(image);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
min_bytes_per_line =
|
min_bytes_per_line =
|
||||||
ROUNDUP((bits_per_pixel * width), image->bitmap_pad);
|
ROUNDUP((bits_per_pixel * width), image->bitmap_pad);
|
||||||
else
|
} else {
|
||||||
|
if ((INT_MAX - offset) < width) {
|
||||||
|
Xfree(image);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
min_bytes_per_line =
|
min_bytes_per_line =
|
||||||
ROUNDUP((width + offset), image->bitmap_pad);
|
ROUNDUP((width + offset), image->bitmap_pad);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ in this Software without prior written authorization from The Open Group.
|
||||||
#include "Xlibint.h"
|
#include "Xlibint.h"
|
||||||
#include "Xutil.h"
|
#include "Xutil.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "Cr.h"
|
#include "Cr.h"
|
||||||
#include "ImUtil.h"
|
#include "ImUtil.h"
|
||||||
#include "reallocarray.h"
|
#include "reallocarray.h"
|
||||||
|
@ -914,8 +915,9 @@ PutSubImage (
|
||||||
req_width, req_height - SubImageHeight,
|
req_width, req_height - SubImageHeight,
|
||||||
dest_bits_per_pixel, dest_scanline_pad);
|
dest_bits_per_pixel, dest_scanline_pad);
|
||||||
} else {
|
} else {
|
||||||
int SubImageWidth = (((Available << 3) / dest_scanline_pad)
|
int SubImageWidth = ((((Available << 3) / dest_scanline_pad)
|
||||||
* dest_scanline_pad) - left_pad;
|
* dest_scanline_pad) - left_pad)
|
||||||
|
/ dest_bits_per_pixel;
|
||||||
|
|
||||||
PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y,
|
PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y,
|
||||||
(unsigned int) SubImageWidth, 1,
|
(unsigned int) SubImageWidth, 1,
|
||||||
|
@ -961,6 +963,10 @@ XPutImage (
|
||||||
height = image->height - req_yoffset;
|
height = image->height - req_yoffset;
|
||||||
if ((width <= 0) || (height <= 0))
|
if ((width <= 0) || (height <= 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (width > USHRT_MAX)
|
||||||
|
width = USHRT_MAX;
|
||||||
|
if (height > USHRT_MAX)
|
||||||
|
height = USHRT_MAX;
|
||||||
|
|
||||||
if ((image->bits_per_pixel == 1) || (image->format != ZPixmap)) {
|
if ((image->bits_per_pixel == 1) || (image->format != ZPixmap)) {
|
||||||
dest_bits_per_pixel = 1;
|
dest_bits_per_pixel = 1;
|
||||||
|
|
|
@ -182,7 +182,8 @@ _XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
|
||||||
if (offset + newMap->nSyms >= map->size_syms) {
|
if (offset + newMap->nSyms >= map->size_syms) {
|
||||||
register int sz;
|
register int sz;
|
||||||
|
|
||||||
sz = map->size_syms + 128;
|
sz = offset + newMap->nSyms;
|
||||||
|
sz = ((sz + (unsigned) 128) / 128) * 128;
|
||||||
_XkbResizeArray(map->syms, map->size_syms, sz, KeySym);
|
_XkbResizeArray(map->syms, map->size_syms, sz, KeySym);
|
||||||
if (map->syms == NULL) {
|
if (map->syms == NULL) {
|
||||||
map->size_syms = 0;
|
map->size_syms = 0;
|
||||||
|
@ -191,8 +192,9 @@ _XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
|
||||||
map->size_syms = sz;
|
map->size_syms = sz;
|
||||||
}
|
}
|
||||||
if (newMap->nSyms > 0) {
|
if (newMap->nSyms > 0) {
|
||||||
_XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset],
|
if (_XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset],
|
||||||
newMap->nSyms);
|
newMap->nSyms) == 0)
|
||||||
|
return BadLength;
|
||||||
offset += newMap->nSyms;
|
offset += newMap->nSyms;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -222,8 +224,10 @@ _XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep)
|
||||||
newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp);
|
newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp);
|
||||||
if (newSyms == NULL)
|
if (newSyms == NULL)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
if (newMap->nSyms > 0)
|
if (newMap->nSyms > 0) {
|
||||||
_XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms);
|
if (_XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms) == 0)
|
||||||
|
return BadLength;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
newSyms[0] = NoSymbol;
|
newSyms[0] = NoSymbol;
|
||||||
oldMap->kt_index[0] = newMap->ktIndex[0];
|
oldMap->kt_index[0] = newMap->ktIndex[0];
|
||||||
|
|
|
@ -46,7 +46,7 @@ XpmCreatePixmapFromBuffer(
|
||||||
Pixmap *shapemask_return,
|
Pixmap *shapemask_return,
|
||||||
XpmAttributes *attributes)
|
XpmAttributes *attributes)
|
||||||
{
|
{
|
||||||
XImage *ximage, *shapeimage;
|
XImage *ximage = NULL, *shapeimage = NULL;
|
||||||
int ErrorStatus;
|
int ErrorStatus;
|
||||||
|
|
||||||
/* initialize return values */
|
/* initialize return values */
|
||||||
|
@ -63,16 +63,34 @@ XpmCreatePixmapFromBuffer(
|
||||||
attributes);
|
attributes);
|
||||||
|
|
||||||
if (ErrorStatus < 0) /* fatal error */
|
if (ErrorStatus < 0) /* fatal error */
|
||||||
return (ErrorStatus);
|
goto cleanup;
|
||||||
|
|
||||||
/* create the pixmaps and destroy images */
|
/* create the pixmaps and destroy images */
|
||||||
if (pixmap_return && ximage) {
|
if (pixmap_return && ximage) {
|
||||||
|
ErrorStatus =
|
||||||
xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
||||||
XDestroyImage(ximage);
|
if (ErrorStatus < 0) /* fatal error */
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (shapemask_return && shapeimage) {
|
if (shapemask_return && shapeimage) {
|
||||||
|
ErrorStatus =
|
||||||
xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ximage != NULL)
|
||||||
|
XDestroyImage(ximage);
|
||||||
|
if (shapeimage != NULL)
|
||||||
XDestroyImage(shapeimage);
|
XDestroyImage(shapeimage);
|
||||||
|
if (ErrorStatus < 0) {
|
||||||
|
if (pixmap_return && *pixmap_return) {
|
||||||
|
XFreePixmap(display, *pixmap_return);
|
||||||
|
*pixmap_return = 0;
|
||||||
|
}
|
||||||
|
if (shapemask_return && *shapemask_return) {
|
||||||
|
XFreePixmap(display, *shapemask_return);
|
||||||
|
*shapemask_return = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (ErrorStatus);
|
return (ErrorStatus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ XpmCreatePixmapFromData(
|
||||||
Pixmap *shapemask_return,
|
Pixmap *shapemask_return,
|
||||||
XpmAttributes *attributes)
|
XpmAttributes *attributes)
|
||||||
{
|
{
|
||||||
XImage *ximage, *shapeimage;
|
XImage *ximage = NULL, *shapeimage = NULL;
|
||||||
int ErrorStatus;
|
int ErrorStatus;
|
||||||
|
|
||||||
/* initialize return values */
|
/* initialize return values */
|
||||||
|
@ -63,19 +63,34 @@ XpmCreatePixmapFromData(
|
||||||
attributes);
|
attributes);
|
||||||
|
|
||||||
if (ErrorStatus != XpmSuccess)
|
if (ErrorStatus != XpmSuccess)
|
||||||
return (ErrorStatus);
|
goto cleanup;
|
||||||
|
|
||||||
if (ErrorStatus < 0) /* fatal error */
|
|
||||||
return (ErrorStatus);
|
|
||||||
|
|
||||||
/* create the pixmaps and destroy images */
|
/* create the pixmaps and destroy images */
|
||||||
if (pixmap_return && ximage) {
|
if (pixmap_return && ximage) {
|
||||||
|
ErrorStatus =
|
||||||
xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
||||||
XDestroyImage(ximage);
|
if (ErrorStatus < 0) /* fatal error */
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (shapemask_return && shapeimage) {
|
if (shapemask_return && shapeimage) {
|
||||||
|
ErrorStatus =
|
||||||
xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ximage != NULL)
|
||||||
|
XDestroyImage(ximage);
|
||||||
|
if (shapeimage != NULL)
|
||||||
XDestroyImage(shapeimage);
|
XDestroyImage(shapeimage);
|
||||||
|
if (ErrorStatus < 0) {
|
||||||
|
if (pixmap_return && *pixmap_return) {
|
||||||
|
XFreePixmap(display, *pixmap_return);
|
||||||
|
*pixmap_return = 0;
|
||||||
|
}
|
||||||
|
if (shapemask_return && *shapemask_return) {
|
||||||
|
XFreePixmap(display, *shapemask_return);
|
||||||
|
*shapemask_return = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (ErrorStatus);
|
return (ErrorStatus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,9 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
#include "XpmI.h"
|
#include "XpmI.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
void
|
int
|
||||||
xpmCreatePixmapFromImage(
|
xpmCreatePixmapFromImage(
|
||||||
Display *display,
|
Display *display,
|
||||||
Drawable d,
|
Drawable d,
|
||||||
|
@ -47,6 +48,11 @@ xpmCreatePixmapFromImage(
|
||||||
GC gc;
|
GC gc;
|
||||||
XGCValues values;
|
XGCValues values;
|
||||||
|
|
||||||
|
/* X Pixmaps are limited to unsigned 16-bit height/width */
|
||||||
|
if ((ximage->width > UINT16_MAX) || (ximage->height > UINT16_MAX)) {
|
||||||
|
return XpmNoMemory;
|
||||||
|
}
|
||||||
|
|
||||||
*pixmap_return = XCreatePixmap(display, d, ximage->width,
|
*pixmap_return = XCreatePixmap(display, d, ximage->width,
|
||||||
ximage->height, ximage->depth);
|
ximage->height, ximage->depth);
|
||||||
/* set fg and bg in case we have an XYBitmap */
|
/* set fg and bg in case we have an XYBitmap */
|
||||||
|
@ -59,4 +65,6 @@ xpmCreatePixmapFromImage(
|
||||||
ximage->width, ximage->height);
|
ximage->width, ximage->height);
|
||||||
|
|
||||||
XFreeGC(display, gc);
|
XFreeGC(display, gc);
|
||||||
|
|
||||||
|
return XpmSuccess;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ XpmReadFileToPixmap(
|
||||||
Pixmap *shapemask_return,
|
Pixmap *shapemask_return,
|
||||||
XpmAttributes *attributes)
|
XpmAttributes *attributes)
|
||||||
{
|
{
|
||||||
XImage *ximage, *shapeimage;
|
XImage *ximage = NULL, *shapeimage = NULL;
|
||||||
int ErrorStatus;
|
int ErrorStatus;
|
||||||
|
|
||||||
/* initialize return values */
|
/* initialize return values */
|
||||||
|
@ -62,16 +62,34 @@ XpmReadFileToPixmap(
|
||||||
attributes);
|
attributes);
|
||||||
|
|
||||||
if (ErrorStatus < 0) /* fatal error */
|
if (ErrorStatus < 0) /* fatal error */
|
||||||
return (ErrorStatus);
|
goto cleanup;
|
||||||
|
|
||||||
/* create the pixmaps and destroy images */
|
/* create the pixmaps and destroy images */
|
||||||
if (pixmap_return && ximage) {
|
if (pixmap_return && ximage) {
|
||||||
|
ErrorStatus =
|
||||||
xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
||||||
XDestroyImage(ximage);
|
if (ErrorStatus < 0) /* fatal error */
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (shapemask_return && shapeimage) {
|
if (shapemask_return && shapeimage) {
|
||||||
|
ErrorStatus =
|
||||||
xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ximage != NULL)
|
||||||
|
XDestroyImage(ximage);
|
||||||
|
if (shapeimage != NULL)
|
||||||
XDestroyImage(shapeimage);
|
XDestroyImage(shapeimage);
|
||||||
|
if (ErrorStatus < 0) {
|
||||||
|
if (pixmap_return && *pixmap_return) {
|
||||||
|
XFreePixmap(display, *pixmap_return);
|
||||||
|
*pixmap_return = 0;
|
||||||
|
}
|
||||||
|
if (shapemask_return && *shapemask_return) {
|
||||||
|
XFreePixmap(display, *shapemask_return);
|
||||||
|
*shapemask_return = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (ErrorStatus);
|
return (ErrorStatus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ FUNC(xpmSetAttributes, void, (XpmAttributes *attributes, XpmImage *image,
|
||||||
XpmInfo *info));
|
XpmInfo *info));
|
||||||
|
|
||||||
#if !defined(FOR_MSW) && !defined(AMIGA)
|
#if !defined(FOR_MSW) && !defined(AMIGA)
|
||||||
FUNC(xpmCreatePixmapFromImage, void, (Display *display, Drawable d,
|
FUNC(xpmCreatePixmapFromImage, int, (Display *display, Drawable d,
|
||||||
XImage *ximage, Pixmap *pixmap_return));
|
XImage *ximage, Pixmap *pixmap_return));
|
||||||
|
|
||||||
FUNC(xpmCreateImageFromPixmap, void, (Display *display, Pixmap pixmap,
|
FUNC(xpmCreateImageFromPixmap, void, (Display *display, Pixmap pixmap,
|
||||||
|
|
|
@ -997,6 +997,11 @@ CreateXImage(
|
||||||
*image_return = NULL;
|
*image_return = NULL;
|
||||||
return XpmNoMemory;
|
return XpmNoMemory;
|
||||||
}
|
}
|
||||||
|
if (width != 0 && (*image_return)->bits_per_pixel >= INT_MAX / width) {
|
||||||
|
XDestroyImage(*image_return);
|
||||||
|
*image_return = NULL;
|
||||||
|
return XpmNoMemory;
|
||||||
|
}
|
||||||
/* now that bytes_per_line must have been set properly alloc data */
|
/* now that bytes_per_line must have been set properly alloc data */
|
||||||
if((*image_return)->bytes_per_line == 0 || height == 0) {
|
if((*image_return)->bytes_per_line == 0 || height == 0) {
|
||||||
XDestroyImage(*image_return);
|
XDestroyImage(*image_return);
|
||||||
|
@ -1652,7 +1657,7 @@ XpmCreatePixmapFromXpmImage(
|
||||||
Pixmap *shapemask_return,
|
Pixmap *shapemask_return,
|
||||||
XpmAttributes *attributes)
|
XpmAttributes *attributes)
|
||||||
{
|
{
|
||||||
XImage *ximage, *shapeimage;
|
XImage *ximage = NULL, *shapeimage = NULL;
|
||||||
int ErrorStatus;
|
int ErrorStatus;
|
||||||
|
|
||||||
/* initialize return values */
|
/* initialize return values */
|
||||||
|
@ -1668,16 +1673,34 @@ XpmCreatePixmapFromXpmImage(
|
||||||
&shapeimage : NULL),
|
&shapeimage : NULL),
|
||||||
attributes);
|
attributes);
|
||||||
if (ErrorStatus < 0)
|
if (ErrorStatus < 0)
|
||||||
return (ErrorStatus);
|
goto cleanup;
|
||||||
|
|
||||||
/* create the pixmaps and destroy images */
|
/* create the pixmaps and destroy images */
|
||||||
if (pixmap_return && ximage) {
|
if (pixmap_return && ximage) {
|
||||||
|
ErrorStatus =
|
||||||
xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
||||||
XDestroyImage(ximage);
|
if (ErrorStatus < 0) /* fatal error */
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (shapemask_return && shapeimage) {
|
if (shapemask_return && shapeimage) {
|
||||||
|
ErrorStatus =
|
||||||
xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ximage != NULL)
|
||||||
|
XDestroyImage(ximage);
|
||||||
|
if (shapeimage != NULL)
|
||||||
XDestroyImage(shapeimage);
|
XDestroyImage(shapeimage);
|
||||||
|
if (ErrorStatus < 0) {
|
||||||
|
if (pixmap_return && *pixmap_return) {
|
||||||
|
XFreePixmap(display, *pixmap_return);
|
||||||
|
*pixmap_return = 0;
|
||||||
|
}
|
||||||
|
if (shapemask_return && *shapemask_return) {
|
||||||
|
XFreePixmap(display, *shapemask_return);
|
||||||
|
*shapemask_return = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (ErrorStatus);
|
return (ErrorStatus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ ParseComment(xpmData *data)
|
||||||
n++;
|
n++;
|
||||||
s2++;
|
s2++;
|
||||||
} while (c == *s2 && *s2 != '\0' && c);
|
} while (c == *s2 && *s2 != '\0' && c);
|
||||||
if (*s2 == '\0') {
|
if (*s2 == '\0' || c == '\0') {
|
||||||
/* this is the end of the comment */
|
/* this is the end of the comment */
|
||||||
notend = 0;
|
notend = 0;
|
||||||
data->cptr--;
|
data->cptr--;
|
||||||
|
@ -259,13 +259,13 @@ xpmNextWord(
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (!data->type || data->type == XPMBUFFER) {
|
if (!data->type || data->type == XPMBUFFER) {
|
||||||
while (isspace(c = *data->cptr) && c != data->Eos)
|
while ((c = *data->cptr) && isspace(c) && (c != data->Eos))
|
||||||
data->cptr++;
|
data->cptr++;
|
||||||
do {
|
do {
|
||||||
c = *data->cptr++;
|
c = *data->cptr++;
|
||||||
*buf++ = c;
|
*buf++ = c;
|
||||||
n++;
|
n++;
|
||||||
} while (!isspace(c) && c != data->Eos && n < buflen);
|
} while (c && !isspace(c) && (c != data->Eos) && (n < buflen));
|
||||||
n--;
|
n--;
|
||||||
data->cptr--;
|
data->cptr--;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue