Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-07-07 05:35:03 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-07-07 05:35:03 +0300
commit31e6f0dc7af6ff1be19da93021b7095fe68da833 (patch)
treecef869d41ccc677310215d1ee9a6e2d4f9663e02
parentf85ef3d4423d77abe84072b781c02dd5a6145109 (diff)
makesdna: fix parsing 'const', 'struct', 'unsigned' as a prefix
DNA parsing assumed any identifier which starts with (`struct`, `unsigned`, `const`) was that identifier. So a struct called `constTest foo;` would be parsed as `est foo;`. Add utility function to check identifiers are not part of a larger identifier. This also supports skipping these identifiers in any order. Reviewed By: LazyDodo Ref D11837
-rw-r--r--source/blender/makesdna/intern/makesdna.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index fb1cf9b591d..f2a75a60a44 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -43,6 +43,7 @@
#define DNA_DEPRECATED_ALLOW
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -272,6 +273,37 @@ void print_struct_sizes(void);
* Make DNA string (write to file).
* \{ */
+static bool match_identifier_with_len(const char *str,
+ const char *identifier,
+ const size_t identifier_len)
+{
+ if (strncmp(str, identifier, identifier_len) == 0) {
+ /* Check `str` isn't a prefix to a longer identifier. */
+ if (isdigit(str[identifier_len]) || isalpha(str[identifier_len]) ||
+ (str[identifier_len] == '_')) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+static bool match_identifier(const char *str, const char *identifier)
+{
+ const size_t identifier_len = strlen(identifier);
+ return match_identifier_with_len(str, identifier, identifier_len);
+}
+
+static bool match_identifier_and_advance(char **str_ptr, const char *identifier)
+{
+ const size_t identifier_len = strlen(identifier);
+ if (match_identifier_with_len(*str_ptr, identifier, identifier_len)) {
+ (*str_ptr) += identifier_len;
+ return true;
+ }
+ return false;
+}
+
static const char *version_struct_static_from_alias(const char *str)
{
const char *str_test = BLI_ghash_lookup(g_version_data.struct_map_static_from_alias, str);
@@ -619,7 +651,7 @@ static int preprocess_include(char *maindata, const int maindata_len)
else if (cp[-1] == '*' && cp[0] == ' ') {
/* pointers with a space */
} /* skip special keywords */
- else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) {
+ else if (match_identifier(cp, "DNA_DEPRECATED")) {
/* single values are skipped already, so decrement 1 less */
a -= 13;
cp += 13;
@@ -721,7 +753,7 @@ static int convert_include(const char *filename)
md1++;
/* we've got a struct name when... */
- if (strncmp(md1 - 7, "struct", 6) == 0) {
+ if (match_identifier(md1 - 7, "struct")) {
const int strct = add_type(md1, 0);
if (strct == -1) {
@@ -756,14 +788,22 @@ static int convert_include(const char *filename)
/* skip when it says 'struct' or 'unsigned' or 'const' */
if (*md1) {
- if (strncmp(md1, "struct", 6) == 0) {
- md1 += 7;
- }
- if (strncmp(md1, "unsigned", 8) == 0) {
- md1 += 9;
- }
- if (strncmp(md1, "const", 5) == 0) {
- md1 += 6;
+ const char *md1_prev = md1;
+ while (match_identifier_and_advance(&md1, "struct") ||
+ match_identifier_and_advance(&md1, "unsigned") ||
+ match_identifier_and_advance(&md1, "const")) {
+ if (UNLIKELY(!ELEM(*md1, '\0', ' '))) {
+ /* This will happen with: `unsigned(*value)[3]` which isn't supported. */
+ fprintf(stderr,
+ "File '%s' contains non white space character "
+ "\"%c\" after identifier \"%s\"\n",
+ filename,
+ *md1,
+ md1_prev);
+ return 1;
+ }
+ /* Skip ' ' or '\0'. */
+ md1++;
}
/* we've got a type! */