5 years, 2 months ago.

Problem with UART serial read to return when CR is pressed

I am using Nucleo-F103RB. I am trying to implement a serial console with password input Below is my code

int main() {

while(1)
{   
   char* ab;
    myled = 1;
    pc.printf("Test\n");
    pc.printf("Enter the password: ");
    ///////pc.gets(ab,(sizeof(char)*256));
    pc.scanf("%s",&ab);
    pc.printf("%s ",ab);
    if(strcmp(ab, "password")==0)
    {
      fun1();
    }
  else
    {
     f2();
    }

wait(10);  
}
}

My NooB question

1. I want the user to enter a password of unlimited length. Not the buffered one like gets(). ( I don't care about BoF atm) 2. How do i make sure that when they press enter it returns whatever the value? Should I use an array and check for /n ?

Thanks in advance

Not sure what you mean. The code you have does this already right? Your biggest problem is that you're not initializing the ab pointer so you're writing in uninitialized memory which will cause you big trouble. Change that line to char ab[1024] = {0};.

posted by Jan Jongboom 03 Mar 2017

1 Answer

5 years, 2 months ago.

You may not care about buffer overflow but you still need a buffer to put the data in, you aren't allocating any memory at all to store the entered text in. Unless the initial value of ab just happens to be in the RAM area of the memory map you're not going to get anything meaningful.

1. I want the user to enter a password of unlimited length. Not the buffered one like gets().

What's wrong with the scanf method you were using? You said you didn't care about buffer overflows so that should work fine. If you want one character at a time then you can use getc().

2. How do i make sure that when they press enter it returns whatever the value? Should I use an array and check for /n ?

Yes, check for /n. Also check for /r just in case their terminal is set to send /r/n for a new line. But if you are checking one character at a time there is no need to use an array, you can check each letter as you get it so there is no need to store it.

Fixed version of your code:

int main() {
 
  while(1)
  {   
    char ab[1024]; // allocate 1024 bytes, you will overflow if they enter more than that.
    myled = 1;
    pc.printf("Test\n");
    pc.printf("Enter the password: ");
    ///////pc.gets(ab,(sizeof(char)*256));
    pc.scanf("%s",ab); // no need for the &, ab is already of type char *
    pc.printf("%s ",ab);
    if(strcmp(ab, "password")==0)
    {
      fun1();
    }
    else
    {
      f2();
    }
 
    wait(10);  
  }
}

version using getc that is immune to buffer overflows.

// returns true if the correct password is entered.
bool checkPassword() {

  const char *correctPassword = "password"; // the password to look for.
  bool passwordCorrect = true; // track if there have been any errors
  int characterPointer = 0; // current character to check.
  int passwordLen = strlen(correctPassword); // length of the password.

  char userEntry;

  do {
    userEntry = pc.getc(); // get the next character
    if (characterPointer < passwordLen) { // if we aren't passed the end of the password
      if ( userEntry != *(correctPassword + characterPointer) ) // check their entry against the letter characterPointer into the password
        passwordCorrect = false;    // if the letters don't match they got it wrong.
    }

    characterPointer++;

  } while ( (userEntry != \n )&& (userEntry != \r )) // keep going until they hit enter

  if (characterPointer != passwordLen)  // if they entered the wrong number of letters then it must be wrong.
    return false;

  return passwordCorrect; // if the length was correct return whether any of the letters were wrong.
}


int main() {
 
  while(1)
  {   
    myled = 1;
    pc.printf("Test\n");
    pc.printf("Enter the password: ");
    if(checkPassword())
    {
      fun1();
    }
    else
    {
      f2();
    }
 
    wait(10);  
  }
}

Ok. I can understand the buffer overflow part now. I have tried this already.

My next problem how do I make the Enter work? This will read the character forever.

posted by Arun Magesh 03 Mar 2017

scanf() should automatically return on a \n in the input stream. I've just updated the answer to show how to do it using getc() to read one character at a time rather than a string.

posted by Andy A 03 Mar 2017