Skip to content

Commit

Permalink
writeANSI: use strcpy instead of strncat
Browse files Browse the repository at this point in the history
strncat(3) needs to traverse through the buffer to append the string
into the end of old string. This will have a big performance penalty
when we have a very large input.

Replace it with strcpy(3) and a pointer to track the end of current
buffer.

Accidently, this change also silence gcc's -Wstringop-overflow warning,
since gcc thinks our issue to strncat(3) to stop right at the NULL
terminator maybe an error.
  • Loading branch information
sgn committed Jan 22, 2021
1 parent 4449c8f commit 6df2b74
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions qrenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,14 @@ static void writeANSI_margin(FILE* fp, size_t realwidth,
}
}

#define COPY_AND_ADVANCE_N(BUF, STR, LEN) \
do { \
strncpy(BUF, STR, LEN); \
BUF += LEN; \
} while (0)

#define COPY_AND_ADVANCE(BUF, STR) COPY_AND_ADVANCE_N(BUF, STR, strlen(STR))

static int writeANSI(const QRcode *qrcode, const char *outfile)
{
FILE *fp;
Expand All @@ -756,6 +764,7 @@ static int writeANSI(const QRcode *qrcode, const char *outfile)

const char *white, *black;
char *buffer;
char *pbuf;
size_t white_s, black_s, buffer_s;

if (image_type == ANSI256_TYPE) {
Expand Down Expand Up @@ -790,32 +799,33 @@ static int writeANSI(const QRcode *qrcode, const char *outfile)
row = p + (y * qrcode->width);

memset(buffer, 0, buffer_s);
strncpy(buffer, white, white_s);
pbuf = buffer;
COPY_AND_ADVANCE_N(pbuf, white, white_s);
for (x = 0; x < margin; x++) {
strncat(buffer, " ", 2);
COPY_AND_ADVANCE(pbuf, " ");
}
last = 0;

for (x = 0; x < qrcode->width; x++) {
if (row[x] & 0x1) {
if (last != 1) {
strncat(buffer, black, black_s);
COPY_AND_ADVANCE_N(pbuf, black, black_s);
last = 1;
}
} else if(last != 0) {
strncat(buffer, white, white_s);
COPY_AND_ADVANCE_N(pbuf, white, white_s);
last = 0;
}
strncat(buffer, " ", 2);
COPY_AND_ADVANCE(pbuf, " ");
}

if (last != 0) {
strncat(buffer, white, white_s);
COPY_AND_ADVANCE_N(pbuf, white, white_s);
}
for (x = 0; x < margin; x++) {
strncat(buffer, " ", 2);
COPY_AND_ADVANCE(pbuf, " ");
}
strncat(buffer, "\033[0m\n", 5);
COPY_AND_ADVANCE(pbuf, "\033[0m\n");
fputs(buffer, fp);
}

Expand Down

0 comments on commit 6df2b74

Please sign in to comment.