X-Git-Url: https://git.efficios.com/?a=blobdiff_plain;f=src%2Fplugins%2Fctf%2Fcommon%2Fmetadata%2Fdecoder-packetized-file-stream-to-buf.cpp;h=3b7224abd526cfafc74ce712a585ec756cedd517;hb=4164020e790fa6c0700715936b40a3fa46df479e;hp=d0cd030432c5f96e92fe150ad5f7ef72b8b6b483;hpb=087cd0f57f0f7d815a609a4e041d1200f380e4aa;p=babeltrace.git diff --git a/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.cpp b/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.cpp index d0cd0304..3b7224ab 100644 --- a/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.cpp +++ b/src/plugins/ctf/common/metadata/decoder-packetized-file-stream-to-buf.cpp @@ -4,10 +4,10 @@ * Copyright 2016-2017 Philippe Proulx */ -#define BT_COMP_LOG_SELF_COMP self_comp +#define BT_COMP_LOG_SELF_COMP self_comp #define BT_COMP_LOG_SELF_COMP_CLASS self_comp_class -#define BT_LOG_OUTPUT_LEVEL log_level -#define BT_LOG_TAG "PLUGIN/CTF/META/DECODER-DECODE-PACKET" +#define BT_LOG_OUTPUT_LEVEL log_level +#define BT_LOG_TAG "PLUGIN/CTF/META/DECODER-DECODE-PACKET" #include "logging/comp-logging.h" #include "decoder-packetized-file-stream-to-buf.hpp" @@ -29,244 +29,245 @@ #include "scanner.hpp" #include "logging.hpp" -#define TSDL_MAGIC 0x75d11d57 +#define TSDL_MAGIC 0x75d11d57 -struct ctf_metadata_decoder { - struct ctf_visitor_generate_ir *visitor; - bt_uuid_t uuid; - bool is_uuid_set; - int bo; - struct ctf_metadata_decoder_config config; +struct ctf_metadata_decoder +{ + struct ctf_visitor_generate_ir *visitor; + bt_uuid_t uuid; + bool is_uuid_set; + int bo; + struct ctf_metadata_decoder_config config; }; -struct packet_header { - uint32_t magic; - bt_uuid_t uuid; - uint32_t checksum; - uint32_t content_size; - uint32_t packet_size; - uint8_t compression_scheme; - uint8_t encryption_scheme; - uint8_t checksum_scheme; - uint8_t major; - uint8_t minor; +struct packet_header +{ + uint32_t magic; + bt_uuid_t uuid; + uint32_t checksum; + uint32_t content_size; + uint32_t packet_size; + uint8_t compression_scheme; + uint8_t encryption_scheme; + uint8_t checksum_scheme; + uint8_t major; + uint8_t minor; } __attribute__((__packed__)); -static -int decode_packet(FILE *in_fp, FILE *out_fp, - int byte_order, bool *is_uuid_set, uint8_t *uuid, - bt_logging_level log_level, bt_self_component *self_comp, - bt_self_component_class *self_comp_class) +static int decode_packet(FILE *in_fp, FILE *out_fp, int byte_order, bool *is_uuid_set, + uint8_t *uuid, bt_logging_level log_level, bt_self_component *self_comp, + bt_self_component_class *self_comp_class) { - struct packet_header header; - size_t readlen, writelen, toread; - uint8_t buf[512 + 1]; /* + 1 for debug-mode \0 */ - int ret = 0; - const long offset = ftell(in_fp); - - if (offset < 0) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, - "Failed to get current metadata file position", - "."); - goto error; - } - BT_COMP_LOGD("Decoding metadata packet: offset=%ld", offset); - readlen = fread(&header, sizeof(header), 1, in_fp); - if (feof(in_fp) != 0) { - BT_COMP_LOGI("Reached end of file: offset=%ld", ftell(in_fp)); - goto end; - } - if (readlen < 1) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode metadata packet: offset=%ld", offset); - goto error; - } - - if (byte_order != BYTE_ORDER) { - header.magic = GUINT32_SWAP_LE_BE(header.magic); - header.checksum = GUINT32_SWAP_LE_BE(header.checksum); - header.content_size = GUINT32_SWAP_LE_BE(header.content_size); - header.packet_size = GUINT32_SWAP_LE_BE(header.packet_size); - } - - if (header.compression_scheme) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Metadata packet compression is not supported as of this version: " - "compression-scheme=%u, offset=%ld", - (unsigned int) header.compression_scheme, offset); - goto error; - } - - if (header.encryption_scheme) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Metadata packet encryption is not supported as of this version: " - "encryption-scheme=%u, offset=%ld", - (unsigned int) header.encryption_scheme, offset); - goto error; - } - - if (header.checksum || header.checksum_scheme) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Metadata packet checksum verification is not supported as of this version: " - "checksum-scheme=%u, checksum=%x, offset=%ld", - (unsigned int) header.checksum_scheme, header.checksum, - offset); - goto error; - } - - if (!ctf_metadata_decoder_is_packet_version_valid(header.major, - header.minor)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid metadata packet version: " - "version=%u.%u, offset=%ld", - header.major, header.minor, offset); - goto error; - } - - /* Set expected trace UUID if not set; otherwise validate it */ - if (is_uuid_set) { - if (!*is_uuid_set) { - bt_uuid_copy(uuid, header.uuid); - *is_uuid_set = true; - } else if (bt_uuid_compare(header.uuid, uuid)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Metadata UUID mismatch between packets of the same stream: " - "packet-uuid=\"" BT_UUID_FMT "\", " - "expected-uuid=\"" BT_UUID_FMT "\", " - "offset=%ld", - BT_UUID_FMT_VALUES(header.uuid), - BT_UUID_FMT_VALUES(uuid), - offset); - goto error; - } - } - - if ((header.content_size / CHAR_BIT) < sizeof(header)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Bad metadata packet content size: content-size=%u, " - "offset=%ld", header.content_size, offset); - goto error; - } - - toread = header.content_size / CHAR_BIT - sizeof(header); - - for (;;) { - size_t loop_read; - - loop_read = MIN(sizeof(buf) - 1, toread); - readlen = fread(buf, sizeof(uint8_t), loop_read, in_fp); - if (ferror(in_fp)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot read metadata packet buffer: " - "offset=%ld, read-size=%zu", - ftell(in_fp), loop_read); - goto error; - } - if (readlen > loop_read) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("fread returned more byte than expected: " - "read-size-asked=%zu, read-size-returned=%zu", - loop_read, readlen); - goto error; - } - - writelen = fwrite(buf, sizeof(uint8_t), readlen, out_fp); - if (writelen < readlen || ferror(out_fp)) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot write decoded metadata text to buffer: " - "read-offset=%ld, write-size=%zu", - ftell(in_fp), readlen); - goto error; - } - - toread -= readlen; - if (toread == 0) { - int fseek_ret; - - /* Read leftover padding */ - toread = (header.packet_size - header.content_size) / - CHAR_BIT; - fseek_ret = fseek(in_fp, toread, SEEK_CUR); - if (fseek_ret < 0) { - BT_COMP_LOGW_STR("Missing padding at the end of the metadata stream."); - } - break; - } - } - - goto end; + struct packet_header header; + size_t readlen, writelen, toread; + uint8_t buf[512 + 1]; /* + 1 for debug-mode \0 */ + int ret = 0; + const long offset = ftell(in_fp); + + if (offset < 0) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, + "Failed to get current metadata file position", "."); + goto error; + } + BT_COMP_LOGD("Decoding metadata packet: offset=%ld", offset); + readlen = fread(&header, sizeof(header), 1, in_fp); + if (feof(in_fp) != 0) { + BT_COMP_LOGI("Reached end of file: offset=%ld", ftell(in_fp)); + goto end; + } + if (readlen < 1) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode metadata packet: offset=%ld", + offset); + goto error; + } + + if (byte_order != BYTE_ORDER) { + header.magic = GUINT32_SWAP_LE_BE(header.magic); + header.checksum = GUINT32_SWAP_LE_BE(header.checksum); + header.content_size = GUINT32_SWAP_LE_BE(header.content_size); + header.packet_size = GUINT32_SWAP_LE_BE(header.packet_size); + } + + if (header.compression_scheme) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Metadata packet compression is not supported as of this version: " + "compression-scheme=%u, offset=%ld", + (unsigned int) header.compression_scheme, offset); + goto error; + } + + if (header.encryption_scheme) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Metadata packet encryption is not supported as of this version: " + "encryption-scheme=%u, offset=%ld", + (unsigned int) header.encryption_scheme, offset); + goto error; + } + + if (header.checksum || header.checksum_scheme) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Metadata packet checksum verification is not supported as of this version: " + "checksum-scheme=%u, checksum=%x, offset=%ld", + (unsigned int) header.checksum_scheme, header.checksum, offset); + goto error; + } + + if (!ctf_metadata_decoder_is_packet_version_valid(header.major, header.minor)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid metadata packet version: " + "version=%u.%u, offset=%ld", + header.major, header.minor, offset); + goto error; + } + + /* Set expected trace UUID if not set; otherwise validate it */ + if (is_uuid_set) { + if (!*is_uuid_set) { + bt_uuid_copy(uuid, header.uuid); + *is_uuid_set = true; + } else if (bt_uuid_compare(header.uuid, uuid)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Metadata UUID mismatch between packets of the same stream: " + "packet-uuid=\"" BT_UUID_FMT "\", " + "expected-uuid=\"" BT_UUID_FMT "\", " + "offset=%ld", + BT_UUID_FMT_VALUES(header.uuid), BT_UUID_FMT_VALUES(uuid), offset); + goto error; + } + } + + if ((header.content_size / CHAR_BIT) < sizeof(header)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Bad metadata packet content size: content-size=%u, " + "offset=%ld", + header.content_size, offset); + goto error; + } + + toread = header.content_size / CHAR_BIT - sizeof(header); + + for (;;) { + size_t loop_read; + + loop_read = MIN(sizeof(buf) - 1, toread); + readlen = fread(buf, sizeof(uint8_t), loop_read, in_fp); + if (ferror(in_fp)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot read metadata packet buffer: " + "offset=%ld, read-size=%zu", + ftell(in_fp), loop_read); + goto error; + } + if (readlen > loop_read) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("fread returned more byte than expected: " + "read-size-asked=%zu, read-size-returned=%zu", + loop_read, readlen); + goto error; + } + + writelen = fwrite(buf, sizeof(uint8_t), readlen, out_fp); + if (writelen < readlen || ferror(out_fp)) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot write decoded metadata text to buffer: " + "read-offset=%ld, write-size=%zu", + ftell(in_fp), readlen); + goto error; + } + + toread -= readlen; + if (toread == 0) { + int fseek_ret; + + /* Read leftover padding */ + toread = (header.packet_size - header.content_size) / CHAR_BIT; + fseek_ret = fseek(in_fp, toread, SEEK_CUR); + if (fseek_ret < 0) { + BT_COMP_LOGW_STR("Missing padding at the end of the metadata stream."); + } + break; + } + } + + goto end; error: - ret = -1; + ret = -1; end: - return ret; + return ret; } BT_HIDDEN -int ctf_metadata_decoder_packetized_file_stream_to_buf(FILE *fp, - char **buf, int byte_order, bool *is_uuid_set, - uint8_t *uuid, bt_logging_level log_level, - bt_self_component *self_comp, - bt_self_component_class *self_comp_class) +int ctf_metadata_decoder_packetized_file_stream_to_buf(FILE *fp, char **buf, int byte_order, + bool *is_uuid_set, uint8_t *uuid, + bt_logging_level log_level, + bt_self_component *self_comp, + bt_self_component_class *self_comp_class) { - FILE *out_fp; - size_t size; - int ret = 0; - int tret; - size_t packet_index = 0; - - out_fp = bt_open_memstream(buf, &size); - if (!out_fp) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot open memory stream: %s.", - strerror(errno)); - goto error; - } - - for (;;) { - if (feof(fp) != 0) { - break; - } - - tret = decode_packet(fp, out_fp, byte_order, is_uuid_set, - uuid, log_level, self_comp, self_comp_class); - if (tret) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode packet: index=%zu", - packet_index); - goto error; - } - - packet_index++; - } - - /* Make sure the whole string ends with a null character */ - tret = fputc('\0', out_fp); - if (tret == EOF) { - _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( - "Cannot append '\\0' to the decoded metadata buffer."); - goto error; - } - - /* Close stream, which also flushes the buffer */ - ret = bt_close_memstream(buf, &size, out_fp); - /* - * See fclose(3). Further access to out_fp after both success - * and error, even through another bt_close_memstream(), results - * in undefined behavior. Nullify out_fp to ensure we don't - * fclose it twice on error. - */ - out_fp = NULL; - if (ret < 0) { - BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, "Cannot close memory stream", "."); - goto error; - } - - goto end; + FILE *out_fp; + size_t size; + int ret = 0; + int tret; + size_t packet_index = 0; + + out_fp = bt_open_memstream(buf, &size); + if (!out_fp) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot open memory stream: %s.", strerror(errno)); + goto error; + } + + for (;;) { + if (feof(fp) != 0) { + break; + } + + tret = decode_packet(fp, out_fp, byte_order, is_uuid_set, uuid, log_level, self_comp, + self_comp_class); + if (tret) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Cannot decode packet: index=%zu", + packet_index); + goto error; + } + + packet_index++; + } + + /* Make sure the whole string ends with a null character */ + tret = fputc('\0', out_fp); + if (tret == EOF) { + _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE( + "Cannot append '\\0' to the decoded metadata buffer."); + goto error; + } + + /* Close stream, which also flushes the buffer */ + ret = bt_close_memstream(buf, &size, out_fp); + /* + * See fclose(3). Further access to out_fp after both success + * and error, even through another bt_close_memstream(), results + * in undefined behavior. Nullify out_fp to ensure we don't + * fclose it twice on error. + */ + out_fp = NULL; + if (ret < 0) { + BT_COMP_LOGE_APPEND_CAUSE_ERRNO(BT_COMP_LOG_SELF_COMP, "Cannot close memory stream", "."); + goto error; + } + + goto end; error: - ret = -1; + ret = -1; - if (out_fp) { - if (bt_close_memstream(buf, &size, out_fp)) { - BT_COMP_LOGE_ERRNO("Cannot close memory stream", "."); - } - } + if (out_fp) { + if (bt_close_memstream(buf, &size, out_fp)) { + BT_COMP_LOGE_ERRNO("Cannot close memory stream", "."); + } + } - if (*buf) { - free(*buf); - *buf = NULL; - } + if (*buf) { + free(*buf); + *buf = NULL; + } end: - return ret; + return ret; }