• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mavlink / MAVSDK / 11452150858

22 Oct 2024 02:32AM UTC coverage: 37.403% (+0.02%) from 37.381%
11452150858

push

github

web-flow
camera_server: prevent double ack+message (#2430)

It turns out we were sending the ack and message for storage information
as well as capture status twice, once directly in the request handler
callback, and once the MAVSDK user would call the respond function.

We should only call it in the respond function, not in the callback.

11105 of 29690 relevant lines covered (37.4%)

255.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/mavsdk/core/inflate_lzma.cpp
1

2
#include "inflate_lzma.h"
3

4
#include <cstdio>
5
#include <cstring>
6
#include <cerrno>
7
#define LZMA_API_STATIC
8
#include <lzma.h>
9

10
// The following code is from the liblzma example:
11
// https://github.com/tukaani-project/xz/blob/master/doc/examples/02_decompress.c
12
static bool init_decoder(lzma_stream* strm)
×
13
{
14
    // Initialize a .xz decoder. The decoder supports a memory usage limit
15
    // and a set of flags.
16
    //
17
    // The memory usage of the decompressor depends on the settings used
18
    // to compress a .xz file. It can vary from less than a megabyte to
19
    // a few gigabytes, but in practice (at least for now) it rarely
20
    // exceeds 65 MiB because that's how much memory is required to
21
    // decompress files created with "xz -9". Settings requiring more
22
    // memory take extra effort to use and don't (at least for now)
23
    // provide significantly better compression in most cases.
24
    //
25
    // Memory usage limit is useful if it is important that the
26
    // decompressor won't consume gigabytes of memory. The need
27
    // for limiting depends on the application. In this example,
28
    // no memory usage limiting is used. This is done by setting
29
    // the limit to UINT64_MAX.
30
    //
31
    // The .xz format allows concatenating compressed files as is:
32
    //
33
    //     echo foo | xz > foobar.xz
34
    //     echo bar | xz >> foobar.xz
35
    //
36
    // When decompressing normal standalone .xz files, LZMA_CONCATENATED
37
    // should always be used to support decompression of concatenated
38
    // .xz files. If LZMA_CONCATENATED isn't used, the decoder will stop
39
    // after the first .xz stream. This can be useful when .xz data has
40
    // been embedded inside another file format.
41
    //
42
    // Flags other than LZMA_CONCATENATED are supported too, and can
43
    // be combined with bitwise-or. See lzma/container.h
44
    // (src/liblzma/api/lzma/container.h in the source package or e.g.
45
    // /usr/include/lzma/container.h depending on the install prefix)
46
    // for details.
47
    lzma_ret ret = lzma_stream_decoder(strm, UINT64_MAX, LZMA_CONCATENATED);
×
48

49
    // Return successfully if the initialization went fine.
50
    if (ret == LZMA_OK)
×
51
        return true;
×
52

53
    // Something went wrong. The possible errors are documented in
54
    // lzma/container.h (src/liblzma/api/lzma/container.h in the source
55
    // package or e.g. /usr/include/lzma/container.h depending on the
56
    // install prefix).
57
    //
58
    // Note that LZMA_MEMLIMIT_ERROR is never possible here. If you
59
    // specify a very tiny limit, the error will be delayed until
60
    // the first headers have been parsed by a call to lzma_code().
61
    const char* msg;
62
    switch (ret) {
×
63
        case LZMA_MEM_ERROR:
×
64
            msg = "Memory allocation failed";
×
65
            break;
×
66

67
        case LZMA_OPTIONS_ERROR:
×
68
            msg = "Unsupported decompressor flags";
×
69
            break;
×
70

71
        default:
×
72
            // This is most likely LZMA_PROG_ERROR indicating a bug in
73
            // this program or in liblzma. It is inconvenient to have a
74
            // separate error message for errors that should be impossible
75
            // to occur, but knowing the error code is important for
76
            // debugging. That's why it is good to print the error code
77
            // at least when there is no good error message to show.
78
            msg = "Unknown error, possibly a bug";
×
79
            break;
×
80
    }
81

82
    fprintf(stderr, "Error initializing the decoder: %s (error code %u)\n", msg, ret);
×
83
    return false;
×
84
}
85

86
static bool decompress(lzma_stream* strm, const char* inname, FILE* infile, FILE* outfile)
×
87
{
88
    // When LZMA_CONCATENATED flag was used when initializing the decoder,
89
    // we need to tell lzma_code() when there will be no more input.
90
    // This is done by setting action to LZMA_FINISH instead of LZMA_RUN
91
    // in the same way as it is done when encoding.
92
    //
93
    // When LZMA_CONCATENATED isn't used, there is no need to use
94
    // LZMA_FINISH to tell when all the input has been read, but it
95
    // is still OK to use it if you want. When LZMA_CONCATENATED isn't
96
    // used, the decoder will stop after the first .xz stream. In that
97
    // case some unused data may be left in strm->next_in.
98
    lzma_action action = LZMA_RUN;
×
99

100
    uint8_t inbuf[BUFSIZ];
×
101
    uint8_t outbuf[BUFSIZ];
×
102

103
    strm->next_in = nullptr;
×
104
    strm->avail_in = 0;
×
105
    strm->next_out = outbuf;
×
106
    strm->avail_out = sizeof(outbuf);
×
107

108
    while (true) {
109
        if (strm->avail_in == 0 && !feof(infile)) {
×
110
            strm->next_in = inbuf;
×
111
            strm->avail_in = fread(inbuf, 1, sizeof(inbuf), infile);
×
112

113
            if (ferror(infile)) {
×
114
                fprintf(stderr, "%s: Read error: %s\n", inname, strerror(errno));
×
115
                // SonarCloud: Address of stack memory associated with local
116
                // variable 'inbuf' is still referred to by the stack variable
117
                // 'strm' upon returning to the caller. This will be a
118
                // dangling reference
119
                // Fixed by setting to nullptr.
120
                strm->next_in = nullptr;
×
121
                strm->avail_in = 0;
×
122
                strm->next_out = nullptr;
×
123
                strm->avail_out = 0;
×
124
                return false;
×
125
            }
126

127
            // Once the end of the input file has been reached,
128
            // we need to tell lzma_code() that no more input
129
            // will be coming. As said before, this isn't required
130
            // if the LZMA_CONCATENATED flag isn't used when
131
            // initializing the decoder.
132
            if (feof(infile))
×
133
                action = LZMA_FINISH;
×
134
        }
135

136
        lzma_ret ret = lzma_code(strm, action);
×
137

138
        if (strm->avail_out == 0 || ret == LZMA_STREAM_END) {
×
139
            size_t write_size = sizeof(outbuf) - strm->avail_out;
×
140

141
            if (fwrite(outbuf, 1, write_size, outfile) != write_size) {
×
142
                fprintf(stderr, "Write error: %s\n", strerror(errno));
×
143
                strm->next_in = nullptr;
×
144
                strm->avail_in = 0;
×
145
                strm->next_out = nullptr;
×
146
                strm->avail_out = 0;
×
147
                return false;
×
148
            }
149

150
            strm->next_out = outbuf;
×
151
            strm->avail_out = sizeof(outbuf);
×
152
        }
153

154
        if (ret != LZMA_OK) {
×
155
            // Once everything has been decoded successfully, the
156
            // return value of lzma_code() will be LZMA_STREAM_END.
157
            //
158
            // It is important to check for LZMA_STREAM_END. Do not
159
            // assume that getting ret != LZMA_OK would mean that
160
            // everything has gone well or that when you aren't
161
            // getting more output it must have successfully
162
            // decoded everything.
163
            if (ret == LZMA_STREAM_END) {
×
164
                strm->next_in = nullptr;
×
165
                strm->avail_in = 0;
×
166
                strm->next_out = nullptr;
×
167
                strm->avail_out = 0;
×
168
                return true;
×
169
            }
170

171
            // It's not LZMA_OK nor LZMA_STREAM_END,
172
            // so it must be an error code. See lzma/base.h
173
            // (src/liblzma/api/lzma/base.h in the source package
174
            // or e.g. /usr/include/lzma/base.h depending on the
175
            // install prefix) for the list and documentation of
176
            // possible values. Many values listen in lzma_ret
177
            // enumeration aren't possible in this example, but
178
            // can be made possible by enabling memory usage limit
179
            // or adding flags to the decoder initialization.
180
            const char* msg;
181
            switch (ret) {
×
182
                case LZMA_MEM_ERROR:
×
183
                    msg = "Memory allocation failed";
×
184
                    break;
×
185

186
                case LZMA_FORMAT_ERROR:
×
187
                    // .xz magic bytes weren't found.
188
                    msg = "The input is not in the .xz format";
×
189
                    break;
×
190

191
                case LZMA_OPTIONS_ERROR:
×
192
                    // For example, the headers specify a filter
193
                    // that isn't supported by this liblzma
194
                    // version (or it hasn't been enabled when
195
                    // building liblzma, but no-one sane does
196
                    // that unless building liblzma for an
197
                    // embedded system). Upgrading to a newer
198
                    // liblzma might help.
199
                    //
200
                    // Note that it is unlikely that the file has
201
                    // accidentally became corrupt if you get this
202
                    // error. The integrity of the .xz headers is
203
                    // always verified with a CRC32, so
204
                    // unintentionally corrupt files can be
205
                    // distinguished from unsupported files.
206
                    msg = "Unsupported compression options";
×
207
                    break;
×
208

209
                case LZMA_DATA_ERROR:
×
210
                    msg = "Compressed file is corrupt";
×
211
                    break;
×
212

213
                case LZMA_BUF_ERROR:
×
214
                    // Typically this error means that a valid
215
                    // file has got truncated, but it might also
216
                    // be a damaged part in the file that makes
217
                    // the decoder think the file is truncated.
218
                    // If you prefer, you can use the same error
219
                    // message for this as for LZMA_DATA_ERROR.
220
                    msg = "Compressed file is truncated or "
×
221
                          "otherwise corrupt";
222
                    break;
×
223

224
                default:
×
225
                    // This is most likely LZMA_PROG_ERROR.
226
                    msg = "Unknown error, possibly a bug";
×
227
                    break;
×
228
            }
229

230
            fprintf(
×
231
                stderr,
232
                "%s: Decoder error: "
233
                "%s (error code %u)\n",
234
                inname,
235
                msg,
236
                ret);
237

238
            strm->next_in = nullptr;
×
239
            strm->avail_in = 0;
×
240
            strm->next_out = nullptr;
×
241
            strm->avail_out = 0;
×
242
            return false;
×
243
        }
244
    }
×
245
}
246

247
bool InflateLZMA::inflateLZMAFile(
×
248
    const std::filesystem::path& lzma_filename, const std::filesystem::path& decompressed_filename)
249
{
250
    lzma_stream strm = LZMA_STREAM_INIT;
×
251

252
    if (!init_decoder(&strm)) {
×
253
        // Decoder initialization failed. There's no point
254
        // to retry it so we need to exit.
255
        return false;
×
256
    }
257

258
    FILE* infile = fopen(lzma_filename.string().c_str(), "rb");
×
259

260
    if (infile == nullptr) {
×
261
        fprintf(
×
262
            stderr,
263
            "%s: Error opening the "
264
            "input file: %s\n",
265
            lzma_filename.string().c_str(),
×
266
            strerror(errno));
×
267
        return false;
×
268
    }
269

270
    FILE* outfile = fopen(decompressed_filename.string().c_str(), "wb");
×
271

272
    if (outfile == nullptr) {
×
273
        fprintf(
×
274
            stderr,
275
            "%s: Error opening the "
276
            "output file: %s\n",
277
            decompressed_filename.string().c_str(),
×
278
            strerror(errno));
×
279
        fclose(infile);
×
280
        return false;
×
281
    }
282

283
    const bool success = decompress(&strm, lzma_filename.string().c_str(), infile, outfile);
×
284
    fclose(infile);
×
285
    fclose(outfile);
×
286

287
    lzma_end(&strm);
×
288

289
    return success;
×
290
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc