Quellcode durchsuchen

Make class name string dynamically-allocated.

This is intended to resolve compiler warnings about the CreateCipClass()
name parameter, which is an immutable(const) character string. Directly
assigning it to the CipClass struct class_name member causes warnings
because the class_name member is not const. Changing it to const would
cause a different set of warnings when the meta-class name, which is
already dynamically-allocated, is freed, because CipFree does not take a
const pointer argument.

Another benefit is callers of CreateCipClass() don't need to ensure the
string pointed to by the name parameter stays in scope for the lifetime
of the created CipClass.
Jason Valenzuela vor 4 Jahren
Ursprung
Commit
cc388cd737
2 geänderte Dateien mit 19 neuen und 1 gelöschten Zeilen
  1. 18 1
      source/src/cip/cipcommon.c
  2. 1 0
      source/src/cip/cipmessagerouter.c

+ 18 - 1
source/src/cip/cipcommon.c

@@ -297,7 +297,24 @@ CipClass *CreateCipClass(const CipUdint class_code,
   cip_class->highest_attribute_number = highest_instance_attribute_number; /* indicate which attributes are included in instance getAttributeAll */
   cip_class->number_of_services = number_of_instance_services; /* the class manages the behavior of the instances */
   cip_class->services = 0;
-  cip_class->class_name = name; /* initialize the class-specific fields of the metaClass struct */
+
+  /* Allocate and initialize the class name string. */
+  OPENER_ASSERT(NULL != name);
+  const size_t name_len = strlen(name); /* Length does not include termination byte. */
+  OPENER_ASSERT(0 < name_len); /* Cannot be an empty string. */
+  cip_class->class_name = CipCalloc(name_len + 1, 1); /* Allocate length plus termination byte. */
+  OPENER_ASSERT(NULL != cip_class->class_name);
+
+  /*
+   * memcpy is used here, instead of a strcpy variant, to avoid Visual Studio
+   * depreciation warnings arising from strcpy use, and the recommended
+   * alternatives, e.g. strcpy_s, are not available on all systems. In this
+   * case the size of the source string is already known, so memcpy() is
+   * suitable.
+   */
+  memcpy(cip_class->class_name, name, name_len + 1);
+
+  /* initialize the class-specific fields of the metaClass struct */
   meta_class->class_code = 0xffffffff; /* set metaclass ID (this should never be referenced) */
   meta_class->number_of_instances = 1; /* the class object is the only instance of the metaclass */
   meta_class->instances = (CipInstance *) cip_class;

+ 1 - 0
source/src/cip/cipmessagerouter.c

@@ -299,6 +299,7 @@ void DeleteAllClasses(void) {
 
     /* free class data*/
     CipClass *cip_class = message_router_object_to_delete->cip_class;
+    CipFree(cip_class->class_name);
     CipFree(cip_class->get_single_bit_mask);
     CipFree(cip_class->set_bit_mask);
     CipFree(cip_class->get_all_bit_mask);