Skip to content

Commit

Permalink
Some asserts and one memory error. (indilib#1161)
Browse files Browse the repository at this point in the history
  • Loading branch information
lboclboc authored Jun 5, 2020
1 parent 87e9b55 commit 9f37544
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 71 deletions.
14 changes: 14 additions & 0 deletions base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@
* out size should be at least 4*inlen/3 + 4.
* return length of out (sans trailing NUL).
*/
int to64frombits_s(unsigned char *out, const unsigned char *in, int inlen, size_t outlen)
{
size_t dlen = (((size_t)inlen + 2) / 3) * 4; /* 4/3, rounded up */

if (dlen > outlen) {
return 0;
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return to64frombits(out, in, inlen);
#pragma GCC diagnostic pop
}

int to64frombits(unsigned char *out, const unsigned char *in, int inlen)
{
uint16_t *b64lut = (uint16_t *)base64lut;
Expand Down
7 changes: 7 additions & 0 deletions base64.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 - 1301 USA

#pragma once

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -39,6 +41,11 @@ extern "C" {
\param inlen number of bytes to convert
\return 0 on success, -1 on failure.
*/
extern int to64frombits_s(unsigned char *out, const unsigned char *in, int inlen, size_t outlen);

#if defined(__GNUC__)
__attribute__((deprecated("unsafe function, use to64frombits_s instead")))
#endif
extern int to64frombits(unsigned char *out, const unsigned char *in, int inlen);

/** \brief Convert base64 to bytes array.
Expand Down
8 changes: 8 additions & 0 deletions indiapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 - 1301 USA

#pragma once

#include <stdio.h>

/** \mainpage Instrument Neutral Distributed Interface INDI
*
\section Introduction
Expand Down Expand Up @@ -495,3 +497,9 @@ typedef struct _IBLOBVectorProperty /* BLOB vector property descriptor */
* with actual array, not pointer.
*/
#define NARRAY(a) (sizeof(a) / sizeof(a[0]))

/**
* @brief Bails out if memory pointer is 0. Prints file and function.
*/
#define assert_mem(p) if((p) == 0) { fprintf(stderr, "%s(%s): Failed to allocate memory\n", __FILE__, __func__); exit(1); }
93 changes: 48 additions & 45 deletions indidriver.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ int isPropDefined(const char *property_name, const char *device_name)
/* N.B. You must free the returned buffer after use! */
char *escapeXML(const char *s, unsigned int MAX_BUF_SIZE)
{
char *buf = malloc(sizeof(char) * MAX_BUF_SIZE);
char *out = buf;
char *buf = malloc(sizeof(char) * MAX_BUF_SIZE);
assert_mem(buf);
char *out = buf;
unsigned int i = 0;

for (i = 0; i <= strlen(s); i++)
Expand Down Expand Up @@ -848,7 +849,7 @@ int IUSnoopBLOB(XMLEle *root, IBLOBVectorProperty *bvp)
if (fa && sa && ec)
{
int enclen = atoi(valuXMLAtt(ec));
bp->blob = realloc(bp->blob, 3 * enclen / 4);
assert_mem(bp->blob = realloc(bp->blob, 3 * enclen / 4));
bp->bloblen = from64tobits_fast(bp->blob, pcdataXMLEle(ep), enclen);
strncpy(bp->format, valuXMLAtt(fa), MAXINDIFORMAT);
bp->size = atoi(valuXMLAtt(sa));
Expand Down Expand Up @@ -1026,8 +1027,8 @@ int dispatch(XMLEle *root, char msg[])
/* seed for reallocs */
if (!doubles)
{
doubles = (double *)malloc(1);
names = (char **)malloc(1);
assert_mem(doubles = (double *)malloc(sizeof *doubles));
assert_mem(names = (char **)malloc(sizeof *names));
}

// Set locale to C and save previous value
Expand All @@ -1044,10 +1045,9 @@ int dispatch(XMLEle *root, char msg[])
if (n >= maxn)
{
/* grow for this and another */
int newsz = (maxn = n + 1) * sizeof(double);
doubles = (double *)realloc(doubles, newsz);
newsz = maxn * sizeof(char *);
names = (char **)realloc(names, newsz);
maxn = n + 1;
assert_mem(doubles = (double *)realloc(doubles, maxn * sizeof *doubles));
assert_mem(names = (char **)realloc(names, maxn * sizeof *names));
}
if (f_scansexa(pcdataXMLEle(ep), &doubles[n]) < 0)
IDMessage(dev, "[ERROR] %s: Bad format %s", name, pcdataXMLEle(ep));
Expand Down Expand Up @@ -1078,8 +1078,8 @@ int dispatch(XMLEle *root, char msg[])
/* seed for reallocs */
if (!states)
{
states = (ISState *)malloc(1);
names = (char **)malloc(1);
assert_mem(states = (ISState *)malloc(sizeof *states));
assert_mem(names = (char **)malloc(sizeof *names));
}

/* pull out each name/state pair */
Expand All @@ -1092,10 +1092,9 @@ int dispatch(XMLEle *root, char msg[])
{
if (n >= maxn)
{
int newsz = (maxn = n + 1) * sizeof(ISState);
states = (ISState *)realloc(states, newsz);
newsz = maxn * sizeof(char *);
names = (char **)realloc(names, newsz);
maxn = n + 1;
assert_mem(states = (ISState *)realloc(states, maxn * sizeof *states));
assert_mem(names = (char **)realloc(names, maxn * sizeof *names));
}
if (strncmp(pcdataXMLEle(ep), "On", 2) == 0)
{
Expand Down Expand Up @@ -1132,8 +1131,8 @@ int dispatch(XMLEle *root, char msg[])
/* seed for reallocs */
if (!texts)
{
texts = (char **)malloc(1);
names = (char **)malloc(1);
assert_mem(texts = (char **)malloc(sizeof *texts));
assert_mem(names = (char **)malloc(sizeof *names));
}

/* pull out each name/text pair */
Expand All @@ -1146,9 +1145,9 @@ int dispatch(XMLEle *root, char msg[])
{
if (n >= maxn)
{
int newsz = (maxn = n + 1) * sizeof(char *);
texts = (char **)realloc(texts, newsz);
names = (char **)realloc(names, newsz);
maxn = n + 1;
assert_mem(texts = (char **)realloc(texts, maxn * sizeof *texts));
assert_mem(names = (char **)realloc(names, maxn * sizeof *names));
}
texts[n] = pcdataXMLEle(ep);
names[n] = valuXMLAtt(na);
Expand Down Expand Up @@ -1178,11 +1177,11 @@ int dispatch(XMLEle *root, char msg[])
/* seed for reallocs */
if (!blobs)
{
blobs = (char **)malloc(1);
names = (char **)malloc(1);
formats = (char **)malloc(1);
blobsizes = (int *)malloc(1);
sizes = (int *)malloc(1);
assert_mem(blobs = (char **)malloc(sizeof *blobs));
assert_mem(names = (char **)malloc(sizeof *names));
assert_mem(formats = (char **)malloc(sizeof *formats));
assert_mem(blobsizes = (int *)malloc(sizeof *blobsizes));
assert_mem(sizes = (int *)malloc(sizeof *sizes));
}

/* pull out each name/BLOB pair, decode */
Expand All @@ -1198,19 +1197,18 @@ int dispatch(XMLEle *root, char msg[])
{
if (n >= maxn)
{
int newsz = (maxn = n + 1) * sizeof(char *);
blobs = (char **)realloc(blobs, newsz);
names = (char **)realloc(names, newsz);
formats = (char **)realloc(formats, newsz);
newsz = maxn * sizeof(int);
sizes = (int *)realloc(sizes, newsz);
blobsizes = (int *)realloc(blobsizes, newsz);
maxn = n + 1;
assert_mem(blobs = (char **)realloc(blobs, maxn * sizeof *blobs));
assert_mem(names = (char **)realloc(names, maxn * sizeof *names));
assert_mem(formats = (char **)realloc(formats, maxn * sizeof *formats));
assert_mem(sizes = (int *)realloc(sizes, maxn * sizeof *sizes));
assert_mem(blobsizes = (int *)realloc(blobsizes, maxn * sizeof *blobsizes));
}
int bloblen = pcdatalenXMLEle(ep);
// enclen is optional and not required by INDI protocol
if (el)
bloblen = atoi(valuXMLAtt(el));
blobs[n] = malloc(3 * bloblen / 4);
assert_mem(blobs[n] = malloc(3 * bloblen / 4));
blobsizes[n] = from64tobits_fast(blobs[n], pcdataXMLEle(ep), bloblen);
names[n] = valuXMLAtt(na);
formats[n] = valuXMLAtt(fa);
Expand Down Expand Up @@ -1772,8 +1770,12 @@ void IUSaveConfigBLOB(FILE *fp, const IBLOBVectorProperty *bvp)
fprintf(fp, " size='%d'\n", bp->size);
fprintf(fp, " format='%s'>\n", bp->format);

encblob = malloc(4 * bp->bloblen / 3 + 4);
l = to64frombits(encblob, bp->blob, bp->bloblen);
assert_mem(encblob = malloc(4 * bp->bloblen / 3 + 4));
l = to64frombits_s(encblob, bp->blob, bp->bloblen, bp->bloblen);
if (l == 0) {
fprintf(stderr, "%s(%s): Not enough memory for decoding.\n", me, __func__);
exit(1);
}
size_t written = 0;

while ((int)written < l)
Expand Down Expand Up @@ -1841,8 +1843,7 @@ void IDDefText(const ITextVectorProperty *tvp, const char *fmt, ...)
if (isPropDefined(tvp->name, tvp->device) < 0)
{
/* Add this property to insure proper sanity check */
propCache =
propCache ? (ROSC *)realloc(propCache, sizeof(ROSC) * (nPropCache + 1)) : (ROSC *)malloc(sizeof(ROSC));
assert_mem(propCache = (ROSC *)(propCache ? realloc(propCache, (nPropCache + 1) * sizeof *propCache) : malloc(sizeof *propCache)));
SC = &propCache[nPropCache++];

strcpy(SC->propName, tvp->name);
Expand Down Expand Up @@ -1913,8 +1914,7 @@ void IDDefNumber(const INumberVectorProperty *n, const char *fmt, ...)
if (isPropDefined(n->name, n->device) < 0)
{
/* Add this property to insure proper sanity check */
propCache =
propCache ? (ROSC *)realloc(propCache, sizeof(ROSC) * (nPropCache + 1)) : (ROSC *)malloc(sizeof(ROSC));
assert_mem(propCache = (ROSC *) (propCache ? realloc(propCache, (nPropCache + 1) * sizeof *propCache) : malloc(sizeof *propCache)));
SC = &propCache[nPropCache++];

strcpy(SC->propName, n->name);
Expand Down Expand Up @@ -1980,8 +1980,7 @@ void IDDefSwitch(const ISwitchVectorProperty *s, const char *fmt, ...)
if (isPropDefined(s->name, s->device) < 0)
{
/* Add this property to insure proper sanity check */
propCache =
propCache ? (ROSC *)realloc(propCache, sizeof(ROSC) * (nPropCache + 1)) : (ROSC *)malloc(sizeof(ROSC));
assert_mem(propCache = (ROSC *) (propCache ? realloc(propCache, (nPropCache + 1) * sizeof *propCache) : malloc(sizeof *propCache)));
SC = &propCache[nPropCache++];

strcpy(SC->propName, s->name);
Expand Down Expand Up @@ -2089,8 +2088,7 @@ void IDDefBLOB(const IBLOBVectorProperty *b, const char *fmt, ...)
if (isPropDefined(b->name, b->device) < 0)
{
/* Add this property to insure proper sanity check */
propCache =
propCache ? (ROSC *)realloc(propCache, sizeof(ROSC) * (nPropCache + 1)) : (ROSC *)malloc(sizeof(ROSC));
assert_mem(propCache = (ROSC *)(propCache ? realloc(propCache, (nPropCache + 1) * sizeof *propCache) : malloc(sizeof *propCache)));
SC = &propCache[nPropCache++];

strcpy(SC->propName, b->name);
Expand Down Expand Up @@ -2315,8 +2313,13 @@ void IDSetBLOB(const IBLOBVectorProperty *bvp, const char *fmt, ...)
}
else
{
encblob = malloc(4 * bp->bloblen / 3 + 4);
l = to64frombits(encblob, bp->blob, bp->bloblen);
size_t sz = 4 * bp->bloblen / 3 + 4;
assert_mem(encblob = malloc(sz));
l = to64frombits_s(encblob, bp->blob, bp->bloblen, sz);
if (l == 0) {
fprintf(stderr, "%s(%s): Not enough memory for decoding.\n", me, __func__);
exit(1);
}
printf(" enclen='%d'\n", l);
printf(" format='%s'>\n", bp->format);
size_t written = 0;
Expand Down
21 changes: 17 additions & 4 deletions libs/indibase/baseclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <stdarg.h>
#include <cstring>
#include <algorithm>
#include <assert.h>

#ifdef _WINDOWS
#include <WinSock2.h>
Expand Down Expand Up @@ -934,8 +935,14 @@ void INDI::BaseClient::sendOneBlob(IBLOB *bp)
{
char nl = '\n';
int rc = 0;
uint8_t *encblob = static_cast<uint8_t*>(malloc(4 * bp->size / 3 + 4));
uint32_t base64Len = to64frombits(encblob, reinterpret_cast<const uint8_t *>(bp->blob), bp->size);
size_t sz = 4 * bp->size / 3 + 4;
uint8_t *encblob = static_cast<uint8_t*>(malloc(sz));
assert_mem(encblob);
uint32_t base64Len = to64frombits_s(encblob, reinterpret_cast<const uint8_t *>(bp->blob), bp->size, sz);
if (base64Len == 0) {
fprintf(stderr, "%s(%s): Not enough memory for decoding.\n", __FILE__, __func__);
exit(1);
}

sendString(" <oneBLOB\n");
sendString(" name='%s'\n", bp->name);
Expand Down Expand Up @@ -981,8 +988,14 @@ void INDI::BaseClient::sendOneBlob(const char *blobName, unsigned int blobSize,
{
char nl = '\n';
int rc = 0;
uint8_t *encblob = static_cast<uint8_t*>(malloc(4 * blobSize / 3 + 4));
uint32_t base64Len = to64frombits(encblob, reinterpret_cast<const uint8_t *>(blobBuffer), blobSize);
size_t sz = 4 * blobSize / 3 + 4;
uint8_t *encblob = static_cast<uint8_t*>(malloc(sz));
assert_mem(encblob);
uint32_t base64Len = to64frombits_s(encblob, reinterpret_cast<const uint8_t *>(blobBuffer), blobSize, sz);
if (base64Len == 0) {
fprintf(stderr, "%s(%s): Not enough memory for decoding.\n", __FILE__, __func__);
exit(1);
}

sendString(" <oneBLOB\n");
sendString(" name='%s'\n", blobName);
Expand Down
20 changes: 16 additions & 4 deletions libs/indibase/baseclientqt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <algorithm>

#include <cstdlib>
#include <assert.h>

#define MAXINDIBUF 49152

Expand Down Expand Up @@ -670,8 +671,13 @@ void INDI::BaseClientQt::sendOneBlob(IBLOB *bp)
unsigned char *encblob;
int l;

encblob = static_cast<unsigned char *>(malloc(4 * bp->size / 3 + 4));
l = to64frombits(encblob, reinterpret_cast<const unsigned char *>(bp->blob), bp->size);
size_t sz = 4 * bp->size / 3 + 4;
assert_mem(encblob = static_cast<unsigned char *>(malloc(sz));)
l = to64frombits_s(encblob, reinterpret_cast<const unsigned char *>(bp->blob), bp->size, sz);
if (l == 0) {
fprintf(stderr, "%s(%s): Not enough memory for decoding.\n", __FILE__, __func__);
exit(1);
}

prop += QString(" <oneBLOB\n");
prop += QString(" name='%1'\n").arg(bp->name);
Expand Down Expand Up @@ -708,8 +714,14 @@ void INDI::BaseClientQt::sendOneBlob(const char *blobName, unsigned int blobSize
unsigned char *encblob;
int l;

encblob = static_cast<unsigned char *>(malloc(4 * blobSize / 3 + 4));
l = to64frombits(encblob, reinterpret_cast<const unsigned char *>(blobBuffer), blobSize);
size_t sz = 4 * blobSize / 3 + 4;
assert_mem(encblob = static_cast<unsigned char *>(malloc(sz)));
l = to64frombits_s(encblob, reinterpret_cast<const unsigned char *>(blobBuffer), blobSize, sz);
if (l == 0) {
fprintf(stderr, "%s(%s): Not enough memory for decoding.\n", __FILE__, __func__);
exit(1);
}


QString prop;

Expand Down
Loading

0 comments on commit 9f37544

Please sign in to comment.