Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: libdnf5-cli: TransactionSummary counters data type #1701

Conversation

jrohel
Copy link
Contributor

@jrohel jrohel commented Sep 17, 2024

Fixes error: implicit conversion changes signedness: 'const int' to 'unsigned long' [-Werror,-Wsign-conversion]

The bug was caused by commit #1696

Fixes "error: implicit conversion changes signedness: 'const int' to
'unsigned long' [-Werror,-Wsign-conversion]"
The bug was caused by commit "I18N: Mark messages in "dnf install" output
for a translation"
@m-blaha m-blaha self-assigned this Sep 17, 2024
@ppisar
Copy link
Contributor

ppisar commented Sep 17, 2024

Sorry. I did not notice that ngettext() expects an unsigned long int as a counter. Shouldn't we add -Wsign-conversion to CXXFLAGS so that GCC catches it too?

Copy link
Member

@m-blaha m-blaha left a comment

Choose a reason for hiding this comment

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

Thank you!

@m-blaha
Copy link
Member

m-blaha commented Sep 17, 2024

Sorry. I did not notice that ngettext() expects an unsigned long int as a counter. Shouldn't we add -Wsign-conversion to CXXFLAGS so that GCC catches it too?

Good idea. I tried, but I must have done it incorrectly, because even with -Wsign-conversion the gcc did not catch the error.

@jrohel
Copy link
Contributor Author

jrohel commented Sep 17, 2024

We have Package Build / CCache Build (clang), which uses clang for compilation. Unfortunately wrong. As you can see with this PR, the build fails because it uses source code without this PR. In other words, it doesn't test this PR but the older code without it. So if there's a bug in the PR, it will show up later in some other PRs. The cache is working strangely.

@m-blaha m-blaha added this pull request to the merge queue Sep 17, 2024
Merged via the queue into rpm-software-management:main with commit 403bba3 Sep 17, 2024
13 of 20 checks passed
ppisar added a commit to ppisar/dnf5 that referenced this pull request Sep 17, 2024
This patch fixes bugs in sign propagation disovered with
-Wsign-conversion compilar flag and related integer overflows in
dnf5::print_transaction_size_stats(), like this one:

    dnf5/main.cpp: In function ‘void dnf5::print_transaction_size_stats(Context&)’:
    dnf5/main.cpp:785:29: error: conversion to ‘long long unsigned int’ from ‘int64_t’ {aka ‘long int’} may change the sign of the result [-Werror=sign-conversion]
      785 |             in_pkgs_size += pkg_size;
          |                             ^~~~~~~~

There were more ways of fixing, but I choose this one:

Use unsigned integers because an integer overflow for signed types is
undefined in C++. I choose unsigned long long int to follow what
get_download_size() and get_install_size() returns. Otherwise, we would
have to add another check whether the value fits into e.g. uint64_t.
Unless we chose uintmax_t.

Explicitly type-cast counters, with a prior range check, on passing
them to libdnf5::cli::utils::units::to_size(). Otherwise, we would
have to add to_size() for unsigned integers to the public API.
(Actuallly to_size() should have been for unsigned integeres from the
very beginning. Package sizes cannot be negative.)

Not printing the transaction size statistics if an irrepresentible
value occurs. Adding more branches to the already complicated code for
the very improbably corner cases does not make much sense.

(I tried also a different implemeation with keeping int64_t as the
counters, but the code was longer and uglier.)

Related: rpm-software-management#1701
ppisar added a commit to ppisar/dnf5 that referenced this pull request Sep 17, 2024
-Wsign-conversion is by default enabled in Clang with -Wconversion,
but disabled in GCC. Unintented type coercion can misinterpret the
sign as in:

    libdnf5-cli/output/transaction_table.cpp:181:97: error: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
      181 |        P_(" Skipping:        {:4} package\n", " Skipping:        {:4} packages\n", skips), skips)
          |                                                                                    ^~~~~

This would be missed when compiling with GCC, but causing a build
failure with Clang.

This patch brings GCC and Clang compilers in line, both to enable
-Wsign-conversion. However, it disables the warning for SWIG-generated
bindings as the generated code violates the warning many times, like
here for Perl:

    bindings/perl5/libdnf5/CMakeFiles/perl5_advisory.dir/advisoryPERL_wrap.cxx:700:36: error: conversion to ‘long unsigned int’ from ‘long int’ may change the sign of the result [-Werror=sign-conversion]
      700 |   if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
          |                                 ~~~^~~~~~~

Related: rpm-software-management#1701
@ppisar ppisar mentioned this pull request Sep 17, 2024
github-merge-queue bot pushed a commit that referenced this pull request Sep 17, 2024
This patch fixes bugs in sign propagation disovered with
-Wsign-conversion compilar flag and related integer overflows in
dnf5::print_transaction_size_stats(), like this one:

    dnf5/main.cpp: In function ‘void dnf5::print_transaction_size_stats(Context&)’:
    dnf5/main.cpp:785:29: error: conversion to ‘long long unsigned int’ from ‘int64_t’ {aka ‘long int’} may change the sign of the result [-Werror=sign-conversion]
      785 |             in_pkgs_size += pkg_size;
          |                             ^~~~~~~~

There were more ways of fixing, but I choose this one:

Use unsigned integers because an integer overflow for signed types is
undefined in C++. I choose unsigned long long int to follow what
get_download_size() and get_install_size() returns. Otherwise, we would
have to add another check whether the value fits into e.g. uint64_t.
Unless we chose uintmax_t.

Explicitly type-cast counters, with a prior range check, on passing
them to libdnf5::cli::utils::units::to_size(). Otherwise, we would
have to add to_size() for unsigned integers to the public API.
(Actuallly to_size() should have been for unsigned integeres from the
very beginning. Package sizes cannot be negative.)

Not printing the transaction size statistics if an irrepresentible
value occurs. Adding more branches to the already complicated code for
the very improbably corner cases does not make much sense.

(I tried also a different implemeation with keeping int64_t as the
counters, but the code was longer and uglier.)

Related: #1701
github-merge-queue bot pushed a commit that referenced this pull request Sep 17, 2024
-Wsign-conversion is by default enabled in Clang with -Wconversion,
but disabled in GCC. Unintented type coercion can misinterpret the
sign as in:

    libdnf5-cli/output/transaction_table.cpp:181:97: error: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
      181 |        P_(" Skipping:        {:4} package\n", " Skipping:        {:4} packages\n", skips), skips)
          |                                                                                    ^~~~~

This would be missed when compiling with GCC, but causing a build
failure with Clang.

This patch brings GCC and Clang compilers in line, both to enable
-Wsign-conversion. However, it disables the warning for SWIG-generated
bindings as the generated code violates the warning many times, like
here for Perl:

    bindings/perl5/libdnf5/CMakeFiles/perl5_advisory.dir/advisoryPERL_wrap.cxx:700:36: error: conversion to ‘long unsigned int’ from ‘long int’ may change the sign of the result [-Werror=sign-conversion]
      700 |   if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
          |                                 ~~~^~~~~~~

Related: #1701
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants