Main Content

Invalid use of standard library routine

Standard library function is called with invalid arguments

Description

This check on a standard library function call determines whether the function is called with valid arguments.

The check works differently for memory routines, floating point routines or string routines because their arguments can be invalid in different ways. For more information on each type of routines, see the following examples.

Examples

expand all

#include <assert.h>
#include <math.h>

#define LARGE_EXP 710

enum operation {
    ASIN,
    ACOS,
    TAN,
    SQRT,
    LOG,
    EXP,
};

enum operation getOperation(void);
double getVal(void);

void main() {
    enum operation myOperation = getOperation();
    double myVal=getVal(), res;
    switch(myOperation) {
    case ASIN:
        assert( myVal <- 1.0 || myVal > 1.0);
        res = asin(myVal);
        break;
    case ACOS:
        assert( myVal < -1.0 || myVal > 1.0);
        res = acos(myVal);
        break;
    case SQRT:
        assert( myVal < 0.0);
        res = sqrt(myVal);
        break;
    case LOG:
        assert(myVal <= 0.0);
        res = log(myVal);
        break;
    case EXP:
        assert(myVal > LARGE_EXP);
        res = exp(myVal);
        break;
    }
}

In this example, following each assert statement, Polyspace® considers that myVal contains only those values that make the assert condition true. For example, following assert(myVal < 1.0);, Polyspace considers that myVal contains values less than 1.0.

When myVal is used as argument in a standard library function, its values are invalid for the function. Therefore, the Invalid use of standard library routine check produces a red error.

To learn more about the specifications of this check for floating point routines, see Invalid Use of Standard Library Floating Point Routines.

#include <string.h>
#include <stdio.h>

char* Copy_First_Six_Letters(void) {
  char str1[10],str2[5];
  printf("Enter string:\n");
  scanf("%s",str1);
  memcpy(str2,str1,6);
  return str2;
}

int main(void) {
  (void*)Copy_First_Six_Letters();
  return 0;
}

In this example, the size of string str2 is 5, but 6 characters of string str1 are copied into str2 using the memcpy function. Therefore, the Invalid use of standard library routine check on the call to memcpy produces a red error.

For other examples, see Code Prover Assumptions About memset and memcpy.

Correction — Call function with valid arguments

One possible correction is to adjust the size of str2 so that it accommodates the characters copied with the memcpy function.

#include <string.h>
#include <stdio.h>

char* Copy_First_Six_Letters(void) {
  char str1[10],str2[6];
  printf("Enter string:\n");
  scanf("%s",str1);
  memcpy(str2,str1,6);
  return str2;
}

int main(void) {
  (void*)Copy_First_Six_Letters();
  return 0;
}
#include <stdio.h>
#include <string.h>

char* Copy_String(void)
{
  char *res;
  char gbuffer[5],text[20]="ABCDEFGHIJKL";
  res=strcpy(gbuffer,text);
  return(res);
}

int main(void) {
  (void*)Copy_String();
}

In this example, the string text is larger in size than gbuffer. Therefore, when you copy text into gbuffer. the Invalid use of standard library routine check on the call to strcpy produces a red error.

Correction — Call function with valid arguments

One possible correction is to declare the destination string gbuffer with equal or larger size than the source string text.

#include <stdio.h>
#include <string.h>

char* Copy_String(void)
{
  char *res;
  char gbuffer[20],text[20]="ABCDEFGHIJKL";
  res=strcpy(gbuffer,text);
  return(res);
}

int main(void) {
  (void*)Copy_String();
}
#include <string>

void main() {
    std::string str = "";
    const char txt[3] = {'n','o','p'};
    str.append(txt);  //txt is not a valid string
}

In this example, txt is not a null-terminated character sequence (C-string). Therefore, the Invalid use of standard library routine check on the call to std::string::append is red.

Correction – Use null-terminated C-string when expected

For methods that take a const char* argument str, make sure that str is non-NULL and points to a valid null-terminated C-string.

#include <string>

void main() {
    std::string str = "";
    const char txtStr[4] = {'n','o','p', '\0'};
    str.append(txtStr); //txtStr is valid string
}

The Invalid use of standard library routine check on the free() function determines if the pointer argument to the function:

  • Is a non-null pointer.

  • Was previously allocated dynamically by an authorized allocation function such as malloc() or realloc().

The check can detect issues associated with freeing of memory such as:

  • Consecutive freeing of memory.

    #include <stdlib.h>
    #include <stdio.h>
    
    int increment_content_of_address(int base_val, int shift)
    {
        int j;
        int* pi = (int*)malloc(sizeof(int));
        if (pi == NULL) return 0;
    
        *pi = base_val;
    
        if(shift < 0)
            {
                j = *pi - shift;
                free(pi);
            }
    
        else if(shift > 0)
            {
                j = *pi + shift;
                free(pi);
            }
        else
            {
                j = *pi;
            }
    
        free(pi);
        return j;
    }

    In this example, the pointer pi is freed twice on some execution paths. The Invalid use of standard library routine check detects this issue and reports a possible run-time error (orange check).

  • Freeing of memory that was not allocated dynamically:

    #include <stdlib.h>
    
    int performOperationsWithAllocatedMemory(unsigned int size) {
        char base = 0;
        char *ptr = &base;
        if(size > 0) {
            ptr = (char*)malloc(sizeof(char)*size);
        }
        //Some operations
        free(ptr);    
        return 0;
    }

    In this example, if the argument size to the function performOperationsWithAllocatedMemory is zero, the pointer ptr is not allocated memory dynamically. However, the free() function is used on this pointer in all cases including when the argument size is zero. The Invalid use of standard library routine check detects this issue and reports a possible run-time error (orange check).

Note that the Invalid use of standard library routine check reports a possible run-time error (orange check) if the pointer is an external pointer and its dynamic memory allocation status is not known. For instance, if a function with a pointer argument is not called anywhere in the source files and you use free() on this pointer inside the function body (without dynamically allocating memory first), an orange check is displayed on free().

Check Information

Group: Other
Language: C | C++
Acronym: STD_LIB