From 45d967c803324a50852d4c4615a521e6e245a5dd Mon Sep 17 00:00:00 2001 From: Graham Bloice Date: Sun, 8 Jan 2017 21:02:46 +0000 Subject: profinet: Skip comments in GSD file Bug: 13303 Change-Id: I9ab17ec25917723be06b36ab4c11fe67e6792715 Reviewed-on: https://code.wireshark.org/review/19593 Reviewed-by: Graham Bloice Petri-Dish: Graham Bloice Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman --- plugins/profinet/packet-dcerpc-pn-io.c | 13 ++++--- plugins/profinet/packet-pn-rtc-one.c | 1 - plugins/profinet/packet-pn.c | 63 ++++++++++++++++++++++++++++++++++ plugins/profinet/packet-pn.h | 6 ++++ 4 files changed, 75 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/profinet/packet-dcerpc-pn-io.c b/plugins/profinet/packet-dcerpc-pn-io.c index f94c651865..5af67f3ce3 100644 --- a/plugins/profinet/packet-dcerpc-pn-io.c +++ b/plugins/profinet/packet-dcerpc-pn-io.c @@ -90,7 +90,6 @@ void proto_reg_handoff_pn_io(void); #define MAX_NAMELENGTH 200 /* max. length of the given paths */ -#define MAX_LINE_LENGTH 1024 /* used for fgets() */ #define F_MESSAGE_TRAILER_4BYTE 4 /* PROFIsafe: Defines the Amount of Bytes for CRC and Status-/Controlbyte */ #define PN_INPUT_CR 1 /* PROFINET Input Connect Request value */ #define PN_INPUT_DATADESCRITPION 1 /* PROFINET Input Data Description value */ @@ -9313,7 +9312,7 @@ dissect_ExpectedSubmoduleBlockReq_block(tvbuff_t *tvb, int offset, if(fp != NULL) { /* ---- Get VendorID & DeviceID ---- */ - while(fgets(puffer, MAX_LINE_LENGTH, fp) != NULL) { + while(pn_fgets(puffer, MAX_LINE_LENGTH, fp) != NULL) { /* ----- VendorID ------ */ if((strstr(puffer, vendorIdStr)) != NULL) { memset (convertStr, 0, sizeof(*convertStr)); @@ -9460,7 +9459,7 @@ dissect_ExpectedSubmoduleBlockReq_block(tvbuff_t *tvb, int offset, fseek(fp, 0, SEEK_SET); /* Find Indexnumber for fParameter */ - while(fgets(temp, MAX_LINE_LENGTH, fp) != NULL) { + while(pn_fgets(temp, MAX_LINE_LENGTH, fp) != NULL) { if((strstr(temp, fParameterStr)) != NULL) { memset (convertStr, 0, sizeof(*convertStr)); @@ -9475,7 +9474,7 @@ dissect_ExpectedSubmoduleBlockReq_block(tvbuff_t *tvb, int offset, memset (temp, 0, sizeof(*temp)); fseek(fp, 0, SEEK_SET); /* Set filepointer to the beginning */ - while(fgets(temp, MAX_LINE_LENGTH, fp) != NULL) { + while(pn_fgets(temp, MAX_LINE_LENGTH, fp) != NULL) { if((strstr(temp, moduleStr)) != NULL) { /* find the String "ModuleIdentNumber=" */ memset (convertStr, 0, sizeof(*convertStr)); pch = strstr(temp, moduleStr); /* search for "ModuleIdentNumber=\"" within GSD-file */ @@ -9486,7 +9485,7 @@ dissect_ExpectedSubmoduleBlockReq_block(tvbuff_t *tvb, int offset, if (read_module_id == io_data_object->moduleIdentNr) { ++io_data_object->amountInGSDML; /* Save the amount of same (!) Module- & SubmoduleIdentNr in one GSD-file */ - while(fgets(temp, MAX_LINE_LENGTH, fp) != NULL) { + while(pn_fgets(temp, MAX_LINE_LENGTH, fp) != NULL) { if((strstr(temp, moduleNameInfo)) != NULL) { /* find the String "= 0) { - while (fgets(temp, MAX_LINE_LENGTH, fp) != NULL && io_data_object->amountInGSDML == 1) { + while (pn_fgets(temp, MAX_LINE_LENGTH, fp) != NULL && io_data_object->amountInGSDML == 1) { /* Find a String with the saved TextID and with a fitting value for it in the same line. This value is the name of the Module! */ if(((strstr(temp, tmp_moduletext)) != NULL) && ((strstr(temp, moduleValueInfo)) != NULL)) { pch = strstr(temp, moduleValueInfo); @@ -9523,7 +9522,7 @@ dissect_ExpectedSubmoduleBlockReq_block(tvbuff_t *tvb, int offset, break; } else { /* flag is not in the same line as Submoduleidentnumber -> search for it */ - while(fgets(temp, MAX_LINE_LENGTH, fp) != NULL) { + while(pn_fgets(temp, MAX_LINE_LENGTH, fp) != NULL) { if((strstr(temp, profisafeStr)) != NULL) { io_data_object->profisafeSupported = TRUE; break; /* Found the PROFIsafeSupported flag of the module */ diff --git a/plugins/profinet/packet-pn-rtc-one.c b/plugins/profinet/packet-pn-rtc-one.c index b89a73d092..0d52002beb 100644 --- a/plugins/profinet/packet-pn-rtc-one.c +++ b/plugins/profinet/packet-pn-rtc-one.c @@ -76,7 +76,6 @@ #include "packet-pn.h" -#define MAX_LINE_LENGTH 1024 /* used for fgets() */ #define F_MESSAGE_TRAILER_4BYTE 4 /* PROFIsafe: Defines the Amount of Bytes for CRC and Status-/Controlbyte */ #define PN_INPUT_CR 1 /* PROFINET Input Connect Request value */ #define PN_INPUT_DATADESCRITPION 1 /* PROFINET Input Data Description value */ diff --git a/plugins/profinet/packet-pn.c b/plugins/profinet/packet-pn.c index 5d6c38ad5c..7c2e013625 100644 --- a/plugins/profinet/packet-pn.c +++ b/plugins/profinet/packet-pn.c @@ -365,6 +365,69 @@ init_pn (int proto) expert_register_field_array(expert_pn, ei, array_length(ei)); } +/* Read a string from an "xml" file, dropping xml comment blocks */ +char *pn_fgets(char *str, int n, FILE *stream) +{ + const char XML_COMMENT_START[] = ""; + + char *retVal = fgets(str, n, stream); + if (retVal == NULL) { + /* No input, we're done */ + return retVal; + } + + /* Search for the XML begin comment marker */ + char *comment_start = strstr(str, XML_COMMENT_START); + char *common_start_end = comment_start + sizeof(XML_COMMENT_START) - 1; + if(comment_start == NULL) { + /* No comment start, we're done */ + return retVal; + } + + /* Terminate the input buffer at the comment start */ + *comment_start = '\0'; + size_t used_space = comment_start - str; + size_t remaining_space = n - used_space; + + /* Read more data looking for the comment end */ + char *comment_end = strstr(common_start_end, XML_COMMENT_END); + if (comment_end == NULL) { + // Not found in this line, read more lines until we do find it */ + char *temp = (char*)wmem_alloc(wmem_packet_scope(), MAX_LINE_LENGTH); + char *next_line = temp; + while((comment_end == NULL) && (next_line != NULL)) { + next_line = fgets(temp, MAX_LINE_LENGTH, stream); + if (next_line == NULL) { + /* No more data, exit now */ + break; + } + comment_start = next_line; + comment_end = strstr(next_line, XML_COMMENT_END); + } + } + + if (comment_end == NULL) { + /* We didn't find the comment end, return what we have */ + return retVal; + } + + /* We did find a comment end, skip past the comment */ + char *comment_end_end = comment_end + sizeof(XML_COMMENT_END) - 1; + + /* Check we have space left in the buffer to move the trailing bytes after the comment end */ + size_t remaining_bytes = strlen(comment_end_end) + 1; + if (remaining_bytes < remaining_space) { + g_strlcat(str, comment_end_end, n); + } + else { + /* Seek the file back to the comment end so the next read picks it up */ + fseek(stream, -(long)(remaining_bytes), SEEK_CUR); + } + + return retVal; +} + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * diff --git a/plugins/profinet/packet-pn.h b/plugins/profinet/packet-pn.h index 9ac7c9eb6d..688c71bee6 100644 --- a/plugins/profinet/packet-pn.h +++ b/plugins/profinet/packet-pn.h @@ -164,3 +164,9 @@ extern int dissect_PNIO_C_SDU_RTC1(tvbuff_t *tvb, int offset, packet_info *pinfo extern void pn_append_info(packet_info *pinfo, proto_item *dcp_item, const char *text); extern gboolean dissect_CSF_SDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data); + +#define MAX_LINE_LENGTH 1024 /* used for fgets() */ + +/* Read a string from an "xml" file, dropping xml comment blocks */ +#include +extern char *pn_fgets(char *str, int n, FILE *stream); -- cgit v1.2.3