Remixware report: firmware

Code in this project that matches third-party code, the licence that code came with, and what that licence asks.

Project
testdata/projects/firmware
Project licence
GPL-2.0-only (from COPYING)
Compared with
upstream.rmx (index: 10 components, 10 files)
Scanned
4 source files, 151 lines
Notice files
none found
Made
2026-10-26T14:06:45Z by remixware 0.2.0
2 CONFLICT1 ATTRIBUTION MISSING

Findings

CONFLICTtools/retry/retry.go lines 5-39RW-d782e687
Matches example.com/retrykit, retry.go lines 12-50. Licence Apache-2.0 (from LICENSE). Copied with some edits (100% match).

Apache-2.0 code can't go into a GPL-2.0-only project: the two licences conflict over patents.

Your code

5    "context"
6    "errors"
7    "time"
8)
9
10var errBricked = errors.New("board does not answer")
11
12func wait(n int, base, max time.Duration, jitter float64, rnd func() float64) time.Duration {
13    d := base
14    for i := 0; i < n && d < max; i++ {
15        d *= 2
16    }
17    if d > max {
18        d = max
19    }
20    if jitter > 0 {
21        spread := float64(d) * jitter
22        d = time.Duration(float64(d) - spread + 2*spread*rnd())
23    }
24    return d
25}
26
27func retryable(err error) bool {
28    if err == nil {
29        return false
30    }
31    if errors.Is(err, errBricked) || errors.Is(err, context.Canceled) {
32        return false
33    }
34    var t interface{ Temporary() bool }
35    if errors.As(err, &t) {
36        return t.Temporary()
37    }
38    return true
39}

Their code

12    "fmt"
13    "math/rand"
14    "time"
15)
16
17// ErrPermanent marks an error that retrying won't fix.
18var ErrPermanent = errors.New("retrykit: permanent error")
19
20// Backoff returns the wait before attempt n, counting from 0: base doubled
21// each time, capped at max, spread by up to jitter either way.
22func Backoff(n int, base, max time.Duration, jitter float64, rnd func() float64) time.Duration {
23    d := base
24    for i := 0; i < n && d < max; i++ {
25        d *= 2
26    }
27    if d > max {
28        d = max
29    }
30    if jitter > 0 {
31        spread := float64(d) * jitter
32        d = time.Duration(float64(d) - spread + 2*spread*rnd())
33    }
34    return d
35}
36
37// Retryable reports whether an error is worth another attempt.
38func Retryable(err error) bool {
39    if err == nil {
40        return false
41    }
42    if errors.Is(err, ErrPermanent) || errors.Is(err, context.Canceled) {
43        return false
44    }
45    var t interface{ Temporary() bool }
46    if errors.As(err, &t) {
47        return t.Temporary()
48    }
49    return true
50}
CONFLICTtools/sortnames/main.go lines 10-37RW-2ff75689
Matches example.org/gplsort, natural.go lines 56-84. Licence GPL-3.0-or-later (from COPYING). Copied with some edits (89% match).

GPL-3.0-or-later code and GPL-2.0-only code can't be combined in one program.

Your code

10func mergeRuns(dst, left, right []string, less func(a, b string) bool) []string {
11    dst = dst[:0]
12    i, j := 0, 0
13    for i < len(left) && j < len(right) {
14        if less(right[j], left[i]) {
15            dst = append(dst, right[j])
16            j++
17        } else {
18            dst = append(dst, left[i])
19            i++
20        }
21    }
22    dst = append(dst, left[i:]...)
23    dst = append(dst, right[j:]...)
24    return dst
25}
26
27func sortNames(names []string, less func(a, b string) bool) {
28    buf := make([]string, len(names))
29    for width := 1; width < len(names); width *= 2 {
30        for lo := 0; lo < len(names); lo += 2 * width {
31            mid := min(lo+width, len(names))
32            hi := min(lo+2*width, len(names))
33            merged := mergeRuns(buf[lo:lo], names[lo:mid], names[mid:hi], less)
34            copy(names[lo:hi], merged)
35        }
36    }
37}

Their code

56func MergeRuns(dst, left, right []string, less func(a, b string) bool) []string {
57    dst = dst[:0]
58    i, j := 0, 0
59    for i < len(left) && j < len(right) {
60        if less(right[j], left[i]) {
61            dst = append(dst, right[j])
62            j++
63        } else {
64            dst = append(dst, left[i])
65            i++
66        }
67    }
68    dst = append(dst, left[i:]...)
69    dst = append(dst, right[j:]...)
70    return dst
71}
72
73// SortNatural sorts names in natural order with a bottom-up merge sort.
74func SortNatural(names []string) {
75    buf := make([]string, len(names))
76    for width := 1; width < len(names); width *= 2 {
77        for lo := 0; lo < len(names); lo += 2 * width {
78            mid := min(lo+width, len(names))
79            hi := min(lo+2*width, len(names))
80            merged := MergeRuns(buf[lo:lo], names[lo:mid], names[mid:hi], NaturalLess)
81            copy(names[lo:hi], merged)
82        }
83    }
84}
ATTRIBUTION MISSINGsrc/strbuf.c lines 2-30RW-36bb1e53
Matches upstream/cstr, strbuf.c lines 2-30. Licence Zlib (from LICENSE). Copied with names changed (100% match).

Don't claim you wrote it, mark it as changed if you changed it, and keep the zlib notice in the source.

Your code

2#include <stdlib.h>
3#include <string.h>
4#include "log.h"
5
6int logbuf_grow(struct logbuf *lb, size_t extra)
7{
8    size_t need = lb->len + extra + 1;
9    if (need <= lb->cap)
10        return 0;
11    size_t cap = lb->cap ? lb->cap : 16;
12    while (cap < need)
13        cap *= 2;
14    char *p = realloc(lb->buf, cap);
15    if (p == NULL)
16        return -1;
17    lb->buf = p;
18    lb->cap = cap;
19    return 0;
20}
21
22int logbuf_append(struct logbuf *lb, const char *s, size_t n)
23{
24    if (logbuf_grow(lb, n) != 0)
25        return -1;
26    memcpy(lb->buf + lb->len, s, n);
27    lb->len += n;
28    lb->buf[lb->len] = '\0';
29    return 0;
30}

Their code

2#include <stdlib.h>
3#include <string.h>
4#include "strbuf.h"
5
6int strbuf_grow(struct strbuf *sb, size_t extra)
7{
8    size_t need = sb->len + extra + 1;
9    if (need <= sb->cap)
10        return 0;
11    size_t cap = sb->cap ? sb->cap : 16;
12    while (cap < need)
13        cap *= 2;
14    char *p = realloc(sb->buf, cap);
15    if (p == NULL)
16        return -1;
17    sb->buf = p;
18    sb->cap = cap;
19    return 0;
20}
21
22int strbuf_append(struct strbuf *sb, const char *s, size_t n)
23{
24    if (strbuf_grow(sb, n) != 0)
25        return -1;
26    memcpy(sb->buf + sb->len, s, n);
27    sb->len += n;
28    sb->buf[sb->len] = '\0';
29    return 0;
30}