Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package difftastic for openSUSE:Factory 
checked in at 2026-09-24 23:01:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/difftastic (Old)
 and      /work/SRC/openSUSE:Factory/.difftastic.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "difftastic"

Thu Sep 24 23:01:06 2026 rev:21 rq:1380182 version:0.71.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/difftastic/difftastic.changes    2026-09-22 
15:55:15.244275962 +0200
+++ /work/SRC/openSUSE:Factory/.difftastic.new.383539/difftastic.changes        
2026-09-24 23:02:34.161048523 +0200
@@ -1,0 +2,7 @@
+Thu Sep 24 12:21:59 UTC 2026 - Andrei Dziahel <[email protected]>
+
+- Fix heap corruption in the Haskell parser
+  * Add tree-sitter-haskell-fix-heap-corruption.patch with the upstream
+    strict-aliasing fix from tree-sitter-haskell for difftastic issue #1036.
+
+-------------------------------------------------------------------

New:
----
  tree-sitter-haskell-fix-heap-corruption.patch

----------(New B)----------
  New:- Fix heap corruption in the Haskell parser
  * Add tree-sitter-haskell-fix-heap-corruption.patch with the upstream
    strict-aliasing fix from tree-sitter-haskell for difftastic issue #1036.
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ difftastic.spec ++++++
--- /var/tmp/diff_new_pack.22qwpS/_old  2026-09-24 23:02:34.946081348 +0200
+++ /var/tmp/diff_new_pack.22qwpS/_new  2026-09-24 23:02:34.947081390 +0200
@@ -33,6 +33,7 @@
 Source1:        vendor.tar.xz
 Patch0:         remove-jq-dependency.patch
 Patch1:         reproducible.patch
+Patch2:         tree-sitter-haskell-fix-heap-corruption.patch
 BuildRequires:  cargo-packaging
 BuildRequires:  fdupes
 BuildRequires:  gcc-c++

++++++ tree-sitter-haskell-fix-heap-corruption.patch ++++++
Fix strict-aliasing heap corruption in the vendored Haskell parser.

Upstream fix: tree-sitter-grammars/tree-sitter-haskell commit
98aedbd2d6947a168ba3ba3755d70b0cb6b78395 (difftastic issue #1036).

--- 
difftastic-0.71.0.orig/vendor/tree-sitter-haskell-0.23.1/src/tree_sitter/array.h
+++ difftastic-0.71.0/vendor/tree-sitter-haskell-0.23.1/src/tree_sitter/array.h
@@ -7,20 +7,21 @@
 
 #include "./alloc.h"
 
 #include <assert.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 
 #ifdef _MSC_VER
+#pragma warning(push)
 #pragma warning(disable : 4101)
 #elif defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-variable"
 #endif
 
 #define Array(T)       \
   struct {             \
     T *contents;       \
     uint32_t size;     \
@@ -44,81 +45,110 @@
 
 /// Get a pointer to the last element in the array.
 #define array_back(self) array_get(self, (self)->size - 1)
 
 /// Clear the array, setting its size to zero. Note that this does not free any
 /// memory allocated for the array's contents.
 #define array_clear(self) ((self)->size = 0)
 
 /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is
 /// less than the array's current capacity, this function has no effect.
-#define array_reserve(self, new_capacity) \
-  _array__reserve((Array *)(self), array_elem_size(self), new_capacity)
+#define array_reserve(self, new_capacity)        \
+  ((self)->contents = _array__reserve(           \
+    (void *)(self)->contents, &(self)->capacity, \
+    array_elem_size(self), new_capacity)         \
+  )
 
 /// Free any memory allocated for this array. Note that this does not free any
 /// memory allocated for the array's contents.
-#define array_delete(self) _array__delete((Array *)(self))
+#define array_delete(self)                           \
+  do {                                               \
+    if ((self)->contents) ts_free((self)->contents); \
+    (self)->contents = NULL;                         \
+    (self)->size = 0;                                \
+    (self)->capacity = 0;                            \
+  } while (0)
 
 /// Push a new `element` onto the end of the array.
-#define array_push(self, element)                            \
-  (_array__grow((Array *)(self), 1, array_elem_size(self)), \
-   (self)->contents[(self)->size++] = (element))
+#define array_push(self, element)                                 \
+  do {                                                            \
+    (self)->contents = _array__grow(                              \
+      (void *)(self)->contents, (self)->size, &(self)->capacity,  \
+      1, array_elem_size(self)                                    \
+    );                                                            \
+   (self)->contents[(self)->size++] = (element);                  \
+  } while(0)
 
 /// Increase the array's size by `count` elements.
 /// New elements are zero-initialized.
-#define array_grow_by(self, count) \
-  do { \
-    if ((count) == 0) break; \
-    _array__grow((Array *)(self), count, array_elem_size(self)); \
+#define array_grow_by(self, count)                                             
  \
+  do {                                                                         
  \
+    if ((count) == 0) break;                                                   
  \
+    (self)->contents = _array__grow(                                           
  \
+      (self)->contents, (self)->size, &(self)->capacity,                       
  \
+      count, array_elem_size(self)                                             
  \
+    );                                                                         
  \
     memset((self)->contents + (self)->size, 0, (count) * 
array_elem_size(self)); \
-    (self)->size += (count); \
+    (self)->size += (count);                                                   
  \
   } while (0)
 
 /// Append all elements from one array to the end of another.
-#define array_push_all(self, other)                                       \
+#define array_push_all(self, other) \
   array_extend((self), (other)->size, (other)->contents)
 
 /// Append `count` elements to the end of the array, reading their values from 
the
 /// `contents` pointer.
-#define array_extend(self, count, contents)                    \
-  _array__splice(                                               \
-    (Array *)(self), array_elem_size(self), (self)->size, \
-    0, count,  contents                                        \
+#define array_extend(self, count, other_contents)                 \
+  (self)->contents = _array__splice(                              \
+    (void*)(self)->contents, &(self)->size, &(self)->capacity,    \
+    array_elem_size(self), (self)->size, 0, count, other_contents \
   )
 
 /// Remove `old_count` elements from the array starting at the given `index`. 
At
 /// the same index, insert `new_count` new elements, reading their values from 
the
 /// `new_contents` pointer.
-#define array_splice(self, _index, old_count, new_count, new_contents)  \
-  _array__splice(                                                       \
-    (Array *)(self), array_elem_size(self), _index,                \
-    old_count, new_count, new_contents                                 \
+#define array_splice(self, _index, old_count, new_count, new_contents) \
+  (self)->contents = _array__splice(                                   \
+    (void *)(self)->contents, &(self)->size, &(self)->capacity,        \
+    array_elem_size(self), _index, old_count, new_count, new_contents  \
   )
 
 /// Insert one `element` into the array at the given `index`.
-#define array_insert(self, _index, element) \
-  _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, 
&(element))
+#define array_insert(self, _index, element)                     \
+  (self)->contents = _array__splice(                            \
+    (void *)(self)->contents, &(self)->size, &(self)->capacity, \
+    array_elem_size(self), _index, 0, 1, &(element)             \
+  )
 
 /// Remove one element from the array at the given `index`.
 #define array_erase(self, _index) \
-  _array__erase((Array *)(self), array_elem_size(self), _index)
+  _array__erase((void *)(self)->contents, &(self)->size, 
array_elem_size(self), _index)
 
 /// Pop the last element off the array, returning the element by value.
 #define array_pop(self) ((self)->contents[--(self)->size])
 
 /// Assign the contents of one array to another, reallocating if necessary.
-#define array_assign(self, other) \
-  _array__assign((Array *)(self), (const Array *)(other), 
array_elem_size(self))
+#define array_assign(self, other)                                   \
+  (self)->contents = _array__assign(                                \
+    (void *)(self)->contents, &(self)->size, &(self)->capacity,     \
+    (const void *)(other)->contents, (other)->size, array_elem_size(self) \
+  )
 
 /// Swap one array with another
-#define array_swap(self, other) \
-  _array__swap((Array *)(self), (Array *)(other))
+#define array_swap(self, other)                                     \
+  do {                                                              \
+    void *_array_swap_tmp = (void *)(self)->contents;               \
+    (self)->contents = (other)->contents;                           \
+    (other)->contents = _array_swap_tmp;                            \
+    _array__swap(&(self)->size, &(self)->capacity,                  \
+                 &(other)->size, &(other)->capacity);               \
+  } while (0)
 
 /// Get the size of the array contents
 #define array_elem_size(self) (sizeof *(self)->contents)
 
 /// Search a sorted array for a given `needle` value, using the given `compare`
 /// callback to determine the order.
 ///
 /// If an existing element is found to be equal to `needle`, then the `index`
 /// out-parameter is set to the existing value's index, and the `exists`
 /// out-parameter is set to true. Otherwise, `index` is set to an index where
@@ -148,115 +178,125 @@
 ///
 /// See also `array_search_sorted_by`.
 #define array_insert_sorted_by(self, field, value) \
   do { \
     unsigned _index, _exists; \
     array_search_sorted_by(self, field, (value) field, &_index, &_exists); \
     if (!_exists) array_insert(self, _index, value); \
   } while (0)
 
 // Private
-
-typedef Array(void) Array;
 
-/// This is not what you're looking for, see `array_delete`.
-static inline void _array__delete(Array *self) {
-  if (self->contents) {
-    ts_free(self->contents);
-    self->contents = NULL;
-    self->size = 0;
-    self->capacity = 0;
-  }
-}
+// Pointers to individual `Array` fields (rather than the entire `Array` 
itself)
+// are passed to the various `_array__*` functions below to address strict 
aliasing
+// violations that arises when the _entire_ `Array` struct is passed as 
`Array(void)*`.
+//
+// The `Array` type itself was not altered as a solution in order to avoid 
breakage
+// with existing consumers (in particular, parsers with external scanners).
 
 /// This is not what you're looking for, see `array_erase`.
-static inline void _array__erase(Array *self, size_t element_size,
-                                uint32_t index) {
-  assert(index < self->size);
-  char *contents = (char *)self->contents;
+static inline void _array__erase(void* self_contents, uint32_t *size,
+                                size_t element_size, uint32_t index) {
+  assert(index < *size);
+  char *contents = (char *)self_contents;
   memmove(contents + index * element_size, contents + (index + 1) * 
element_size,
-          (self->size - index - 1) * element_size);
-  self->size--;
+          (*size - index - 1) * element_size);
+  (*size)--;
 }
 
 /// This is not what you're looking for, see `array_reserve`.
-static inline void _array__reserve(Array *self, size_t element_size, uint32_t 
new_capacity) {
-  if (new_capacity > self->capacity) {
-    if (self->contents) {
-      self->contents = ts_realloc(self->contents, new_capacity * element_size);
+static inline void *_array__reserve(void *contents, uint32_t *capacity,
+                                  size_t element_size, uint32_t new_capacity) {
+  void *new_contents = contents;
+  if (new_capacity > *capacity) {
+    if (contents) {
+      new_contents = ts_realloc(contents, new_capacity * element_size);
     } else {
-      self->contents = ts_malloc(new_capacity * element_size);
+      new_contents = ts_malloc(new_capacity * element_size);
     }
-    self->capacity = new_capacity;
+    *capacity = new_capacity;
   }
+  return new_contents;
 }
 
 /// This is not what you're looking for, see `array_assign`.
-static inline void _array__assign(Array *self, const Array *other, size_t 
element_size) {
-  _array__reserve(self, element_size, other->size);
-  self->size = other->size;
-  memcpy(self->contents, other->contents, self->size * element_size);
+static inline void *_array__assign(void* self_contents, uint32_t *self_size, 
uint32_t *self_capacity,
+                                 const void *other_contents, uint32_t 
other_size, size_t element_size) {
+  void *new_contents = _array__reserve(self_contents, self_capacity, 
element_size, other_size);
+  *self_size = other_size;
+  memcpy(new_contents, other_contents, *self_size * element_size);
+  return new_contents;
 }
 
 /// This is not what you're looking for, see `array_swap`.
-static inline void _array__swap(Array *self, Array *other) {
-  Array swap = *other;
-  *other = *self;
-  *self = swap;
+static inline void _array__swap(uint32_t *self_size, uint32_t *self_capacity,
+                               uint32_t *other_size, uint32_t *other_capacity) 
{
+  uint32_t tmp_size = *self_size;
+  uint32_t tmp_capacity = *self_capacity;
+  *self_size = *other_size;
+  *self_capacity = *other_capacity;
+  *other_size = tmp_size;
+  *other_capacity = tmp_capacity;
 }
 
 /// This is not what you're looking for, see `array_push` or `array_grow_by`.
-static inline void _array__grow(Array *self, uint32_t count, size_t 
element_size) {
-  uint32_t new_size = self->size + count;
-  if (new_size > self->capacity) {
-    uint32_t new_capacity = self->capacity * 2;
+static inline void *_array__grow(void *contents, uint32_t size, uint32_t 
*capacity,
+                               uint32_t count, size_t element_size) {
+  void *new_contents = contents;
+  uint32_t new_size = size + count;
+  if (new_size > *capacity) {
+    uint32_t new_capacity = *capacity * 2;
     if (new_capacity < 8) new_capacity = 8;
     if (new_capacity < new_size) new_capacity = new_size;
-    _array__reserve(self, element_size, new_capacity);
+    new_contents = _array__reserve(contents, capacity, element_size, 
new_capacity);
   }
+  return new_contents;
 }
 
 /// This is not what you're looking for, see `array_splice`.
-static inline void _array__splice(Array *self, size_t element_size,
+static inline void *_array__splice(void *self_contents, uint32_t *size, 
uint32_t *capacity,
+                                 size_t element_size,
                                  uint32_t index, uint32_t old_count,
                                  uint32_t new_count, const void *elements) {
-  uint32_t new_size = self->size + new_count - old_count;
+  uint32_t new_size = *size + new_count - old_count;
   uint32_t old_end = index + old_count;
   uint32_t new_end = index + new_count;
-  assert(old_end <= self->size);
+  assert(old_end <= *size);
 
-  _array__reserve(self, element_size, new_size);
+  void *new_contents = _array__reserve(self_contents, capacity, element_size, 
new_size);
 
-  char *contents = (char *)self->contents;
-  if (self->size > old_end) {
+  char *contents = (char *)new_contents;
+  if (*size > old_end) {
     memmove(
       contents + new_end * element_size,
       contents + old_end * element_size,
-      (self->size - old_end) * element_size
+      (*size - old_end) * element_size
     );
   }
   if (new_count > 0) {
     if (elements) {
       memcpy(
         (contents + index * element_size),
         elements,
         new_count * element_size
       );
     } else {
       memset(
         (contents + index * element_size),
         0,
         new_count * element_size
       );
     }
   }
-  self->size += new_count - old_count;
+  *size += new_count - old_count;
+
+  return new_contents;
 }
 
 /// A binary search routine, based on Rust's `std::slice::binary_search_by`.
 /// This is not what you're looking for, see `array_search_sorted_with` or 
`array_search_sorted_by`.
 #define _array__search_sorted(self, start, compare, suffix, needle, _index, 
_exists) \
   do { \
     *(_index) = start; \
     *(_exists) = false; \
     uint32_t size = (self)->size - *(_index); \
     if (size == 0) break; \
@@ -271,20 +311,20 @@
     comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \
     if (comparison == 0) *(_exists) = true; \
     else if (comparison < 0) *(_index) += 1; \
   } while (0)
 
 /// Helper macro for the `_sorted_by` routines below. This takes the left 
(existing)
 /// parameter by reference in order to work with the generic sorting function 
above.
 #define _compare_int(a, b) ((int)*(a) - (int)(b))
 
 #ifdef _MSC_VER
-#pragma warning(default : 4101)
+#pragma warning(pop)
 #elif defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic pop
 #endif
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif  // TREE_SITTER_ARRAY_H_
--- 
difftastic-0.71.0.orig/vendor/tree-sitter-haskell-0.23.1/.cargo-checksum.json
+++ difftastic-0.71.0/vendor/tree-sitter-haskell-0.23.1/.cargo-checksum.json
@@ -1 +1 @@
-{"$comment":"This file only protects against accidental modifications. It is 
not a security mechanism and does not protect against malicious 
changes.","files":{".cargo_vcs_info.json":"388da105d4ddc5b0df137c0ce8317189e544f1c2770be4df7530b852732975b8","Cargo.toml":"fe8a38ea6a662ec2a71c84a73ac453fa6500474b66be01e2c15cbd668270e704","Cargo.toml.orig":"5920f305f9058a57495037200b5a22538453fe3dfa8a3ce836f2c7057c02d682","README.md":"e9ec7650b46ecc583d56d9feefbadb187b209eb440994f0e3ac17f6a3bc1ad1a","bindings/rust/build.rs":"ea5f63728090e0d756513ea78d970f274ea06a9b1131e7c2ffa87e0c33896fa8","bindings/rust/lib.rs":"3d656783d7992ee9eea9ba485aaf102435f915ecf877a90586c91643643d16f1","grammar.js":"a8bd15e99d2e276685ab2f41d58eef2c00e6e47615aad9dc6691065fc75e9873","queries/highlights.scm":"f8232b2c9b79ca3038c08c0b13602776019039d8e7668c60c18dcbc373c32e16","queries/injections.scm":"156d5d5e67ff199cb768a7ce72eccacfbfd2de9701f7f8c44cb016a4cddfc04e","queries/locals.scm":"bc584a6e978e99f2456a238dbe8560501fa
 
065110df9541a8580794e199033c2","src/grammar.json":"509bd0c498d149234296d0cf6a5e93de3320679371ead4ce97d1c266b3102c3e","src/node-types.json":"da12ac400f963fa2a2de6a331d538763602709db83be1d1a5b170b417e09ab3e","src/parser.c":"f05f34d3cabb3c4a0397a2ac29d4cf4212f814dec98199042228d1850055db93","src/scanner.c":"344cd5c8161dbfafdf76438343672e035f20c62d0cbba63fd1e62c730b016c67","src/tree_sitter/alloc.h":"b29c1c9fb7cc82f58c84b376df1297d6e2737a1d655fd356db0859e3c29c2fea","src/tree_sitter/array.h":"4ff743903dc46f5db6aa54f31c6b4d160a8a9779e5b2ab1ee59ae7ebcd850ea1","src/tree_sitter/parser.h":"a1f6ef161fbaf48a0e10fca90ef5290a062462b307b3898aa562993853b9f80a","src/unicode.h":"5dc193ae6173ddeeb9d0d724cad043b7299353c0edeff125059df1ccb0b685e5","tree-sitter.json":"ebc13cd7ec0f4c027100a75fb73d95201fed70e5e769bf964b3068e1c274b3c3"},"package":"977c51e504548cba13fc27cb5a2edab2124cf6716a1934915d07ab99523b05a4"}
\ No newline at end of file
+{"$comment":"This file only protects against accidental modifications. It is 
not a security mechanism and does not protect against malicious 
changes.","files":{".cargo_vcs_info.json":"388da105d4ddc5b0df137c0ce8317189e544f1c2770be4df7530b852732975b8","Cargo.toml":"fe8a38ea6a662ec2a71c84a73ac453fa6500474b66be01e2c15cbd668270e704","Cargo.toml.orig":"5920f305f9058a57495037200b5a22538453fe3dfa8a3ce836f2c7057c02d682","README.md":"e9ec7650b46ecc583d56d9feefbadb187b209eb440994f0e3ac17f6a3bc1ad1a","bindings/rust/build.rs":"ea5f63728090e0d756513ea78d970f274ea06a9b1131e7c2ffa87e0c33896fa8","bindings/rust/lib.rs":"3d656783d7992ee9eea9ba485aaf102435f915ecf877a90586c91643643d16f1","grammar.js":"a8bd15e99d2e276685ab2f41d58eef2c00e6e47615aad9dc6691065fc75e9873","queries/highlights.scm":"f8232b2c9b79ca3038c08c0b13602776019039d8e7668c60c18dcbc373c32e16","queries/injections.scm":"156d5d5e67ff199cb768a7ce72eccacfbfd2de9701f7f8c44cb016a4cddfc04e","queries/locals.scm":"bc584a6e978e99f2456a238dbe8560501fa
 
065110df9541a8580794e199033c2","src/grammar.json":"509bd0c498d149234296d0cf6a5e93de3320679371ead4ce97d1c266b3102c3e","src/node-types.json":"da12ac400f963fa2a2de6a331d538763602709db83be1d1a5b170b417e09ab3e","src/parser.c":"f05f34d3cabb3c4a0397a2ac29d4cf4212f814dec98199042228d1850055db93","src/scanner.c":"344cd5c8161dbfafdf76438343672e035f20c62d0cbba63fd1e62c730b016c67","src/tree_sitter/alloc.h":"b29c1c9fb7cc82f58c84b376df1297d6e2737a1d655fd356db0859e3c29c2fea","src/tree_sitter/array.h":"31e60a1bff6f715afacce03b5b70efe42b58371b4f9595dd4af52a577ff9608c","src/tree_sitter/parser.h":"a1f6ef161fbaf48a0e10fca90ef5290a062462b307b3898aa562993853b9f80a","src/unicode.h":"5dc193ae6173ddeeb9d0d724cad043b7299353c0edeff125059df1ccb0b685e5","tree-sitter.json":"ebc13cd7ec0f4c027100a75fb73d95201fed70e5e769bf964b3068e1c274b3c3"},"package":"977c51e504548cba13fc27cb5a2edab2124cf6716a1934915d07ab99523b05a4"}
\ No newline at end of file

Reply via email to