0

I am writing a piece of code in C++ that takes a char array as input which contains a JSON-like text. The idea is to get the values from that JSON.

The function that is giving the error is the following:

variable * getVariableInfo(const char * variableInfo){
        /*get {...}*/
        printf("%s\n",variableInfo);
        int start, countWord=0;
        int order=-1, type=-1;
        char * value;
        variable * returnValue;
        const char * aux;
        while(*(variableInfo++)){
            if(*variableInfo=='"'){
                variableInfo++;
                aux=variableInfo;
                countWord=0;
                while(*(variableInfo++)!='"'){
                    countWord++;
                }
                char *word = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                strncpy(word, aux, countWord);
                word[countWord]='\0';
                printf("\nWORD %s", word);

                while(*(variableInfo++)!='"');
                aux=variableInfo;
                countWord=0;
                while(*(variableInfo++)!='"'){
                    countWord++;
                }
                char *str = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                strncpy(str, aux, countWord);
                str[countWord]='\0';
                printf("\nSTR %s\n",str);
                if(strcmp(word,ORDER)==0){
                        order=a2i(str);
                        printf("ORDER = %i", order);
                }
                /*TYPE*/
                else if(strcmp(word,TYPE)==0){
                        if(strcmp(str, valueINT)==0) type=TYPE_INT;
                        else if(strcmp(str, valueSTR)==0) type=TYPE_STRING;
                        else if(strcmp(str, valueBOOL)==0) type=TYPE_BOOLEAN;
                        else return 0;
                        printf("TYPE = %i", type);
                /*VALUE*/
                }
                else if(strcmp(word,VALUE)==0){
                        value =  (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
                        strncpy(value, str, countWord);
                        value[countWord]='\0';
                        printf("VALUE = %s", value);
                }
                else{
                        printf("ELSE");
                        return 0;
                }
            }
            printf("\nCHAR %c\n---------", *variableInfo);
        }

        printf("Pass");
        if(type==-1||order==-1||!value){
            if(!type) printf("NOT");
            if(!order) printf("NOO");
            if(!value) printf("NOV");
            return 0;
        } 
        returnValue = (variable *) calloc(1,sizeof(variable)+(sizeof(char)*(strlen(value)+1)));
        returnValue->order=order;
        returnValue->type=type;
        strncpy(returnValue->value,value,strlen(value));
        returnValue->value[strlen(value)]='\0';
        return returnValue;
}

The var "variableInfo" is sent from another function and is created like following from the aux pointer which contains the original full JSON-like text:

variableInfo = (char *) calloc(1, sizeof(char) * ( countWord + 1 ) );
strncpy(variableInfo, aux, countWord);
variableInfo[countWord]='\0';                               
variables[variableCount]=getVariableInfo(variableInfo);

As you can see, I added some printf and the output looks like the following:

{"ORDER":"0","TYPE":"int","VALUE":"9999"}

WORD ORDER
STR 0
ORDER = 0
CHAR ,
---------
WORD TYPE
STR int
TYPE = 0
CHAR ,
---------
WORD VALUE
STR 9999
VALUE = 9999
CHAR }
---------
CHAR 
Segmentation fault (core dumped)

I print the "variableInfo" variable and it shows the right piece of text that should be sent to the "getVariableInfo" function, then the values for ORDER, TYPE and VALUE are properly taken from the JSON-like text. However, I get the segmentation fault error, since the last round of the while, even if the last char is '\0' it stays in the while loop (See output "CHAR }" should be last and next time that checks the while statement it should end it but it then prints "CHAR ").

Thanks for your help.

Kind regards.

Asier
  • 11
  • 2
    Completely irrelevant of your problem, but thats a lot of code for traversing a json string. If possible, consider a different way to do this. – Ezio May 30 '17 at 08:17
  • 5
    This look more like C than C++ – nefas May 30 '17 at 08:18
  • *However, I get the segmentation fault error,* -- Not surprised, with all of that `C` code. Where is the usage of `std::string` and `std::vector`? And if it's JSON, consider using a JSON library and not try to parse this code yourself. – PaulMcKenzie May 30 '17 at 08:23
  • Hello, thanks for your responses. The reason why I am trying to create my own JSON is that I am working in a limited environment. However, I checked the environment again and seems that I can use string and vector there too, so I will try using them. Thanks for your help :) – Asier May 30 '17 at 08:51

2 Answers2

0

You are using the post-increment operator to increment variableInfo. This operator returns a copy of the old pointer value, which does not point to \0. Use pre-increment instead:

while(*(++variableInfo))

Pre-increment will return the incremented value. See this question for more info on pre- and post-increment.

maddin45
  • 737
  • 7
  • 17
0

In this case if I would debug I might choose to store the original value of 'variableinfo' and print 'variableinfo-originalPointer' - to get a sensable index value.

I don't have a C compiler handy but I do wonder about your while loops: Perhaps

while (*(variableinfo++)=='"') 

Always increases 'variableinfo'. If that is so, it can be increased 3 times (three while-loops) before you check that the end of the string may be reached. If that is the case, it can go past the end of the string, never detecting that it crosses the end of the string.

Solutions: (1) tear the whileloops apart to make the increment explicit, and (2) Always check for '\0' when you increase your string-pointer:

while(*variableinfo == '"' && *variableinfo!='\0')
{
    variableinfo++;
}

and possibly:

if ('\0' == *variableinfo)
    break;

to exit the outermost loop immediately.

  • Thanks for your response, I tried implementing your solution but still getting the error. As I said a response earlier, I can use string and vector in the limited environment so I guess I will give a try to it. Thanks for your time :) – Asier May 30 '17 at 08:59