This is an automated email from the ASF dual-hosted git repository.

astitcher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git


The following commit(s) were added to refs/heads/main by this push:
     new c73b52b  PROTON-2468: Fix some undefined behaviour found by ubsan
c73b52b is described below

commit c73b52b22135cd8eed5241f8bceb4c6aa81c5fad
Author: Andrew Stitcher <[email protected]>
AuthorDate: Thu Nov 18 21:42:55 2021 -0500

    PROTON-2468: Fix some undefined behaviour found by ubsan
---
 c/src/core/consumers.h |  6 ++---
 c/src/core/data.h      |  2 +-
 c/src/core/encoder.c   | 64 ++++++++++++++++++++++++++++----------------------
 c/src/core/encoder.h   |  2 +-
 4 files changed, 41 insertions(+), 33 deletions(-)

diff --git a/c/src/core/consumers.h b/c/src/core/consumers.h
index 930c7c7..b4140e8 100644
--- a/c/src/core/consumers.h
+++ b/c/src/core/consumers.h
@@ -534,7 +534,7 @@ static inline bool consume_atom(pni_consumer_t* consumer, 
pn_atom_t *atom) {
 // if we get a symbol we should map it to the numeric value and dispatch on 
that
 static inline bool consume_descriptor(pni_consumer_t* consumer, pni_consumer_t 
*subconsumer, uint64_t *descriptor) {
   *descriptor = 0;
-  *subconsumer = 
(pni_consumer_t){.output_start=consumer->output_start+consumer->position, 
.position=0, .size=0};
+  *subconsumer = (pni_consumer_t){.output_start=NULL, .position=0, .size=0};
   uint8_t type;
   if (!pni_consumer_readf8(consumer, &type)) return false;
   switch (type) {
@@ -554,7 +554,7 @@ static inline bool consume_descriptor(pni_consumer_t* 
consumer, pni_consumer_t *
 }
 
 static inline bool consume_list(pni_consumer_t* consumer, pni_consumer_t 
*subconsumer, uint32_t *count) {
-  *subconsumer = 
(pni_consumer_t){.output_start=consumer->output_start+consumer->position, 
.position=0, .size=0};
+  *subconsumer = (pni_consumer_t){.output_start=NULL, .position=0, .size=0};
   *count = 0;
   uint8_t type;
   if (!pni_consumer_readf8(consumer, &type)) return false;
@@ -592,7 +592,7 @@ static inline bool consume_end_list(pni_consumer_t 
*consumer) {
 }
 
 static inline bool consume_array(pni_consumer_t* consumer, pni_consumer_t 
*subconsumer, uint32_t *count, uint8_t *element_type) {
-  *subconsumer = 
(pni_consumer_t){.output_start=consumer->output_start+consumer->position, 
.position=0, .size=0};
+  *subconsumer = (pni_consumer_t){.output_start=NULL, .position=0, .size=0};
   *count = 0;
   *element_type = 0;
   uint8_t type;
diff --git a/c/src/core/data.h b/c/src/core/data.h
index b95a657..e90e4f2 100644
--- a/c/src/core/data.h
+++ b/c/src/core/data.h
@@ -32,7 +32,7 @@ typedef uint16_t pni_nid_t;
 #define PNI_INTERN_MINSIZE 64
 
 typedef struct {
-  char *start;
+  size_t start;
   size_t data_offset;
   size_t data_size;
   pn_atom_t atom;
diff --git a/c/src/core/encoder.c b/c/src/core/encoder.c
index 44722ef..111ae25 100644
--- a/c/src/core/encoder.c
+++ b/c/src/core/encoder.c
@@ -38,7 +38,7 @@ static inline pn_error_t *pni_encoder_error(pn_encoder_t 
*encoder)
 void pn_encoder_initialize(pn_encoder_t *encoder)
 {
   encoder->output = NULL;
-  encoder->position = NULL;
+  encoder->position = 0;
   encoder->error = NULL;
   encoder->size = 0;
   encoder->null_count = 0;
@@ -144,9 +144,8 @@ static uint8_t pn_node2code(pn_encoder_t *encoder, 
pni_node_t *node)
 }
 
 static size_t pn_encoder_remaining(pn_encoder_t *encoder) {
-  char * end = encoder->output + encoder->size;
-  if (end > encoder->position)
-    return end - encoder->position;
+  if (encoder->size > encoder->position)
+    return encoder->size - encoder->position;
   else
     return 0;
 }
@@ -154,7 +153,8 @@ static size_t pn_encoder_remaining(pn_encoder_t *encoder) {
 static inline void pn_encoder_writef8(pn_encoder_t *encoder, uint8_t value)
 {
   if (pn_encoder_remaining(encoder)) {
-    encoder->position[0] = value;
+    char* position = encoder->output+encoder->position;
+    position[0] = value;
   }
   encoder->position++;
 }
@@ -162,8 +162,9 @@ static inline void pn_encoder_writef8(pn_encoder_t 
*encoder, uint8_t value)
 static inline void pn_encoder_writef16(pn_encoder_t *encoder, uint16_t value)
 {
   if (pn_encoder_remaining(encoder) >= 2) {
-    encoder->position[0] = 0xFF & (value >> 8);
-    encoder->position[1] = 0xFF & (value     );
+    char* position = encoder->output+encoder->position;
+    position[0] = 0xFF & (value >> 8);
+    position[1] = 0xFF & (value     );
   }
   encoder->position += 2;
 }
@@ -171,31 +172,34 @@ static inline void pn_encoder_writef16(pn_encoder_t 
*encoder, uint16_t value)
 static inline void pn_encoder_writef32(pn_encoder_t *encoder, uint32_t value)
 {
   if (pn_encoder_remaining(encoder) >= 4) {
-    encoder->position[0] = 0xFF & (value >> 24);
-    encoder->position[1] = 0xFF & (value >> 16);
-    encoder->position[2] = 0xFF & (value >>  8);
-    encoder->position[3] = 0xFF & (value      );
+    char* position = encoder->output+encoder->position;
+    position[0] = 0xFF & (value >> 24);
+    position[1] = 0xFF & (value >> 16);
+    position[2] = 0xFF & (value >>  8);
+    position[3] = 0xFF & (value      );
   }
   encoder->position += 4;
 }
 
 static inline void pn_encoder_writef64(pn_encoder_t *encoder, uint64_t value) {
   if (pn_encoder_remaining(encoder) >= 8) {
-    encoder->position[0] = 0xFF & (value >> 56);
-    encoder->position[1] = 0xFF & (value >> 48);
-    encoder->position[2] = 0xFF & (value >> 40);
-    encoder->position[3] = 0xFF & (value >> 32);
-    encoder->position[4] = 0xFF & (value >> 24);
-    encoder->position[5] = 0xFF & (value >> 16);
-    encoder->position[6] = 0xFF & (value >>  8);
-    encoder->position[7] = 0xFF & (value      );
+    char* position = encoder->output+encoder->position;
+    position[0] = 0xFF & (value >> 56);
+    position[1] = 0xFF & (value >> 48);
+    position[2] = 0xFF & (value >> 40);
+    position[3] = 0xFF & (value >> 32);
+    position[4] = 0xFF & (value >> 24);
+    position[5] = 0xFF & (value >> 16);
+    position[6] = 0xFF & (value >>  8);
+    position[7] = 0xFF & (value      );
   }
   encoder->position += 8;
 }
 
 static inline void pn_encoder_writef128(pn_encoder_t *encoder, char *value) {
   if (pn_encoder_remaining(encoder) >= 16) {
-    memmove(encoder->position, value, 16);
+    char* position = encoder->output+encoder->position;
+    memmove(position, value, 16);
   }
   encoder->position += 16;
 }
@@ -203,16 +207,20 @@ static inline void pn_encoder_writef128(pn_encoder_t 
*encoder, char *value) {
 static inline void pn_encoder_writev8(pn_encoder_t *encoder, const pn_bytes_t 
*value)
 {
   pn_encoder_writef8(encoder, value->size);
-  if (pn_encoder_remaining(encoder) >= value->size)
-    memmove(encoder->position, value->start, value->size);
+  if (pn_encoder_remaining(encoder) >= value->size && value->size) {
+    char* position = encoder->output+encoder->position;
+    memmove(position, value->start, value->size);
+  }
   encoder->position += value->size;
 }
 
 static inline void pn_encoder_writev32(pn_encoder_t *encoder, const pn_bytes_t 
*value)
 {
   pn_encoder_writef32(encoder, value->size);
-  if (pn_encoder_remaining(encoder) >= value->size)
-    memmove(encoder->position, value->start, value->size);
+  if (pn_encoder_remaining(encoder) >= value->size && value->size) {
+    char* position = encoder->output+encoder->position;
+    memmove(position, value->start, value->size);
+  }
   encoder->position += value->size;
 }
 
@@ -339,7 +347,7 @@ static int pni_encoder_enter(void *ctx, pn_data_t *data, 
pni_node_t *node)
 static int pni_encoder_exit(void *ctx, pn_data_t *data, pni_node_t *node)
 {
   pn_encoder_t *encoder = (pn_encoder_t *) ctx;
-  char *pos;
+  size_t pos;
 
   // Special case 0 length list, but not as element in an array
   pni_node_t *parent = pn_data_node(data, node->parent);
@@ -388,12 +396,12 @@ static int pni_encoder_exit(void *ctx, pn_data_t *data, 
pni_node_t *node)
 ssize_t pn_encoder_encode(pn_encoder_t *encoder, pn_data_t *src, char *dst, 
size_t size)
 {
   encoder->output = dst;
-  encoder->position = dst;
+  encoder->position = 0;
   encoder->size = size;
 
   int err = pni_data_traverse(src, pni_encoder_enter, pni_encoder_exit, 
encoder);
   if (err) return err;
-  size_t encoded = encoder->position - encoder->output;
+  size_t encoded = encoder->position;
   if (encoded > size) {
       pn_error_format(pn_data_error(src), PN_OVERFLOW, "not enough space to 
encode");
       return PN_OVERFLOW;
@@ -412,5 +420,5 @@ ssize_t pn_encoder_size(pn_encoder_t *encoder, pn_data_t 
*src)
   pn_data_restore(src, save);
 
   if (err) return err;
-  return encoder->position - encoder->output;
+  return encoder->position;
 }
diff --git a/c/src/core/encoder.h b/c/src/core/encoder.h
index 3a961bf..8ec08e9 100644
--- a/c/src/core/encoder.h
+++ b/c/src/core/encoder.h
@@ -24,7 +24,7 @@
 
 typedef struct pn_encoder_t {
   char *output;
-  char *position;
+  size_t position;
   pn_error_t *error;
   size_t size;
   unsigned null_count;

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to