Skip to content

Commit

Permalink
Z: Fix atoe_vsnprintf to support null buffer
Browse files Browse the repository at this point in the history
Std vsnprintf accepts null buffer and returns an estimate
Our implementation does not support that
Updated the atoe_vsnprintf implementation

Signed-off-by: ehsan kiani far ehsan.kianifar@gmail.com
  • Loading branch information
ehsankianifar committed Oct 31, 2023
1 parent 386a708 commit 3cb6426
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 24 deletions.
3 changes: 2 additions & 1 deletion fvtest/porttest/omrstrTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1486,7 +1486,8 @@ printToBuffer(struct OMRPortLibrary *portLibrary, BOOLEAN precision, char *buffe
va_list args;

va_start(args, format);
stringLength = atoe_vsnprintf(buffer, bufferLength, format, args);
atoe_vsnprintf(buffer, bufferLength, format, args);
stringLength = strlen(buffer);
va_end(args);

if (stringLength >= 0) {
Expand Down
57 changes: 34 additions & 23 deletions util/a2e/atoe_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <stdio.h>
#include <stdlib.h> /* for malloc() via e2a_string()/a2e_string() */
#include <string.h>
#include <limits.h>

/*
* ======================================================================
Expand All @@ -55,11 +56,12 @@

#define ERROR_RETVAL -1
#define SUCCESS 0
#define CheckRet(x) { if ((x) == ERROR_RETVAL) return ERROR_RETVAL; }
#define CheckRet(x) { if ((x) < 0) return ERROR_RETVAL; }

typedef struct InstanceData {
char *buffer;
char *end;
int counter;
} InstanceData;

/**************************************************************************
Expand Down Expand Up @@ -100,11 +102,12 @@ pchar(InstanceData *this, int c)
*this->buffer++ = '^';
}
#endif /* 0 */
this->counter++;

if (this->buffer >= this->end) {
return ERROR_RETVAL;
if (this->buffer != NULL && this->buffer < this->end) {
*this->buffer++ = c;
}
*this->buffer++ = c;

return SUCCESS;
}

Expand Down Expand Up @@ -418,18 +421,18 @@ atoe_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
bool_t fPrecision;
int min_width, precision, ch;
static char NULLCHARSTRING[] = "[null]"; /*ibm@029013*/
this.counter = 0;
/*ibm@029013*/
if (fmt == NULL) { /*ibm@029013*/
fmt = NULLCHARSTRING; /*ibm@029013*/
} /*ibm@029013*/
if (str == NULL) {
return ERROR_RETVAL;
}
str[0] = '\0';

this.buffer = str;
this.end = str + count - 1;
*this.end = '\0'; /* ensure null-termination in case of failure */
this.end = this.buffer + count - 1;

if(this.buffer != NULL){
this.buffer[0] = '\0';
*this.end = '\0'; /* ensure null-termination in case of failure */
}

while ((ch = *fmt++) != 0) {
if (ch == '%') {
Expand All @@ -440,7 +443,7 @@ atoe_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
pattern = fmt - 1; /*ibm@8665*/
left_justify = TRUE;
min_width = 0;
precision = this.end - this.buffer;
precision = INT_MAX;

next_char:
ch = *fmt++;
Expand Down Expand Up @@ -545,22 +548,28 @@ atoe_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
/* ibm@8665
* Add floating point support for dbl2str & flt2str
*/
char *b;
int len;
char *tempPattern;

b = a2e((char *)pattern, fmt - pattern);
tempPattern = a2e((char *)pattern, fmt - pattern);

/* Extract a double from args, this works for both doubles
* and floats,
* NB if we use float for a single precision floating
* point number the result is wrong.
*/
len = sprintf(this.buffer, b, va_arg(args, double));
free(b);
b = e2a_string(this.buffer);
strcpy(this.buffer, b);
free(b);
this.buffer += len;
size_t freeCap = count > this.counter ? count - this.counter : 0;
double argument = va_arg(args, double);
int requiredSpace = snprintf(this.buffer, freeCap, tempPattern, argument);
free(tempPattern);
CheckRet(requiredSpace);
this.counter += requiredSpace;
if ((freeCap > 0) && (requiredSpace > 0)) {
tempPattern = e2a_string(this.buffer);
strcpy(this.buffer, tempPattern);
int JumpLength = freeCap > requiredSpace ? requiredSpace : freeCap;
this.buffer += JumpLength;
free(tempPattern);
}
}
break;
default:
Expand All @@ -584,8 +593,10 @@ atoe_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
CheckRet(pchar(&this, ch));
}
}
*this.buffer = '\0';
return strlen(str);
if(this.buffer != NULL){
*this.buffer = '\0';
}
return this.counter;
}

/* END OF FILE */

0 comments on commit 3cb6426

Please sign in to comment.