-5

I am trying to implement a command line interface function for a micro-controller, which has very limited stack size (around 1kB) and I do not want to use an array to hold the string values to not push them into the stack. I come up with two solutions, but according to the coding standard, I should not use #define in the function definition.

How can I use strings along with sizeof operator without using #define and arrays?

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

#define ARRAY_COUNT(a) (sizeof(a)/sizeof(a[0]))

int cli(int argc, char *argv[])
{
#if 1
    // I should not use #define in function definition due to the coding standard
    #define fetch "fetch"
    #define push "push"
    #define quit "quit"
#else
    // arrays get allocated in stack, and stack is very small
    const char fetch[] = "fetch";
    const char push[] = "push";
    const char quit[] = "quit";
#endif
    if (1 < argc) {
        if (!strncmp(argv[1], fetch, ARRAY_COUNT(fetch)-1)) {
            // do fetc...
        } else if (!strncmp(argv[1], push, ARRAY_COUNT(push)-1)) {
            // do push...
        } else if (!strncmp(argv[1], quit, ARRAY_COUNT(quit)-1)) {
            // do quit...
        }
    }

    return 0; 
}
Ken White
  • 123,280
  • 14
  • 225
  • 444
albin
  • 773
  • 1
  • 8
  • 27
  • Declare the arrays with `static`. – Eric Postpischil Oct 16 '22 at 03:48
  • 1
    Is using the string literals directly a possibility? Then they would just be stored in the string table, or equivalent, in ROM/flash. You would then need to use strlen to get the length. – Avi Berger Oct 16 '22 at 03:52
  • 2
    Since you're passing the length of second string to `strncmp()`, you can use `strcmp()` and not worry about computing the length. So simply do `if (!strcmp(argv[1], fetch))` or even `if (!strcmp(argv[1], "fetch"))` instead. – Peter Oct 16 '22 at 03:56
  • 1
    @AviBerger That was my first solution, to use strlen to get string length on runtime, but this has performance penalty. – albin Oct 16 '22 at 03:57
  • @Peter This is another option, but this takes arguments from command line interface which can have unknown length of input, and strcmp can cause security vulnerability. – albin Oct 16 '22 at 04:02
  • True, but as @Peter pointed out, its not clear that your strncmp rather than using strcmp is actually useful or would be an actual vulnerability.. If the argv strings are null terminated and you are looking for an exact match then strncmp helps you not at all. OTOH your strncmp code would produce a positive match for an input of "fetchxyz!&^%" – Avi Berger Oct 16 '22 at 04:08
  • 1
    See [here](https://stackoverflow.com/a/24353916/631266) and [here](https://stackoverflow.com/a/30190652/631266) regarding the potential vulnerability for strcmp. If you are parsing the command line and insure that you are feeding in properly null terminated strings, strcmp is your best choice for memory usage and performance, unless you are doing prefix matching. Another alternative is to static array of struct (containing a const char * and an int length) possibly indexed by an enum value. – Avi Berger Oct 16 '22 at 04:26

1 Answers1

1

Make the arrays static so they will not be allocated on the stack.

static const char fetch[] = "fetch";
static const char push[] = "push";
static const char quit[] = "quit";
user16217248
  • 3,119
  • 19
  • 19
  • 37