Feature/rdk 60236 searchremoved dynamic#195
Conversation
Code Coverage Summary |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 13 changed files in this pull request and generated 7 comments.
Comments suppressed due to low confidence (1)
src/rrdJsonParser.c:178
split_issue_type()is not syntactically complete: the function body never closes (missing closing braces) and thereadJsonFile()comment/definition begins while still inside thesplit_issue_typecontrol flow. This will not compile; please rewrite/simplify the function and ensure all opened blocks are closed beforereadJsonFile()starts.
if (split) {
size_t b_len = (size_t)(split - input);
if (b_len >= base_len) b_len = base_len - 1;
strncpy(base, input, b_len);
base[b_len] = '\0';
// Suffix logic as before
if (strlen(split) <= RRD_MAX_SUFFIX_LEN) {
size_t si = 0, di = 0;
size_t max_copy = suffix_len - 1;
while (split[si] != '\0' && di < max_copy) {
const char *p = input;
const char *split = NULL;
size_t appnd_len = strlen(APPEND_SUFFIX);
int found_appnd = 0;
while ((p = strchr(p, '_')) != NULL) {
if (strncmp(p, APPEND_SUFFIX, appnd_len) == 0) {
found_appnd = 1;
// Don't skip the underscore, just mark that APPEND_SUFFIX is present
p += appnd_len;
continue;
} else {
split = p;
break;
}
}
if (split) {
size_t b_len = (size_t)(split - input);
if (b_len >= base_len) b_len = base_len - 1;
strncpy(base, input, b_len);
base[b_len] = '\0';
// Suffix logic as before
if (strlen(split) <= RRD_MAX_SUFFIX_LEN) {
size_t si = 0, di = 0;
size_t max_copy = suffix_len - 1;
while (split[si] != '\0' && di < max_copy) {
char ch = split[si];
if (isalnum((unsigned char)ch) || ch == '_' || ch == '-') {
suffix[di++] = ch;
}
si++;
}
suffix[di] = '\0';
} else {
RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Suffix after '%s' exceeds max length (%zu > %d); discarding\n",
__FUNCTION__, __LINE__, base, strlen(split), RRD_MAX_SUFFIX_LEN);
suffix[0] = '\0';
}
} else {
// No split point found
// If APPEND_SUFFIX was found, base is the whole input (including _ and APPEND_SUFFIX)
strncpy(base, input, base_len - 1);
base[base_len - 1] = '\0';
suffix[0] = '\0';
}
* @brief Reads the JSON file and stores the content in a character array.
* @param char *jsonfile - The name of the JSON file whose content is to be read.
* @return char* - A string containing the JSON content, or NULL on failure.
*/
char * readJsonFile(char *jsonfile)
| #include <sys/stat.h> | ||
| #include <sys/types.h> | ||
| #include <ctype.h> | ||
| #define RRD_MAX_SUFFIX_LEN 10 |
| RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Restored suffix from cache struct: %s\n", __FUNCTION__, __LINE__, cache->suffix); | ||
| // Append suffix to mdata | ||
| size_t mdata_len = strlen(sendbuf->mdata); | ||
| size_t suffix_len = strlen(sendbuf->suffix); | ||
| size_t total_len = mdata_len + suffix_len + 1; | ||
| char *new_mdata = realloc(sendbuf->mdata, total_len); | ||
| if (new_mdata) | ||
| { | ||
| sendbuf->mdata = new_mdata; | ||
| strncat(sendbuf->mdata, sendbuf->suffix, suffix_len); | ||
| } | ||
| else | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_REMDEBUG, "[%s:%d]: Failed to realloc mdata for suffix append\n", __FUNCTION__, __LINE__); | ||
| } |
| RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Restored suffix from cache struct: %s\n", __FUNCTION__, __LINE__, cache->suffix); | ||
| // Append suffix to mdata | ||
| size_t mdata_len = strlen(sendbuf->mdata); | ||
| size_t suffix_len = strlen(sendbuf->suffix); | ||
| size_t total_len = mdata_len + suffix_len + 1; | ||
| char *new_mdata = realloc(sendbuf->mdata, total_len); | ||
| if (new_mdata) | ||
| { | ||
| sendbuf->mdata = new_mdata; | ||
| strncat(sendbuf->mdata, sendbuf->suffix, suffix_len); | ||
| } | ||
| else | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_REMDEBUG, "[%s:%d]: Failed to realloc mdata for suffix append\n", __FUNCTION__, __LINE__); | ||
| } |
| { | ||
| /* "_Random-token" is 13 chars (> 9): suffix discarded; base = "Device.DeviceTime" */ | ||
| data_buf rbuf = {}; | ||
| rbuf.mdata = strdup("Device.DeviceTime_Random-token"); | ||
| rbuf.inDynamic = false; | ||
| rbuf.jsonPath = nullptr; | ||
| /* Should not crash; long suffix is discarded, base is processed normally */ | ||
| processIssueTypeEvent(&rbuf); | ||
| free(rbuf.mdata); | ||
| rbuf.mdata = NULL; |
| { | ||
| /* When the IssueType value from RBUS is whitespace (e.g. a space), | ||
| * removeSpecialCharacterfromIssueTypeList() strips it to an empty string. | ||
| * processIssueTypeEvent() must detect the post-sanitization empty base | ||
| * and skip processing without crashing or invoking processIssueType. */ | ||
| data_buf rbuf = {}; | ||
| rbuf.mdata = strdup(" "); /* single space — all-special after split */ | ||
| rbuf.inDynamic = false; | ||
| rbuf.jsonPath = nullptr; | ||
| /* Must not crash and must not reach getIssueInfo with an empty mdata */ | ||
| processIssueTypeEvent(&rbuf); | ||
| free(rbuf.mdata); |
| TEST(ProcessIssueTypeEvntTest, EmptyStringIssueTypeIsSkipped) | ||
| { | ||
| /* An empty-string mdata must be handled gracefully — issueTypeSplitter | ||
| * returns 1 token that is an empty string, which split_issue_type then | ||
| * maps to an empty base, causing the entry to be skipped. */ | ||
| data_buf rbuf = {}; | ||
| rbuf.mdata = strdup(""); | ||
| rbuf.inDynamic = false; | ||
| rbuf.jsonPath = nullptr; | ||
| processIssueTypeEvent(&rbuf); | ||
| free(rbuf.mdata); |
| /* | ||
| * @function getParamcount | ||
| * @brief Calculates the total number of nodes (elements) in the input string, excluding delimiters. | ||
| * @param char *str - The string from TR181 whose nodes are to be counted. | ||
| * @return int - The number of nodes. | ||
| * @function split_issue_type | ||
| * @brief Utility to split base and suffix from issue type string. | ||
| * The input is always split at the first '_'. The base is the part | ||
| * before the underscore (never contains '_'). The suffix is only | ||
| * kept when its total length (including the leading '_') is at most | ||
| * RRD_MAX_SUFFIX_LEN (9) characters; longer suffixes are discarded. | ||
| * After length validation the suffix is sanitized: only the characters | ||
| * [A-Za-z0-9_-] are retained so that the value is safe to use in file | ||
| * names and shell command arguments without risk of injection. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 13 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
src/rrdJsonParser.c:31
RRD_MAX_SUFFIX_LENis defined as 10, but the docstring below describes the max suffix length (including the leading_) as 9. This inconsistency can cause off-by-one behavior (accepting 10-char suffixes) and makes the boundary unclear. Align the constant with the documented/expected limit (or update the documentation/tests if 10 is intended).
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#define RRD_MAX_SUFFIX_LEN 10
/*
* @function removeSpecialChar
* @brief Removes special characters ('\r' and '\n') from the device properties parameter string.
| * @brief Reads the JSON file and stores the content in a character array. | ||
| * @param char *jsonfile - The name of the JSON file whose content is to be read. | ||
| * @return char* - A string containing the JSON content, or NULL on failure. | ||
| */ | ||
| char * readJsonFile(char *jsonfile) | ||
| { | ||
| FILE *fp = NULL; | ||
| int ch_count = 0; | ||
| char *jsonfile_content = NULL; | ||
|
|
||
| RDK_LOG(RDK_LOG_DEBUG,LOG_REMDEBUG,"[%s:%d]: Reading json config file %s \n",__FUNCTION__,__LINE__,jsonfile); | ||
| fp = fopen(jsonfile, "r"); | ||
| if (fp == NULL) | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR,LOG_REMDEBUG,"[%s:%d]: Json File %s Read Failed!!! \n",__FUNCTION__,__LINE__,jsonfile); | ||
| return NULL; | ||
| } | ||
| fseek(fp, 0, SEEK_END); | ||
| ch_count = ftell(fp); | ||
| if(ch_count < 1) | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR,LOG_REMDEBUG,"[%s:%d]: Json File %s is Empty!!! \n",__FUNCTION__,__LINE__,jsonfile); | ||
| // CID 278332: Resource leak (RESOURCE_LEAK) | ||
| fclose(fp); | ||
| return NULL; | ||
| } | ||
| fseek(fp, 0, SEEK_SET); | ||
| jsonfile_content = (char *) malloc(sizeof(char) * (ch_count + 1)); | ||
| if (jsonfile_content == NULL) | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR,LOG_REMDEBUG,"[%s:%d]: Memory allocation failed for json file %s \n",__FUNCTION__,__LINE__,jsonfile); | ||
| fclose(fp); | ||
| return NULL; | ||
| } | ||
|
|
||
| size_t bytes_read = fread(jsonfile_content, 1, ch_count, fp); | ||
| if (bytes_read != (size_t)ch_count) | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR,LOG_REMDEBUG,"[%s:%d]: Failed to read json file %s. Expected %d bytes, read %zu bytes \n",__FUNCTION__,__LINE__,jsonfile,ch_count,bytes_read); | ||
| free(jsonfile_content); | ||
| fclose(fp); | ||
| return NULL; | ||
| } | ||
|
|
||
| jsonfile_content[ch_count] ='\0'; | ||
| fclose(fp); | ||
|
|
||
| return jsonfile_content; |
| @@ -88,9 +116,19 @@ void processIssueTypeEvent(data_buf *rbuf) | |||
| } | |||
| cacheData *tmp = createCache(pkgData, issueTypeData, suffix); | ||
| if(!tmp) | ||
| { | ||
| RDK_LOG(RDK_LOG_INFO,LOG_REMDEBUG,"[%s:%d]: Memory Allocation Failed : Cannot Append Item to Cache\n", __FUNCTION__, __LINE__); |
Code Coverage Summary |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 13 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (1)
src/rrdJsonParser.c:31
RRD_MAX_SUFFIX_LENis defined as 10, but the function comment (and tests) describe a max suffix length of 9 characters (including the leading '_'). This makes the length validation ambiguous/off-by-one. Align the macro value, comment, and comparisons so the enforced maximum matches the intended contract.
#include <ctype.h>
#define RRD_MAX_SUFFIX_LEN 10
/*
* @function removeSpecialChar
* @brief Removes special characters ('\r' and '\n') from the device properties parameter string.
| sendbuf->suffix = strdup(cache->suffix); | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Restored suffix from cache struct: %s\n", __FUNCTION__, __LINE__, cache->suffix); | ||
| // Append suffix to mdata | ||
| size_t mdata_len = strlen(sendbuf->mdata); | ||
| size_t suffix_len = strlen(sendbuf->suffix); | ||
| size_t total_len = mdata_len + suffix_len + 1; | ||
| char *new_mdata = realloc(sendbuf->mdata, total_len); | ||
| if (new_mdata) | ||
| { | ||
| sendbuf->mdata = new_mdata; | ||
| strncat(sendbuf->mdata, sendbuf->suffix, suffix_len); | ||
| } | ||
| else | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_REMDEBUG, "[%s:%d]: Failed to realloc mdata for suffix append\n", __FUNCTION__, __LINE__); | ||
| } |
| if (cache->suffix && cache->suffix[0] != '\0') | ||
| { | ||
| sendbuf->suffix = strdup(cache->suffix); | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Restored suffix from cache struct: %s\n", __FUNCTION__, __LINE__, cache->suffix); | ||
| // Append suffix to mdata | ||
| size_t mdata_len = strlen(sendbuf->mdata); | ||
| size_t suffix_len = strlen(sendbuf->suffix); | ||
| size_t total_len = mdata_len + suffix_len + 1; | ||
| char *new_mdata = realloc(sendbuf->mdata, total_len); | ||
| if (new_mdata) | ||
| { | ||
| sendbuf->mdata = new_mdata; | ||
| strncat(sendbuf->mdata, sendbuf->suffix, suffix_len); | ||
| } | ||
| else | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_REMDEBUG, "[%s:%d]: Failed to realloc mdata for suffix append\n", __FUNCTION__, __LINE__); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| sendbuf->suffix = NULL; |
| /* | ||
| * @function split_issue_type | ||
| * @brief Utility to split base and suffix from issue type string. | ||
| * The input is always split at the first '_'. The base is the part | ||
| * before the underscore (never contains '_'). The suffix is only | ||
| * kept when its total length (including the leading '_') is at most | ||
| * RRD_MAX_SUFFIX_LEN (9) characters; longer suffixes are discarded. | ||
| * After length validation the suffix is sanitized: only the characters |
| int cnt = 1, i = 0; | ||
| char *str = input_str; | ||
|
|
||
| removeSpecialCharacterfromIssueTypeList(str); | ||
| while (*str == delimeter) | ||
| str++; | ||
|
|
| { | ||
| char *pkgData = NULL; | ||
| char *issueTypeData = strdup("ValidIssueTypeData"); | ||
| append_item(pkgData, issueTypeData); | ||
| append_item(pkgData, issueTypeData, NULL); | ||
|
|
||
| ASSERT_NE(cacheDataNode, nullptr); | ||
| ASSERT_EQ(cacheDataNode->mdata, nullptr); |
| cacheData *firstNode = (cacheData *)calloc(1, sizeof(cacheData)); | ||
| firstNode->mdata = strdup("FirstPkgData"); | ||
| firstNode->issueString = strdup("FirstIssueString"); | ||
| firstNode->next = NULL; | ||
| cacheData *secondNode = (cacheData *)malloc(sizeof(cacheData)); | ||
| cacheData *secondNode = (cacheData *)calloc(1, sizeof(cacheData)); | ||
| secondNode->mdata = strdup("SecondPkgData"); | ||
| secondNode->issueString = strdup("SecondIssueString"); | ||
| secondNode->next = NULL; |
Code Coverage Summary |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 13 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
src/rrdJsonParser.c:31
- RRD_MAX_SUFFIX_LEN is defined as 10 but the function documentation/logging describes the maximum allowed suffix length as 9 (including the leading '_'), and unit tests in this PR assert 9 as the upper bound. Please align the constant + documentation/tests (e.g., change the define to 9, or update docs/tests if 10 is intended) so the length gate is unambiguous.
#define RRD_MAX_SUFFIX_LEN 10
/*
* @function removeSpecialChar
* @brief Removes special characters ('\r' and '\n') from the device properties parameter string.
| RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Restored suffix from cache struct: %s\n", __FUNCTION__, __LINE__, cache->suffix); | ||
| // Append suffix to mdata | ||
| size_t mdata_len = strlen(sendbuf->mdata); | ||
| size_t suffix_len = strlen(sendbuf->suffix); | ||
| size_t total_len = mdata_len + suffix_len + 1; | ||
| char *new_mdata = realloc(sendbuf->mdata, total_len); | ||
| if (new_mdata) | ||
| { | ||
| sendbuf->mdata = new_mdata; | ||
| strncat(sendbuf->mdata, sendbuf->suffix, suffix_len); | ||
| } | ||
| else | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_REMDEBUG, "[%s:%d]: Failed to realloc mdata for suffix append\n", __FUNCTION__, __LINE__); | ||
| } |
| void append_item(char *pkgData, char *issueTypeData) | ||
| void append_item(char *pkgData, char *issueTypeData, char *suffix) | ||
| { | ||
| RDK_LOG(RDK_LOG_INFO,LOG_REMDEBUG,"[%s:%d]: Append Item with PkgData: %s and issue Type: %s to Cache \n",__FUNCTION__,__LINE__,pkgData,issueTypeData); |
| RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Restored suffix from cache struct: %s\n", __FUNCTION__, __LINE__, cache->suffix); | ||
| // Append suffix to mdata | ||
| size_t mdata_len = strlen(sendbuf->mdata); | ||
| size_t suffix_len = strlen(sendbuf->suffix); | ||
| size_t total_len = mdata_len + suffix_len + 1; | ||
| char *new_mdata = realloc(sendbuf->mdata, total_len); | ||
| if (new_mdata) | ||
| { | ||
| sendbuf->mdata = new_mdata; | ||
| strncat(sendbuf->mdata, sendbuf->suffix, suffix_len); | ||
| } | ||
| else | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_REMDEBUG, "[%s:%d]: Failed to realloc mdata for suffix append\n", __FUNCTION__, __LINE__); | ||
| } |
| RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Restored suffix from cache struct: %s\n", __FUNCTION__, __LINE__, cache->suffix); | ||
| // Append suffix to mdata | ||
| size_t mdata_len = strlen(sendbuf->mdata); | ||
| size_t suffix_len = strlen(sendbuf->suffix); | ||
| size_t total_len = mdata_len + suffix_len + 1; | ||
| char *new_mdata = realloc(sendbuf->mdata, total_len); | ||
| if (new_mdata) | ||
| { | ||
| sendbuf->mdata = new_mdata; | ||
| strncat(sendbuf->mdata, sendbuf->suffix, suffix_len); | ||
| } | ||
| else | ||
| { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_REMDEBUG, "[%s:%d]: Failed to realloc mdata for suffix append\n", __FUNCTION__, __LINE__); | ||
| } |
| sendbuf->suffix = strdup(cache->suffix); | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_REMDEBUG, "[%s:%d]: Restored suffix from cache struct: %s\n", __FUNCTION__, __LINE__, cache->suffix); | ||
| // Append suffix to mdata | ||
| size_t mdata_len = strlen(sendbuf->mdata); | ||
| size_t suffix_len = strlen(sendbuf->suffix); |
|
@copilot do we need both |
Yes—right now both are needed because they do different jobs: |
|
@copilot can we make issueTypeSplitter() and split_issue_type() to a single function? |
Yes, we can combine them, but for the current code it’s a weaker approach. Keeping them separate is better right now: one function handles list tokenization, and the other handles per-token base/suffix validation/sanitization. Merging would mix two responsibilities and increase regression risk unless we redesign as a single well-scoped parser with full test updates. No UI change, so screenshot is not applicable. |
No description provided.