hd44780-i2c icon indicating copy to clipboard operation
hd44780-i2c copied to clipboard

Small fix and add new escape sequence commands

Open kreijack opened this issue 5 years ago • 6 comments

Dear all,

please consider this PR composed by 4 commits:

  • dcb7fbb -> small fix: after an if, before its body there is a ';'.
  • ba097fa -> increase the buffer size, in order to make space for the '0'. I am not sure that this is a problem, however I think that it is better to have all the string 0 terminated.
  • ebd2ae2 -> add support for the ESC [<r>;<c>H command to allow the placing of the cursor at row 'r' and column 'c'. Also the following short versions are allowed: ESC [<r>H and ESC [;<c>H.
  • d63a66c -> add further commands like:
  1. ESC c (RIS) reset to initial state
  2. ESC [ ? 25 h show cursor
  3. ESC [ ? 25 l hide cursor
  4. ESC [ 5 m blink on
  5. ESC [ 25 m blink of

kreijack avatar Aug 28 '19 19:08 kreijack

ba097fa : Why do you care if this char array is anyhow terminated and if it's overwritten?

gorskima avatar Aug 29 '19 19:08 gorskima

d63a66c : :+1:

gorskima avatar Aug 29 '19 19:08 gorskima

ebd2ae2 : Look pretty tricky; my guts tell me it can be done simpler ;)

Did you test all this stuff?

gorskima avatar Aug 29 '19 19:08 gorskima

ba097fa : Why do you care if this char array is anyhow terminated and if it's overwritten?

This buffer is used by function like strcmp() which assumes the buffer is zero terminated. Event tough in this case there is no problem (strcmp works against static string with a length lesser than this buffer), I fear that in future developments this could lead to a buffer exploit.

kreijack avatar Aug 29 '19 21:08 kreijack

ebd2ae2 : Look pretty tricky; my guts tell me it can be done simpler ;)

The CUP escape sequence is quite complicate: all the following formats are allowed: ESC [H ESC [H ESC [;H ESC [H

(and the variants which end by 'f')

I tried also sscanf [*], but at the end I concluded that I would test all these cases separately (i.e. something like:

if (strcmp(buf, "[H") == 0) {
   ... 
} else if (sscanf(buf, "[%dH", &r) == 1) {
   ....
} else if (sscanf(buf, "[;%dH", &c) == 1) {
   ....
} else if (sscanf(buf, "[%d;%dH", &r, &c) == 2) {
   ....

However sscanf don't check if the last char is 'H'....)

Did you test all this stuff?

Yes, see https://godbolt.org/z/C4gyHk

[*] If I used sscanf, the buffer would be needed terminated by '\0'....

kreijack avatar Aug 29 '19 21:08 kreijack

ebd2ae2 : Look pretty tricky; my guts tell me it can be done simpler ;)

The CUP escape sequence is quite complicate: all the following formats are allowed:

I tried to simplify the code. Let me know your opinion:

static inline int __isdigit(const char c)
{
	return c >= '0' && c <= '9';
}

/*
 *	Be aware that the following function supports only positive conversion
 */
static inline int __atoi(const char *p)
{
	int ret = 0;
	while (__isdigit(*p))
		ret = ret * 10 + *p++ - '0';
	return ret;
}

static int hd44780_parse_cup_command(const char *p, int *pr, int *pc)
{
	int r = 0;
	*pr = *pc = -1;

	if (*p != '[')
		return -1;
	p++;

	while (r < 2) {
		if (__isdigit(*p)) {
			/* there is a numeric argument */
			if (r==0)
				/* first arg */
				*pr = __atoi(p);
			else
				/* second arg */
				*pc = __atoi(p);
			while (__isdigit(*p))
				p++;
		} else if (*p == ';') {
			/* there is another arg, continue */
			p++;
			r++;
		} else if (*p == 'H'|| *p == 'f') {
			/* no more arg, exit */
			return 0;
		} else {
			/* unexpected char (not digit, nor ';' nor 'H'*/
			return -2;
		}
	}
	/* too much arg */
	return -3;
}

kreijack avatar Aug 30 '19 19:08 kreijack