--- /dev/null
+--- cvs-fast-export-1.66/export.c.orig 2024-04-07 15:56:24.234143317 +0200
++++ cvs-fast-export-1.66/export.c 2024-04-07 15:59:49.626363945 +0200
+@@ -182,7 +182,7 @@ static void export_blob(node_t *node, vo
+ *cp = '\n';
+ }
+ }
+- if (strlen(cbuf) >= 2 && cbuf[0] == '!' && cbuf[1] == '\n') {
++ if (strnlen(cbuf, len) >= 2 && cbuf[0] == '!' && cbuf[1] == '\n') {
+ extralen = 0;
+ cbuf += 2;
+ clen -= 2;
+@@ -724,7 +724,7 @@ static struct commit_seq *canonicalize(g
+ (((struct commit_seq *)x)->commit->date < \
+ ((struct commit_seq *)y)->commit->date)
+ /* back up as far as we can */
+- while (!is_parent_of(bp - 1, hp) &&
++ while ((bp > history) && !is_parent_of(bp - 1, hp) &&
+ !is_branchroot_of(bp - 1, hp) &&
+ !is_older_than(bp - 1, hp)) {
+ bp--;
--- /dev/null
+--- cvs-fast-export-1.66/atom.c.orig 2024-04-07 15:44:05.728144147 +0200
++++ cvs-fast-export-1.66/atom.c 2024-04-07 15:49:33.189703469 +0200
+@@ -100,24 +100,24 @@ const char *atom(const char *string)
+ hash_bucket_t *b;
+ int len;
+
++#ifdef THREADS
++ if (threads > 1) {
++ pthread_mutex_lock(&bucket_mutex);
++ }
++#endif /* THREADS */
+ while ((b = *head)) {
+ collision:
+ if (b->hash == hash && !strcmp(string, b->string)) {
++#ifdef THREADS
++ if (threads > 1) {
++ pthread_mutex_unlock(&bucket_mutex);
++ }
++#endif /* THREADS */
+ return b->string;
+ }
+ head = &(b->next);
+ }
+-#ifdef THREADS
+- if (threads > 1) {
+- pthread_mutex_lock(&bucket_mutex);
+- }
+-#endif /* THREADS */
+ if ((b = *head)) {
+-#ifdef THREADS
+- if (threads > 1) {
+- pthread_mutex_unlock(&bucket_mutex);
+- }
+-#endif /* THREADS */
+ goto collision;
+ }
+
+@@ -157,24 +157,24 @@ const cvs_number *atom_cvs_number(const
+ number_bucket_t **head = &number_buckets[bucket];
+ number_bucket_t *b;
+
++#ifdef THREADS
++ if (threads > 1) {
++ pthread_mutex_lock(&number_bucket_mutex);
++ }
++#endif /* THREADS */
+ while ((b = *head)) {
+ collision:
+ if (cvs_number_equal(&b->number, &n)) {
++#ifdef THREADS
++ if (threads > 1) {
++ pthread_mutex_unlock(&number_bucket_mutex);
++ }
++#endif /* THREADS */
+ return &b->number;
+ }
+ head = &(b->next);
+ }
+-#ifdef THREADS
+- if (threads > 1) {
+- pthread_mutex_lock(&number_bucket_mutex);
+- }
+-#endif /* THREADS */
+ if ((b = *head)) {
+-#ifdef THREADS
+- if (threads > 1) {
+- pthread_mutex_unlock(&number_bucket_mutex);
+- }
+-#endif /* THREADS */
+ goto collision;
+ }
+
+--- cvs-fast-export-1.66/revcvs.c.orig 2024-04-07 15:44:05.731477463 +0200
++++ cvs-fast-export-1.66/revcvs.c 2024-04-07 15:56:06.944236984 +0200
+@@ -22,6 +22,9 @@
+ #endif
+
+ const master_dir *root_dir = NULL;
++#ifdef THREADS
++static pthread_mutex_t root_dir_mutex = PTHREAD_MUTEX_INITIALIZER;
++#endif
+
+ static const char *fileop_name(const char *rectified) {
+ size_t rlen = strlen(rectified);
+@@ -79,24 +82,24 @@ static const master_dir *atom_dir(const
+ dir_bucket **head = &dir_buckets[HASH_VALUE(dirname) % DIR_BUCKETS];
+ dir_bucket *b;
+
++#ifdef THREADS
++ if (threads > 1) {
++ pthread_mutex_lock(&dir_bucket_mutex);
++ }
++#endif /* THREADS */
+ while ((b = *head)) {
+ collision:
+ if (b->dir.name == dirname) {
++#ifdef THREADS
++ if (threads > 1) {
++ pthread_mutex_unlock(&dir_bucket_mutex);
++ }
++#endif /* THREADS */
+ return &(b->dir);
+ }
+ head = &(b->next);
+ }
+-#ifdef THREADS
+- if (threads > 1) {
+- pthread_mutex_lock(&dir_bucket_mutex);
+- }
+-#endif /* THREADS */
+ if ((b = *head)) {
+-#ifdef THREADS
+- if (threads > 1) {
+- pthread_mutex_unlock(&dir_bucket_mutex);
+- }
+-#endif /* THREADS */
+ goto collision;
+ }
+ b = xmalloc(sizeof(dir_bucket), __func__);
+@@ -859,9 +862,17 @@ cvs_commit *cvs_master_digest(cvs_file *
+ cvs_branch *cb;
+ cvs_version *ctrunk = NULL;
+
++#ifdef THREADS
++ if (threads > 1)
++ pthread_mutex_lock(&root_dir_mutex);
++#endif
+ if (!root_dir) {
+ root_dir = atom_dir(atom("\0"));
+ }
++#ifdef THREADS
++ if (threads > 1)
++ pthread_mutex_unlock(&root_dir_mutex);
++#endif
+ build_rev_master(cvs, master);
+ #if CVSDEBUG
+ char buf[CVS_MAX_REV_LEN];
--- /dev/null
+--- cvs-fast-export-1.66/treepack.c.orig 2024-04-07 16:00:03.669621200 +0200
++++ cvs-fast-export-1.66/treepack.c 2024-04-07 16:01:11.059256119 +0200
+@@ -210,6 +210,7 @@ void revdir_pack_init(void) {
+ frame = frames;
+ nfiles = 0;
+ frames[0].dir = root_dir;
++ frames[0].dirs = xmalloc(0, __func__);
+ frames[0].ndirs = 0;
+ frames[0].hash = hash_init();
+ }
+@@ -253,6 +254,7 @@ void revdir_pack_add(const cvs_commit *f
+
+ const master_dir *parent = frame++->dir;
+ frame->dir = first_subdir(dir, parent);
++ frame->dirs = xmalloc(0, __func__);
+ frame->ndirs = 0;
+ frame->hash = hash_init();
+ continue;
+--- cvs-fast-export-1.66/generate.c.orig 2024-04-07 16:00:03.669621200 +0200
++++ cvs-fast-export-1.66/generate.c 2024-04-07 16:02:04.075635571 +0200
+@@ -1158,7 +1158,7 @@ static node_t *generate_setup(generator_
+ eb->Gfilename = gen->master_name;
+ eb->Gexpand = gen->expand;
+ eb->Gabspath = NULL;
+- Gline(eb) = NULL;
++ Gline(eb) = xmalloc(0, __func__);
+ Ggap(eb) = Ggapsize(eb) = Glinemax(eb) = 0;
+ }
+
+--- cvs-fast-export-1.66/import.c.orig 2024-04-07 16:00:03.669621200 +0200
++++ cvs-fast-export-1.66/import.c 2024-04-07 16:02:53.108703269 +0200
+@@ -347,6 +347,7 @@ void analyze_masters(int argc, const cha
+ striplen = analyzer->striplen;
+
+ forest->textsize = forest->filecount = 0;
++ forest->is_cvs = false;
+ progress_begin("Reading file list...", NO_MAX);
+ for (;;) {
+ struct stat stb;
Summary: Tool to export CVS history into a fast-import stream
Summary(pl.UTF-8): Narzędzie eksportujące historię CVS w postaci strumienia fast-import
Name: cvs-fast-export
-Version: 1.62
+Version: 1.66
Release: 1
License: GPL v2
Group: Development/Version Control
Source0: http://www.catb.org/~esr/cvs-fast-export/%{name}-%{version}.tar.gz
-# Source0-md5: 8ed2dac4c7c1763d8351650d0bb2630c
+# Source0-md5: b619c3dc9c72cc1b14f8b4fefdcb4f32
Patch0: hack-disable-cvsignore.patch
+Patch1: %{name}-tsan.patch
+Patch2: %{name}-asan.patch
+Patch3: %{name}-ubsan.patch
URL: http://www.catb.org/~esr/cvs-fast-export/
BuildRequires: asciidoc
BuildRequires: sed >= 4.0
%prep
%setup -q
%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
%{__sed} -i -e '1s,/usr/bin/env python3$,%{__python3},' cvsconvert cvsstrip
Upstream: https://gitlab.com/esr/cvs-fast-export/issues/13
---- cvs-fast-export-1.62/export.c.orig 2023-12-10 13:22:44.800987007 +0100
-+++ cvs-fast-export-1.62/export.c 2023-12-10 13:24:03.297228423 +0100
-@@ -570,8 +570,10 @@ export_commit(git_commit *commit, const
- }
- if (need_ignores) {
- need_ignores = false;
-+ if (!getenv("DISABLE_GITIGNORE")) {
- printf("M 100644 inline .gitignore\ndata %d\n%s\n",
- (int)sizeof(CVS_IGNORES)-1, CVS_IGNORES);
-+ }
- }
- if (revpairs != NULL && strlen(revpairs) > 0)
- {
+--- cvs-fast-export-1.66/export.c.orig 2024-04-07 15:42:44.128586210 +0200
++++ cvs-fast-export-1.66/export.c 2024-04-07 15:43:38.798290039 +0200
+@@ -581,8 +581,10 @@ static void export_commit(git_commit *co
+ }
+ if (need_ignores) {
+ need_ignores = false;
++ if (!getenv("DISABLE_GITIGNORE")) {
+ printf("M 100644 inline .gitignore\ndata %d\n%s\n",
+ (int)sizeof(CVS_IGNORES) - 1, CVS_IGNORES);
++ }
+ }
+ if (revpairs != NULL && strlen(revpairs) > 0) {
+ if (opts->revision_map) {