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

Add a workflow build/test for macOS+Sanitizers #2123

Merged
merged 2 commits into from
Mar 7, 2022

Conversation

mallman
Copy link
Collaborator

@mallman mallman commented Mar 3, 2022

This is a PR build workflow for macOS+sanitizers. As can be seen at #2117 (comment), two test failures are reported in this configuration (for x86_64).

I'm not sure how to test GitHub workflow changes. Let's see if creating this PR activates the workflow in this PR. If it doesn't, I'll look into how to test it independently.

@mallman mallman self-assigned this Mar 3, 2022
@mallman
Copy link
Collaborator Author

mallman commented Mar 3, 2022

It looks like the new build is being picked up and run: https://github.com/Exiv2/exiv2/runs/5413848387?check_suite_focus=true 👍

@codecov
Copy link

codecov bot commented Mar 3, 2022

Codecov Report

Merging #2123 (531de46) into main (30a1609) will decrease coverage by 0.60%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2123      +/-   ##
==========================================
- Coverage   63.98%   63.38%   -0.61%     
==========================================
  Files          97       97              
  Lines       19084    19189     +105     
  Branches     9750     9715      -35     
==========================================
- Hits        12211    12163      -48     
- Misses       4599     4758     +159     
+ Partials     2274     2268       -6     
Impacted Files Coverage Δ
src/easyaccess.cpp 92.85% <0.00%> (-0.84%) ⬇️
src/helper_functions.cpp 60.00% <0.00%> (-40.00%) ⬇️
src/psdimage.cpp 52.92% <0.00%> (-8.83%) ⬇️
src/pngimage.cpp 60.66% <0.00%> (-3.21%) ⬇️
src/pgfimage.cpp 45.00% <0.00%> (-3.10%) ⬇️
src/preview.cpp 47.24% <0.00%> (-2.76%) ⬇️
src/xmpsidecar.cpp 68.18% <0.00%> (-2.47%) ⬇️
include/exiv2/value.hpp 84.97% <0.00%> (-1.60%) ⬇️
src/rafimage.cpp 20.35% <0.00%> (-1.25%) ⬇️
app/exiv2.cpp 59.46% <0.00%> (-1.23%) ⬇️
... and 84 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 30a1609...531de46. Read the comment docs.

@piponazo
Copy link
Collaborator

piponazo commented Mar 4, 2022

Great, now we can see the test which is failing in CI:

======================================================================
FAIL: test_run (github.test_issue_1827.ExposureTimeCastDoubleToLong)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/runner/work/exiv2/exiv2/tests/system_tests.py", line 652, in test_run
    self.compare_stderr(i, command, processed_stderr, stderr)
  File "/Users/runner/work/exiv2/exiv2/tests/system_tests.py", line 773, in compare_stderr
    self._compare_output(
  File "/Users/runner/work/exiv2/exiv2/tests/system_tests.py", line 745, in _compare_output
    self.assertMultiLineEqual(
AssertionError: "/Users/runner/work/exiv2/exiv2/src/types[207 chars]n \n" != ''
- /Users/runner/work/exiv2/exiv2/src/types.cpp:693:45: runtime error: inf is outside the range of representable values of type 'long long'
- SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Users/runner/work/exiv2/exiv2/src/types.cpp:693:45 in 
 : Standard error does not match

It should be possible to check that test and run the exact command from a debugger to discover what is happening there.

@clanmills
Copy link
Collaborator

clanmills commented Mar 4, 2022

I'll look at the x86_64 build and update this report.

The arm64/ASAN build is a disaster zone. We should try to simplify that and report it on Apple Radar. I believe @piponazo changed Exiv2::ExifData to Exiv2::Metadata and the arm64/ASAN build is throwing vptr exceptions. With good fortune, we can isolate/demonstrate the vptr issue with samples/exifprint.cpp.

@mallman
Copy link
Collaborator Author

mallman commented Mar 4, 2022

I don't have the full stack trace in front of me, but I did step through the debugger. The problem in this test is in the code that extracts the ISO speed from the metadata. IIRC without the sanitizer the code that converts a float to an int64_t converts +Inf to the minimum int64_t value. The code that calls it is looking for a value > 0, so without the sanitizer the logic works.

@clanmills
Copy link
Collaborator

clanmills commented Mar 4, 2022

parseInt64() is decoding string "inf" by calling stringTo() which does not set ok to false:

    template<typename T>
    T stringTo(const std::string& s, bool& ok)
    {
        std::istringstream is(s);
        T tmp = T();
        ok = bool(is >> tmp);
        std::string rest;
        is >> std::skipws >> rest;
        if (!rest.empty()) ok = false;  <--  not setting ok = false
        return tmp;
    }

    int64_t parseInt64(const std::string& s, bool& ok)
    {
        int64_t ret = stringTo<int64_t>(s, ok);
        if (ok) return ret;

        auto f = stringTo<float>(s, ok); 
        if (ok) return static_cast<int64_t>(f); <--- explodes

        Rational r = stringTo<Rational>(s, ok);
        if (ok) {
            if (r.second <= 0) {
                ok = false;
                return 0;
            }
            return static_cast<int64_t>(static_cast<float>(r.first) / r.second);
        }
    }

The quick fix is as follows and survives a "full test" (unit_tests, samples, everything) 100% tests passed, 0 tests failed out of 7 with CMakeCache.txt:EXIV2_TEAM_USE_SANITIZERS:BOOL=1:

diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp
index ed3fac48..3b0a1844 100644
--- a/include/exiv2/types.hpp
+++ b/include/exiv2/types.hpp
@@ -501,7 +501,7 @@ namespace Exiv2 {
         ok = bool(is >> tmp);
         std::string rest;
         is >> std::skipws >> rest;
-        if (!rest.empty()) ok = false;
+        if (!rest.empty() || s.find("inf") != std::string::npos) ok = false;
         return tmp;
     }
 

I'm investigating the source of "inf" which isn't in the Exiv2 code base! I suspect a template or std-library call is returning this when performing a short-to-String(). The value of "AutoISO" smells wrong. I'll investigate.

675 rmills@rmillsmm-local:~/gnu/github/exiv2/main/xcode_build $ exiv2 -g iso/i ../test/data/issue_1827_poc.crw 
Exif.CanonSi.AutoISO                         Short       1  2.00187e+06
Exif.CanonSi.ISOSpeed                        Short       1  inf
676 rmills@rmillsmm-local:~/gnu/github/exiv2/main/xcode_build $ exiv2 -pv -g iso/i ../test/data/issue_1827_poc.crw 
0x0001 CanonSi      AutoISO                     Short       1  14632
0x0002 CanonSi      ISOSpeed                    Short       1  57446
677 rmills@rmillsmm-local:~/gnu/github/exiv2/main/xcode_build $

Every tag in Exif.CanonSi looks wrong and I get the same suspicious output on branch 0.27-maintenance.

695 rmills@rmillsmm-local:~/gnu/github/exiv2/main/build $ env DYLD_LIBRARY_PATH=$PWD/lib bin/exiv2 -g CanonSi ../test/data/issue_1827_poc.crw 
Exif.CanonSi.AutoISO                         Short       1  2.00187e+06
Exif.CanonSi.ISOSpeed                        Short       1  inf
Exif.CanonSi.MeasuredEV                      Short       1  749.31
Exif.CanonSi.TargetAperture                  Short       1  57649
Exif.CanonSi.TargetShutterSpeed              Short       1  1 s
Exif.CanonSi.ExposureCompensation            Short       1  147
Exif.CanonSi.WhiteBalance                    Short       1  (21327)
Exif.CanonSi.SlowShutter                     Short       1  (54101)
Exif.CanonSi.Sequence                        Short       1  28624
Exif.CanonSi.OpticalZoomCode                 Short       1  29367
Exif.CanonSi.CameraTemperature               Short       1  19286 °C
Exif.CanonSi.FlashGuideNumber                Short       1  734
Exif.CanonSi.AFPointUsed                     Short       1  2 focus points;  used
Exif.CanonSi.FlashBias                       Short       1  (63793)
Exif.CanonSi.AutoExposureBracketing          Short       1  (37805)
Exif.CanonSi.AEBBracketValue                 Short       1  44174
Exif.CanonSi.ControlMode                     Short       1  20743
Exif.CanonSi.SubjectDistance                 Short       1  230.21 m
Exif.CanonSi.ApertureValue                   Short       1  55444
Exif.CanonSi.ShutterSpeedValue               Short       1  1 s
Exif.CanonSi.MeasuredEV2                     Short       1  7023.00
Exif.CanonSi.BulbDuration                    Short       1  4035
Exif.CanonSi.CameraType                      Short       1  (54067)
696 rmills@rmillsmm-local:~/gnu/github/exiv2/main/build $ 

It appears that the metadata decoder is accessing the wrong bytes in this file.

@clanmills
Copy link
Collaborator

I'll wait for feedback from @mallman about my proposed fix before discovering how/why string "inf" arrives in parseInt64().

I've investigated the file structure. exiv2, ExifTool and tvisitor all concur about the location of CanonSi (Shot Info) in the file. Therefore I will not undertake further study of the file.

$ exiftool ../test/data/issue_1827_poc.crw | grep -e "Camera Type" -e "Focus Distance Upper"
Focus Distance Upper            : 230.21 m
Camera Type                     : Unknown (-11469)
$ exiv2 -g CameraType -g SubjectDistance ../test/data/issue_1827_poc.crw 
Exif.CanonSi.SubjectDistance                 Short       1  230.21 m
Exif.CanonSi.CameraType                      Short       1  (54067) == 0xffff-11469
$ tvisitor -pRU ../test/data/issue_1827_poc.crw  | grep ShotInfo
       0x102a | HW   |   42 | Exif.CRW.CanonShotInfo           |     54 |     12 | D$.9f..]1..m._OSU..o.r.u.K.[X$1..... +++
$ exiftool -v5 ../test/data/issue_1827_poc.crw | grep -i -A 2 ShotInfo
  | | | 3)  CanonShotInfo (SubDirectory) -->
  | | |     - Tag 0x102a (54 bytes, int16u[27]):
  | | |         13ec: 44 24 28 39 66 e0 0a 5d 31 e1 92 6d 93 00 4f 53 [D$.9f..]1..m..OS]
$ 

@clanmills
Copy link
Collaborator

It's amazing the stuff you find at the bottom of the swamp:

    std::ostream& CanonMakerNote::printSi0x0002(std::ostream& os,
                                                const Value& value,
                                                const ExifData*)
    {
        std::ios::fmtflags f( os.flags() );
        if (   value.typeId() == unsignedShort
            && value.count() > 0) {
            // Ported from Exiftool by Will Stokes
            os << std::exp(canonEv(value.toInt64()) * std::log(2.0F)) * 100.0F / 32.0F;
        }
        os.flags(f);
        return os;
    }

I've never heard of Wilf Stokes and even less idea what this code does. This code can write "inf". Proof?

.../main/build $ git diff ../src/canonmn_int.cpp 
diff --git a/src/canonmn_int.cpp b/src/canonmn_int.cpp
index 879a449d..b626e472 100644
--- a/src/canonmn_int.cpp
+++ b/src/canonmn_int.cpp
@@ -2877,7 +2877,7 @@ namespace Exiv2 {
         if (   value.typeId() == unsignedShort
             && value.count() > 0) {
             // Ported from Exiftool by Will Stokes
-            os << std::exp(canonEv(value.toInt64()) * std::log(2.0F)) * 100.0F / 32.0F;
+            os << "wilf was here" ; // std::exp(canonEv(value.toInt64()) * std::log(2.0F)) * 100.0F / 32.0F;
         }
         os.flags(f);
         return os;
.../main/build $ env DYLD_LIBRARY_PATH=$PWD/lib bin/exiv2 -pa -g iso/i ../test/data/issue_1827_poc.crw 
Exif.CanonSi.AutoISO                         Short       1  2.00187e+06
Exif.CanonSi.ISOSpeed                        Short       1  wilf was here
.../main/build $ 

The command-line in the test is $ exiv2 test/data/issue_1827_poc.crw which uses the "EasyAccess API". The concept of the "EasyAccess" API is really good. It understands how to cascade though metadata keys on behalf of application code. Most of the code in easyaccess.cpp are lists of keys to be searched. The following function is not simple at all:

ExifData::const_iterator isoSpeed(const ExifData& ed)

It does an amazing dance of writing the metadata into a stream and then parsing it again. Why? No idea!

However, we now have answers to two questions:

  1. What's the origin of the string "inf" ? Answer "Wilf Stokes".
  2. Why are we converting this string to a number? Answer: src/easyaccess.cpp ExifData::const_iterator isoSpeed(const ExifData& ed). There's an easy fix:
index 0c851304..e41b7e6e 100644
--- a/src/easyaccess.cpp
+++ b/src/easyaccess.cpp
@@ -113,6 +113,7 @@ namespace Exiv2 {
             std::ostringstream os;
             md->write(os, &ed);
             bool ok = false;
+            if ( os.str().find("inf") != std::string::npos ) break;
             iso_val = parseInt64(os.str(), ok);
             if (ok && iso_val > 0) break;
             while (strcmp(keys[idx++], md->key().c_str()) != 0 && idx < cnt) {}

This fix is "less aggressive" in that it's in the exiv2 application and not in the heart of the library. However, it's isolated to the single case of reporting weird ISOSpeed and nothing else.

The immediate issue is to get exiv2/ASAN/macOS to pass the test suite. Two patches have been proposed:

  1. The low-level change to T stringTo(const std::string& s, bool& ok)
  2. The application level toExifData::const_iterator isoSpeed(const ExifData& ed)

@piponazo, @kevinbackhouse . Could you discuss this? I haven't really understood what the rest does. It's likely that there's a better way to test if the input string was not totally consumed. We shouldn't need to test inf, the function should return ok = false for any input that is not totally consumed.

I prefer the low-level change because it solves the ISOSpeed issue and probably reinforces other parts of the exiv2 application.


Damn Difficult Followup Question

Why do we not see this on other platforms? Maybe apple/clang library issue? In the code that I replaced with "wilf was here", we could investigate how the following performs on other platforms:

std::cout << std::exp(canonEv(value.toInt64()) * std::log(2.0F)) * 100.0F / 32.0F;

I'm not offering to undertake such an investigation. To really do justice to this, we should investigate everything contributed by Wilf and the EasyAccess API. That's not a criticism of Wilf. I believe that code's been there for about 15 years and ExifTool may work in a different way today.

@clanmills
Copy link
Collaborator

clanmills commented Mar 4, 2022

The stringTo() template accepts "inf" as valid (and +Inf, and -Inf) and possibly other values. The stringTo() template is good and should not be modified.

The issue is caused by the application code which writes and then parses. That's not working correctly when the string is "inf".

             md->write(os, &ed);
             bool ok = false;
             iso_val = parseInt64(os.str(), ok);

This needs more time which I don't want to give. The second patch enables the test suite to run on macOS.

1165 rmills@rmillsmm-local:~/temp $ cat stringTo.cpp 
#include <iostream>
#include <string>
#include <sstream>

int stringToInt(const std::string& s, bool& ok)
{
    std::istringstream is(s);
    int tmp ;
    ok = (is >> tmp) ? true : false;
    std::string rest;
    is >> std::skipws >> rest;
    if (!rest.empty()) ok = false;
    return tmp;
}

float stringToFloat(const std::string& s, bool& ok)
{
    std::istringstream is(s);
    float tmp ;
    ok = (is >> tmp) ? true : false;
    std::string rest;
    is >> std::skipws >> rest;
    if (!rest.empty()) ok = false;
    return tmp;
}

int main(int argc, const char* argv[])
{
    for ( int a = 1 ; a < argc ; a++ ) {
        std::string s(argv[a]);
        bool        oki,okf   ;
        int   i = stringToInt(s,oki);
        float f = stringToFloat(s,okf);
        std::cout << a << " : "     << s
                       << " = "     << i 
                       << " ok = "  << oki
                       << " = "     << f 
                       << " ok = "  << okf
                       << std::endl;
    }
    return 0 ;
}
1166 rmills@rmillsmm-local:~/temp $ ./stringTo 10 20 inf foo X +inf
1 : 10 = 10 ok = 1 = 10 ok = 1
2 : 20 = 20 ok = 1 = 20 ok = 1
3 : inf = 0 ok = 0 = inf ok = 1
4 : foo = 0 ok = 0 = 0 ok = 0
5 : X = 0 ok = 0 = 0 ok = 0
6 : +inf = 0 ok = 0 = inf ok = 1
1167 rmills@rmillsmm-local:~/temp $

@postscript-dev
Copy link
Collaborator

@clanmills:

I'm not offering to undertake such an investigation. To really do justice to this, we should investigate everything contributed by Wilf and the EasyAccess API.

I agree, the EasyAccess API needs to be reviewed at some point.

While working on the manpage, I found that some of the tags listed in isoSpeed() don't work correctly. In the keys array, there are problems with Exif.MinoltaCsNew.ISOSetting, Exif.MinoltaCsOld.ISOSetting, Exif.Sony1Cs.ISOSetting, Exif.Sony2Cs.ISOSetting, Exif.Sony1Cs2.ISOSetting, Exif.Sony2Cs2.ISOSetting and Exif.Olympus.ISOSpeed. The reason is that the tags' values are stored in an encoded format and we don't have pretty printing functions to do the decoding - the formulas are available in the ExifTool source code.

When the EasyAccess API is reviewed, we may find other similar problems. However, as many new tags have been added to Exiv2, we may also find that some of them can be added to the EasyAccess lists.

At the moment, I have too many other projects to commit to a full review of the EasyAccess API.

@clanmills
Copy link
Collaborator

clanmills commented Mar 4, 2022

@postscript-dev For sure, Peter, nobody has the time to get sucked into the EasyAccess API. @kmilos and I did some work on EasyAccess in 2020 and I documented it in the Wiki: https://github.com/Exiv2/exiv2/wiki/EasyAccess-API. I don't recall how we became interested in that in 2020. It's been there for a long time with almost no issues.

In order to get the macOS/ASAN/x86_64 build to pass the test suite, I think we should adopt the change discussed here: #2123 (comment). We should not touch the good code in the stringTo() template.

@piponazo
Copy link
Collaborator

piponazo commented Mar 5, 2022

Thanks @clanmills for your investigation. I might take this challenge in the next days, it looks like an interesting one. I just hope I can reproduce some of the issues in other platforms. Otherwise, I might ask you access again to your mac PC 😉

@clanmills
Copy link
Collaborator

clanmills commented Mar 5, 2022

For sure you are welcome to use the MacMini. You can access it using the IP address (email me to get that).

I think there are at least three different issues:

  1. Getting the macOS/ASAN/x86_64 to build/test successfully.
  2. How/why does the mac generate the string "inf".
  3. How are ISO values stored and processed.

The first is easy.

index 0c851304..e41b7e6e 100644
--- a/src/easyaccess.cpp
+++ b/src/easyaccess.cpp
@@ -113,6 +113,7 @@ namespace Exiv2 {
             std::ostringstream os;
             md->write(os, &ed);
             bool ok = false;
+            if ( os.str().find("inf") != std::string::npos ) break;
             iso_val = parseInt64(os.str(), ok);
             if (ok && iso_val > 0) break;
             while (strcmp(keys[idx++], md->key().c_str()) != 0 && idx < cnt) {}

@mallman. This fix only impacts EasyAccess/ISO. Can you update the PR with this change, please?

The "inf" matter is indeed interesting and can probably be understood in a couple of days. I suspect the code is good and we only need changes to the ISO pretty printer and some Wiki documentation. If changes are needed, they should be in a different PR. Let's get the macOS/ASAN/x86_64 CI into production.

ISO storage looks like a black hole that could consume a huge amount of time. The code has been there for a long time and nobody has complained. Until solid bugs are reported by users, we should leave this alone.

@clanmills
Copy link
Collaborator

1237 rmills@rmillsmm-local:~/temp $ cat stringTo.cpp 
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>
#include <cfenv>

int stringToInt(const std::string& s, bool& ok)
{
    std::istringstream is(s);
    int tmp ;
    ok = (is >> tmp) ? true : false;
    std::string rest;
    is >> std::skipws >> rest;
    if (!rest.empty()) ok = false;
    return tmp;
}

float stringToFloat(const std::string& s, bool& ok)
{
    std::istringstream is(s);
    float tmp ;
    ok = (is >> tmp) ? true : false;
    std::string rest;
    is >> std::skipws >> rest;
    if (!rest.empty()) ok = false;
    return tmp;
}

int64_t fib(uint64_t n)
{
    return n <= 1 ? n : fib(n-1) + fib(n-2);
}

float canonEv(int64_t val)
{
    // temporarily remove sign
    int sign = 1;
    if (val < 0) {
        sign = -1;
        val = -val;
    }
    // remove fraction
    const auto remainder = val & 0x1f;
    val -= remainder;
    float frac = static_cast<float>(remainder);
    // convert 1/3 (0x0c) and 2/3 (0x14) codes
    if (frac == 0x0c) {
        frac = 32.0F / 3;
    }
    else if (frac == 0x14) {
        frac = 64.0F / 3;
    }
    else if ((val == 160) && (frac == 0x08)) { // for Sigma f/6.3 lenses that report f/6.2 to camera
        frac = 30.0F / 3;
    }
    return sign * (val + frac) / 32.0F;
}

float wilf(uint64_t value)
{
    return std::exp(canonEv(value) * std::log(2.0F)) * 100.0F / 32.0F;
}

int main(int argc, const char* argv[])
{
    if ( argc == 1 ) {
        for ( uint64_t a = 0 ; a < 50 ; a++ ) {
            std::cout << a*100 << " -> " << wilf(a*100) << std::endl;
        }
    } else for ( int a = 1 ; a < argc ; a++ ) {
        std::string s(argv[a]);
        bool        oki,okf   ;
        int   i = stringToInt(s,oki);
        float f = stringToFloat(s,okf);
        std::cout << a << " : "     << s
                       << " = "     << i 
                       << " ok = "  << oki
                       << " = "     << f 
                       << " ok = "  << okf
                       << std::endl;
    }
    return 0 ;
}
1238 rmills@rmillsmm-local:~/temp $ make -B stringTo
c++     stringTo.cpp   -o stringTo
stringTo.cpp:46:11: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
    const auto remainder = val & 0x1f;
          ^
1 warning generated.
1239 rmills@rmillsmm-local:~/temp $ ./stringTo 
0 -> 3.125
100 -> 27.2627
200 -> 237.841
300 -> 2015.87
400 -> 18101.9
500 -> 162550
600 -> 1.37772e+06
700 -> 1.20194e+07
800 -> 1.04858e+08
900 -> 9.14784e+08
1000 -> 7.98063e+09
1100 -> 6.76414e+10
1200 -> 6.074e+11
1300 -> 5.45427e+12
1400 -> 4.62288e+13
1500 -> 4.03303e+14
1600 -> 3.51844e+15
1700 -> 3.06951e+16
1800 -> 2.67786e+17
1900 -> 2.26967e+18
2000 -> 2.03809e+19
2100 -> 1.83014e+20
2200 -> 1.55118e+21
2300 -> 1.35326e+22
2400 -> 1.18059e+23
2500 -> 1.02995e+24
2600 -> 8.98538e+24
2700 -> 7.61577e+25
2800 -> 6.83872e+26
2900 -> 6.14096e+27
3000 -> 5.20491e+28
3100 -> 4.5408e+29
3200 -> 3.96142e+30
3300 -> 3.45596e+31
3400 -> 3.015e+32
3500 -> 2.55543e+33
3600 -> 2.29469e+34
3700 -> 2.06055e+35
3800 -> 1.74647e+36
3900 -> inf
4000 -> inf
4100 -> inf
4200 -> inf
4300 -> inf
4400 -> inf
4500 -> inf
4600 -> inf
4700 -> inf
4800 -> inf
4900 -> inf
1240 rmills@rmillsmm-local:~/temp $ 

@mallman
Copy link
Collaborator Author

mallman commented Mar 5, 2022

I think the codecov failure was spurious. I re-ran it and it succeeded.

@mallman
Copy link
Collaborator Author

mallman commented Mar 5, 2022

@clanmills I've pushed a commit with the change you requested.

@clanmills
Copy link
Collaborator

Better. It's succeeded on macOS. Can you have a look at the two failures, please? They are probably either benign or incomprehensible and we can merge.

@mallman
Copy link
Collaborator Author

mallman commented Mar 6, 2022

I re-ran the codecov check and it succeeded. The other check fails because of some kind of configuration issue unrelated to this PR. I think it's safe to merge this PR.

@clanmills
Copy link
Collaborator

I concur. Can you invite Luis @piponazo to review and approve. I believe you have permission to merge.

I've proposed a Team Exiv2 convention: The author of a PR is the person to merge. A few weeks ago, I merged one of Luis' PRs and he wasn't finished. Apple have a house convention that the person who opens an issue is the person to close it. It's a good way of saying "I'm satisfied.".

@mallman
Copy link
Collaborator Author

mallman commented Mar 6, 2022

I've proposed a Team Exiv2 convention: The author of a PR is the person to merge.

Sounds like a good idea to me.

Copy link
Collaborator

@piponazo piponazo left a comment

Choose a reason for hiding this comment

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

This looks good great to me! Thank you very much for the contribution.

The 2 checks that are failing are indeed spurious.

Let me know if you can merge, otherwise I will do it 😉

@mallman mallman merged commit 7ed4303 into Exiv2:main Mar 7, 2022
@mallman mallman deleted the macSanitizersWorkflowBuild branch March 7, 2022 20:36
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.

4 participants