Included Primer3 modifications
The C sources under primer3/src/libprimer3/ are the included copy of the
open-source Primer3 v2.6.1 library, modified to make them amenable to the
Python C API / Cython bindings (see also Derivative work). In
addition to the pervasive build-glue and API-surface changes, we occasionally
patch this included C to fix bugs that are reachable through the bindings.
This page records those intentional, behavior-affecting divergences from upstream Primer3 so they can be reviewed and re-applied if the included tree is ever updated to a newer upstream release. It is a living document: add an entry here whenever you change the included C in a way that alters behavior (pure mechanical/build changes and comments do not need to be listed).
Each entry notes the file and function, the category of change, what changed and why, and whether it is reachable from the Python API.
Safety / correctness fixes
read_boulder.c — parse_intron_list bounds check
Category: memory-safety fix (out-of-bounds write)
Reachable from Python: yes —
run_design/bindings.design_primersvia theSEQUENCE_OVERLAP_JUNCTION_LISTandSEQUENCE_INTERNAL_OVERLAP_JUNCTION_LISTtags.
parse_intron_list wrote list[*count] and incremented *count with no
check against PR_MAX_INTERVAL_ARRAY (200). The destination arrays
(sa->primer_overlap_junctions, sa->intl_overlap_junctions) are fixed
int[PR_MAX_INTERVAL_ARRAY] fields of seq_args, so a junction list with more
than 200 integers overran the array and corrupted adjacent struct fields. The
sibling interval parsers already bounds-check; this one was the outlier.
The parser now resets *count and returns 0 (its existing error signal, on
which the caller appends an "Error in SEQUENCE_..._JUNCTION_LIST" message)
when the array is full.
oligotm.c — reject sequences shorter than 2 nt in oligotm()
Category: memory-safety + correctness fix (out-of-bounds read / nonsense result)
Reachable from Python: yes —
calc_tm/bindings.calc_tmviaseqtm.
oligotm() computed len = strlen(s) - 1 and then applied the
nearest-neighbor terminal penalty at s[len]. For an empty string len
underflowed to -1, so the code read s[-1] (out of bounds); a 1-nt sequence
produced a nonsense Tm instead of the OLIGOTM_ERROR sentinel that the
function’s own ERROR: label documents for “length < 2”.
oligotm() now returns OLIGOTM_ERROR up front when strlen(s) < 2. Empty
input still returns the same sentinel (now without the OOB read), and 1-nt
input returns the sentinel instead of a meaningless value.
Notes
Line numbers are intentionally omitted; search for the function name and the
primer3-py:comment that marks each patch in the source.When updating the included tree from a newer upstream Primer3, check each entry above against the incoming source and re-apply any patch that upstream has not itself adopted.