Skip to content

clang-tidy: enable bugprone-signed-char-misuse, fix fallouts#20654

Closed
vszakats wants to merge 2 commits intocurl:masterfrom
vszakats:ctidy14
Closed

clang-tidy: enable bugprone-signed-char-misuse, fix fallouts#20654
vszakats wants to merge 2 commits intocurl:masterfrom
vszakats:ctidy14

Conversation

@vszakats
Copy link
Member

@vszakats vszakats commented Feb 20, 2026

Examples:

lib/vtls/openssl.c:2585:18: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
 2585 |       msg_type = *(const char *)buf;
lib/vtls/openssl.c:2593:18: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
 2593 |       msg_type = *(const char *)buf;
tests/server/mqttd.c:514:10: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse]
  514 |       if(passwd_flag == (char)(conn_flags & passwd_flag)) {
tests/server/tftpd.c:362:13: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  362 |         c = test->rptr[0];
tests/server/tftpd.c:454:9: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  454 |     c = *p++;                     /* pick up a character */
src/tool_urlglob.c:272:46: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  272 |     pat->c.ascii.letter = pat->c.ascii.min = min_c;
src/tool_urlglob.c:273:24: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  273 |     pat->c.ascii.max = max_c;
tests/libtest/cli_h2_pausing.c:164:23: warning: suspicious usage of 'sizeof()' on an expression of pointer type [bugprone-sizeof-expression]
  164 |   memset(&resolve, 0, sizeof(resolve));
tests/libtest/cli_upload_pausing.c:158:23: warning: suspicious usage of 'sizeof()' on an expression of pointer type [bugprone-sizeof-expression]
  158 |   memset(&resolve, 0, sizeof(resolve));
tests/libtest/first.c:86:15: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
   86 |     coptopt = arg[optpos];
tests/tunit/../libtest/first.c:86:15: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
   86 |     coptopt = arg[optpos];
tests/unit/../libtest/first.c:86:15: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
   86 |     coptopt = arg[optpos];

Also:

  • tests/server/mqttd: drop a redundant and a wrongly signed cast.

Ref: https://clang.llvm.org/extra/clang-tidy/checks/bugprone/signed-char-misuse.html


@vszakats vszakats marked this pull request as draft February 20, 2026 17:09
@vszakats
Copy link
Member Author

augment review

@augmentcode
Copy link

augmentcode bot commented Feb 20, 2026

🤖 Augment PR Summary

Summary: Enables clang-tidy’s bugprone-signed-char-misuse check and updates affected code paths to treat bytes as unsigned where needed.
Changes: Adds explicit (unsigned char) casts / unsigned-byte reads across inet_pton parsing, MIME quoted-printable encoding, OpenSSL trace decoding, URL glob ASCII ranges, and a few test utilities to avoid sign-extension/mismatched signedness warnings.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. No suggestions at this time.

Comment augment review to trigger a new review at any time.

@vszakats vszakats marked this pull request as ready for review February 20, 2026 19:40
@vszakats
Copy link
Member Author

@aisle-analyzer

@aisle-research-bot
Copy link

aisle-research-bot bot commented Feb 20, 2026

🔒 Aisle Security Analysis

We found 1 potential security issue(s) in this PR:

# Severity Title
1 🔵 Low Out-of-bounds read in OpenSSL message trace callback (ossl_trace) when record length is too short

See details in the comment below.


Analyzed PR: #20654 at commit 9227fd1

Comment on lines 2584 to 2595
if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
msg_type = *(const char *)buf;
msg_type = *(const unsigned char *)buf;
msg_name = "Change cipher spec";
}
else if(content_type == SSL3_RT_ALERT) {
msg_type = (((const char *)buf)[0] << 8) + ((const char *)buf)[1];
msg_type = (((const unsigned char *)buf)[0] << 8) +
((const unsigned char *)buf)[1];
msg_name = SSL_alert_desc_string_long(msg_type);
}
else {
msg_type = *(const char *)buf;
msg_type = *(const unsigned char *)buf;
msg_name = ssl_msg_type(ssl_ver, msg_type);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1. 🔵 Out-of-bounds read in OpenSSL message trace callback (ossl_trace) when record length is too short

Property Value
Severity Low
CWE CWE-125

Description

In ossl_trace() (registered via SSL_CTX_set_msg_callback when verbose tracing is enabled), the code unconditionally reads the first byte of buf and, for alerts, the first two bytes:

  • msg_type = *(const unsigned char *)buf;
  • msg_type = (((const unsigned char *)buf)[0] << 8) + ((const unsigned char *)buf)[1];

There is no guard that len is at least 1 (or 2 for alerts) before these dereferences.

If OpenSSL invokes the msg callback with a short/empty record payload (e.g., a zero-length TLS record, or a malformed short alert record), this will read past the end of the provided buffer.

Impact:

  • Remote-triggerable crash (DoS) in applications that enable libcurl verbose tracing with the OpenSSL msg callback.
  • Potential information disclosure of adjacent memory via the computed msg_type included in debug output (though only in verbose/debug logging mode).

Vulnerable code:

if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
  msg_type = *(const unsigned char *)buf;
}
else if(content_type == SSL3_RT_ALERT) {
  msg_type = (((const unsigned char *)buf)[0] << 8) +
              ((const unsigned char *)buf)[1];
}
else {
  msg_type = *(const unsigned char *)buf;
}

Recommendation

Add length guards before dereferencing buf, and handle short records safely (e.g., log "short record" / "truncated alert" without reading bytes).

Example fix:

if(len < 1)
  return; /* or skip msg_type parsing */

if(content_type == SSL3_RT_ALERT) {
  if(len < 2) {
    msg_type = 0;
    msg_name = "Truncated alert";
  }
  else {
    const unsigned char *p = buf;
    msg_type = (p[0] << 8) | p[1];
    msg_name = SSL_alert_desc_string_long(msg_type);
  }
}
else {
  msg_type = *(const unsigned char *)buf;
  ...
}

This ensures the trace callback never reads past the provided buffer regardless of what OpenSSL passes to it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tackled via b35e58b #20656

vszakats added a commit to vszakats/curl that referenced this pull request Feb 20, 2026
vszakats added a commit to vszakats/curl that referenced this pull request Feb 20, 2026
vszakats added a commit that referenced this pull request Feb 21, 2026
@vszakats vszakats changed the title clang-tidy: try fixing bugprone-signed-char-misuse clang-tidy: fix bugprone-signed-char-misuse warnings Feb 22, 2026
@vszakats vszakats changed the title clang-tidy: fix bugprone-signed-char-misuse warnings clang-tidy: enable bugprone-signed-char-misuse, fix fallouts Feb 22, 2026
```
lib/vtls/openssl.c:2585:18: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
 2585 |       msg_type = *(const char *)buf;
      |                  ^
lib/vtls/openssl.c:2593:18: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
 2593 |       msg_type = *(const char *)buf;
      |                  ^
tests/server/mqttd.c:514:10: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse]
  514 |       if(passwd_flag == (char)(conn_flags & passwd_flag)) {
      |          ^
tests/server/tftpd.c:362:13: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  362 |         c = test->rptr[0];
      |             ^
tests/server/tftpd.c:454:9: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  454 |     c = *p++;                     /* pick up a character */
      |         ^
src/tool_urlglob.c:272:46: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  272 |     pat->c.ascii.letter = pat->c.ascii.min = min_c;
      |                                              ^
src/tool_urlglob.c:273:24: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  273 |     pat->c.ascii.max = max_c;
      |                        ^
tests/libtest/cli_h2_pausing.c:164:23: warning: suspicious usage of 'sizeof()' on an expression of pointer type [bugprone-sizeof-expression]
  164 |   memset(&resolve, 0, sizeof(resolve));
      |                       ^
tests/libtest/cli_upload_pausing.c:158:23: warning: suspicious usage of 'sizeof()' on an expression of pointer type [bugprone-sizeof-expression]
  158 |   memset(&resolve, 0, sizeof(resolve));
      |                       ^
tests/libtest/first.c:86:15: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
   86 |     coptopt = arg[optpos];
      |               ^
tests/tunit/../libtest/first.c:86:15: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
   86 |     coptopt = arg[optpos];
      |               ^
tests/unit/../libtest/first.c:86:15: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
   86 |     coptopt = arg[optpos];
      |               ^
```

Ref: https://clang.llvm.org/extra/clang-tidy/checks/bugprone/signed-char-misuse.html
@vszakats vszakats closed this in ac46392 Feb 25, 2026
@vszakats vszakats deleted the ctidy14 branch February 25, 2026 13:46
dkarpov1970 pushed a commit to dkarpov1970/curl that referenced this pull request Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

1 participant