Re: smtp.c and popsbr.c do not require C strings

Robert Elz <[email protected]> Thu, 03 Jul 2025 10:12:18 +0700
Newsgroups gmane.mail.nmh.devel
Message-ID <[email protected]>
    Date:        Wed, 02 Jul 2025 09:15:52 -0700
    From:        Stephen Gildea <[email protected]>
    Message-ID:  <[email protected]>

  |  	if (doingEHLO
  |  	        && has_prefix_len(buffer, buflen, "250")
  | -	        && (buffer[3] == '-' || doingEHLO == 2)
  | -	        && buffer[4]) {
  | +	        && (has_prefix_len(buffer, buflen, "250-") || doingEHLO == 2)

That change looks bizarre, and silly, to me - the previous (unchanged)
line already checked that buffer[0,1,2] == "250", there's no reason to
check those again, just testing that buffer [3] == '-' (the old way) is
much better.

  | +	        && buflen > 4) {

but that, instead of checking the buffer[4] is not \0 is OK.

  | -	code = atoi ((char *) bp);
  | -	bp += 3, buflen -= 3;
  | +	for (code = 0; buflen > 0 && isdigit (*bp); bp++, buflen--) {
  | +            code = code * 10 + (*bp - '0');
  | +	}

It is hard to argue against anything which replaces atoi(), but
new code these days should be checking for overflow (and as this
is, probably, an SMTP response code, perhaps allowing just 3 digits
instead - overflow can't happen then).

It is also wrong to call isdigit with a char arg, unless there's some
way to guarantee it is between 0 and 255 (or EOF).   Further, I assume
that something is guaranteeing that LC_CTYPE == "C" there, or assuming
that isdigit() returning true means '0' .. '9' is probably unsafe -- might
be better to just open code what isdigit() is supposed to be doing,
	*bp >= '0' && *bp <= '9'


  | -		puts(sm_reply.text);
  | +		printf("%.*s", sm_reply.length, sm_reply.text);

That change drops the \n that puts() appends to the written string.


  | -		if (len != 2 || strcmp(line, "+ ") != 0) {
  | +		if (len != 2 || strncmp(line, "+ ", 2) != 0) {

personally I'd question using any strcmp() type function for checking
just two chars:
		if (len != 2 || line[0] != '+' || line[1] != ' ') {


kre