Compare commits

...
178 Commits
Author SHA1 Message Date
Mark Johnston bd31ee522f Add UPDATING entries and bump version
Approved by:	so
2026-10-20 21:55:26 +00:00
Dag-Erling Smørgrav 091c8ad19f ObsoleteFiles.inc: Add moved certificates
These two moved from trusted to untrusted.

Approved by:	so
Security:	FreeBSD-SA-26:73.caroot
Fixes:		21ac476142 ("ObsoleteFiles.inc: Add dropped certificates")
(cherry picked from commit dd6a1fef0e)
2026-10-20 21:55:26 +00:00
Dag-Erling Smørgrav 7410d52364 ObsoleteFiles.inc: Add dropped certificates
Approved by:	so
Security:	FreeBSD-SA-26:73.caroot
Reported by:	michaelo@
Fixes:		82af7f44eb ("caroot: Regenerate")

(cherry picked from commit 21ac476142)
2026-10-20 21:55:26 +00:00
Dag-Erling Smørgrav 96a1404d5b caroot: Regenerate
Regenerate using certificate data from NSS 3.131.1.

Upstream dropped emSign_ECC_Root_CA_-_G3.pem entirely; we deliberately
move it to untrusted instead to block its reintroduction through e.g.
an outdated copy of security/ca_root_nss.

Approved by:	so
Security:	FreeBSD-SA-26:73.caroot
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D60906

(cherry picked from commit 82af7f44eb)
2026-10-20 21:55:24 +00:00
Dag-Erling Smørgrav 9686673eed caroot: Regenerate
Regenerate using certificate data from NSS 3.123.1.

Approved by:	so
Security:	FreeBSD-SA-26:73.caroot
MFC after:	1 week
Reviewed by:	kevans

(cherry picked from commit 07b52233e8)
(cherry picked from commit 09bb6a62d0)
2026-10-20 21:55:13 +00:00
Dag-Erling Smørgrav e303b980d0 caroot: Clean up
* Get certdata.txt directly from the NSS Mercurial repository, rather
  than from the Mozilla Firefox repository which imports it from NSS at
  irregular intervals.

* Instead of always fetching the latest certdata.txt, fetch a specific
  version.  For this commit, we set this to the version that was last
  imported in May 2025.

* Add a refrence to the MPL to the generated files.

* Regenerate with latest OpenSSL.  This is purely cosmetic; mostly, the
  certificate names now contain less unnecessary whitespace and some
  elements are quoted.

Approved by:	so
Security:	FreeBSD-SA-26:73.caroot
MFC after:	1 week
Reviewed by:	michaelo, kevans
Differential Revision:	https://reviews.freebsd.org/D56620

(cherry picked from commit ce33d6396a)
(cherry picked from commit 7e064a35a7)
2026-10-20 20:39:48 +00:00
Dag-Erling Smørgrav 1258151af5 caroot: Rename script and normalize license
Approved by:	so
Security:	FreeBSD-SA-26:73.caroot
MFC after:	1 week
Reviewed by:	mandree, markj
Differential Revision:	https://reviews.freebsd.org/D51775

(cherry picked from commit 0886019bf8)
(cherry picked from commit dbf17ec890)
2026-10-20 20:39:36 +00:00
Dag-Erling Smørgrav 2540afe9af caroot: Generate both trusted and untrusted
Until now, the untrusted directory has been maintained manually.  Modify
the script used to maintain the trusted directory so it can handle both.
While here, clean it up a bit.

Approved by:	so
Security:	FreeBSD-SA-26:73.caroot
MFC after:	1 week
Reviewed by:	mandree, markj
Differential Revision:	https://reviews.freebsd.org/D51774

(cherry picked from commit b88b0bb784)
(cherry picked from commit ca80ae39e8)
2026-10-20 20:39:24 +00:00
Mark Johnston 5dd0f22460 Add UPDATING entries and bump version
Approved by:	so
2026-10-13 23:16:51 +00:00
Mark Johnston 00ec12d48c bhyve: Fix handling of framebuffer resizing
The rfb code maintains an array of CRCs for 32x32 tiles in the
framebuffer.  This array is sized statically based on the rfb code's
notion of the maximum framebuffer size, which changed in commit
fb51ddb20d without updating the rfb code.

Morever, writes to the framebuffer BAR can modify the recorded height
and width of the framebuffer.  These values were not validated against
the maximum at all, unlike the parameters set via bhyve config.

Fix these problems:
- Define the maximum width and height in a shared header file so that
  they do not get out of sync again.
- In pci_fbuf_render(), don't resize the console if the new dimensions
  are too large.
- Add a mutex to synchronize framebuffer BAR I/O with the rfb thread.

Approved by:	so
Security:	FreeBSD-SA-26:72.bhyve
Security:	CVE-2026-101311
Fixes:		fb51ddb20d ("bhyve: increase fbuf display resolution limit")
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D60680
2026-10-13 23:16:51 +00:00
Mark Johnston 1fe825bba4 bhyve: Improve HDA stream descriptor validation
The length of each block in the stream must be non-zero.  This is
assumed in hda_transfer(), otherwise an out-of-bounds read or write is
possible.

Use atomic loads to access stream descriptor fields, since they are
guest-controlled.  Make sure that the descriptor array is suitably
aligned so that we can drop the __packed annotation from the structure
definition; per section 3.3.42 of the HDA spec the BDL pointer is
supposed to be 128-byte aligned, in fact.

Approved by:	so
Security:	FreeBSD-SA-26:72.bhyve
Security:	CVE-2026-101310
Reported by:	Brian Delgado from Intel using Anthropic Opus 4.8
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D60678
2026-10-13 20:22:00 +00:00
Mark Johnston 409554009e bhyve: Fix handling of the xhci event ring
rts->erst_p and rts->erstba_p are pointers to guest-controlled memory
which describe the event rings and pending event array, respectively.
The device model was not validating the size nor saving the value.
As a result, the bounds checks in pci_xhci_insert_event() were
susceptible to TOCTOU races.

Fix pci_xhci_rtsregs_write() to save the ring size in a softc field.
Validate that the size isn't larger than the maximum allowed by the XHCI
specification (64KB, or 4096 TRBs).

When processing TRBs, make sure we don't load fields more than once.
Make sure that pci_xhci_trb_next() doesn't return a pointer to host
memory.  When handling ERDP writes, make sure that the guest-supplied
address is actually a pointer into the TRB array, and ignore the write
if not.

Approved by:	so
Security:	FreeBSD-SA-26:72.bhyve
Security:	CVE-2026-101309
Reported by:	Brian Delgado from Intel using Anthropic Opus 4.8
Differential Revision:	https://reviews.freebsd.org/D60677
2026-10-13 20:22:00 +00:00
Mark Johnston ea6ecd1e37 sound: Revalidate after reacquiring locks when resizing buffers
sndbuf_resize() and sndbuf_remalloc() drop the channel lock in order to
allocate the new buffer(s) with M_WAITOK.  Before doing that they verify
that the buffer is not mapped, but this could change while the lock is
dropped, as there is no higher-level synchronization which prevents
buffer resize (e.g., via the SNDCTL_DSP_SETBLKSIZE ioctl) from happening
concurrently with mmap.  Thus, these checks are insufficient.

Modify sndbuf_resize() and sndbuf_remalloc() to revalidate after
reacquiring the lock.  Extend them to check for a couple of channel
flags, mirroring the check in chn_resizebuf().  Modify chn_resizebuf()
to revalidate state after reacquiring the channel lock.

We could also allocate new buffers with M_NOWAIT and so avoid dropping
the lock.  Then, I think we could go even further and invoke
CHANNEL_SETBLOCKSIZE and CHANNEL_SETFRAGMENTS with the channel lock
held.  But really it would be better to ensure that dsp operations are
serialized; there is no reason for mmap and chn_resizebuf() to be able
to run in parallel, we should not be relying on the channel lock for
this.  So, let's keep a more minimal approach here.

Add a simple regression test.

Approved by:	so
Security:	FreeBSD-SA-26:71.sound
Security:	CVE-2026-101308
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D60554
2026-10-13 16:54:40 +00:00
Mark Johnston 7944824ae3 sound: Check for errors from sndbuf_resize()
Most implementations of CHANNEL_SETBLOCKSIZE and CHANNEL_SETFRAGMENTS
were not checking this.  This is probably not a big problem: it's
unlikely for sndbuf_resize() to fail due to the refcount check in this
case since it's operating on the hardware buffer, which doesn't get
mmaped.  But, I will add more reasons for it to fail in the next patch,
so let's be more careful.

This change modifies various CHANNEL_SETBLOCKSIZE implementations to
check for errors.  In some cases I reordered things to avoid updating
driver state until after sndbuf_resize() succeeds.

Return 0 from CHANNEL_SETBLOCKSIZE to indicate an error, as it otherwise
returns the new block size.  We could change the interface to return
both an error number and a block size, but that would break at least one
out-of-tree driver and I wish to avoid that here.  Make sure that errors
from CHANNEL_SETFRAGMENTS are returned to userspace.

Approved by:	so
Security:	FreeBSD-SA-26:71.sound
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D60553
2026-10-13 16:54:40 +00:00
Michael Tuexen 11f0c61eec tcp: improve handling of stopped timers
When a TCP timer is stopped, t_timers[] is set to SBT_MAX. Adding the
corresponding t_precisions[], if it is not zero, would result in
overflows in tcp_timer_next(). To avoid this, skip stopped timers.

The problem was identified while debugging uperf by Lukas Book and
an initial patch was provided by him. The committed patch was
suggested by glebius.

The problem can be observed by running netstat -nxptcp and looking for
negative timer values and by observing very long running timers in
some cases.

Approved by:		so
Security:		FreeBSD-EN-26:27.tcp
Reported by:		Lukas Book <[email protected]>
Reviewed by:		glebius
Differential Revision:	https://reviews.freebsd.org/D58484

(cherry picked from commit 52b7cbcb78)
(cherry picked from commit 85485a570d)
2026-10-13 13:47:11 +00:00
Dag-Erling Smørgrav 1c821dc49b hastd: Use fixed-length protocol names
All communication between hastd nodes and internally between hastd and
its worker children passes through the same pair of send / receive
functions.  The receive function uses recv(2) with the MSG_WAITALL flag,
which in theory means we should never get a short read.  However, when
handing off a socket to a worker child, we also pass a variable-length
string identifying the type of socket we're passing, and reading this
string relies on a short read.  This used to work because the arrival of
the descriptor would interrupt the recv(2) call, but this bug was fixed
when the AF_UNIX code was rewritten a while ago and hastd has been
broken ever since.

Fixing the length of the protocol name to four characters including the
terminating null solves the short-read bug by never requiring a short
read (nothing else in hastd requires one).

Note that this issue appears to have been reported independently first
by Alessandro Sagratini in PR 292322 and then by Martin Vidovic in
D57511.  I ended up going in a different direction than Martin's patch,
but his analysis was invaluable, hence the double credit below.

Approved by:	so
Security:	FreeBSD-EN-26:26.hastd
PR:		292322
Reported by:	Martin Vidovic <[email protected]>
MFC after:	1 week
Event:		EuroBSDcon DevSummit 2026
Reviewed by:	xtronom_gmail.com, kevans, glebius, gjb
Differential Revision:	https://reviews.freebsd.org/D59521

(cherry picked from commit b7e5c2e008)
(cherry picked from commit 9401bfb061)
2026-10-13 13:47:11 +00:00
Dag-Erling Smørgrav e1d55e72b3 hastd: Ensure nvpair padding is initialized
The proto-libnv implementation embedded in hastd pads names and values
out to the nearest multiple of eight bytes, but leaves the padding
uninitialized, leaking up to 14 bytes of recycled heap per pair in a
message.

While here, switch from bcopy() to memcpy().

Approved by:	so
Security:	FreeBSD-EN-26:26.hastd
MFC after:	3 days
Reviewed by:	kevans, emaste
Differential Revision:	https://reviews.freebsd.org/D59343

(cherry picked from commit 911bda7cff)
(cherry picked from commit e4b16e7868)
2026-10-13 13:47:11 +00:00
Glen Barber a6ccb9d690 hastd: Fix crash on empty message
A HAST message can be empty, in which case ebuf_add_tail() does nothing
and ebuf_data() returns NULL because the size of the ebuf is zero, but
hast_proto_recv_hdr() asserts that the return value is not NULL,
resulting in an immediate crash if hastctl or hastd receive an empty
message.  This is trivially reproducable by running `hastctl status` or
`hastctl role init` (as the rc script does prior to stopping hastd).

To avoid this, don't try to grow the ebuf or receive additional data
if the header size is zero.

Approved by:	so
Security:	FreeBSD-EN-26:26.hastd
PR:		298085
MFC after:	3 days
Reviewed by:	kevans, gjb
Differential Revision:	https://reviews.freebsd.org/D59306

(cherry picked from commit 8646d65b45)
(cherry picked from commit 4d83686bc3)
2026-10-13 13:47:11 +00:00
Philip Paeps 24aef4c96a contrib/tzdata: import tzdata 2026e
Changes: https://github.com/eggert/tz/blob/2026e/NEWS

Briefly:
    Manitoba moves to permanent -05 on 2026-10-31.

Approved by:	so
Security:	FreeBSD-EN-26:25.tzdata

(cherry picked from commit f11af65350)
(cherry picked from commit 7b8c805722)
2026-10-08 14:36:47 +00:00
Mark Johnston 8b3713b741 Add UPDATING entries and bump version
Approved by:	so
2026-09-28 18:20:48 +00:00
Gordon Tetlow 49084ed8ec openssl: Fix CVE-2026-84782
This is a backport of an upstream commit to fix:
  dtls: reset init_off before retransmitting a message

Approved by:	so
Security:	FreeBSD-SA-26:68.openssl
Security:	CVE-2026-84782
2026-09-28 18:17:20 +00:00
Mark Johnston 9d0644e7a4 unix: Preserve FD_RESOLVE_BENEATH when passing an fd
The FD_RESOLVE_BENEATH flag is supposed to be sticky.  It's set when you
receive an fd from a different jail and preserved by openat(<dfd>) etc..
However, if you send the fd to yourself, the flag is stripped since
SCM_RIGHTS message don't preserve file descriptor flags.

Fix this by preserving those flags and checking for UF_RESOLVE_BENEATH
in restrict_rights().

Approved by:	so
Security:	FreeBSD-SA-26:66.jail
Security:	CVE-2026-101306
Fixes:		350ba9672a ("unix: Set O_RESOLVE_BENEATH on fds transferred between jails")
Reviewed by:	kib
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D58317

(cherry picked from commit 586e2b3d89)
(cherry picked from commit 441885dcff)
2026-09-28 18:17:20 +00:00
Mark Johnston 1c1575015c vfs: Disallow renameat() with FD_RESOLVE_BENEATH descriptors
The FD_RESOLVE_BENEATH flag was intended to try to resolve bugzilla PR
262179 without entirely disallowing fd passing between jails.  However,
one can use renameat() to bypass the restriction: upon receiving a
directory fd with FD_RESOLVE_BENEATH set, a jailed process can still
move its CWD or one of its ancestors to the directory, and just cd
out of its jail root.

So disallow renameat() when either the source or destination directory
fds has FD_RESOLVE_BENEATH set, like we do with fchdir() and fchroot()
to prevent similar escapes.

Approved by:	so
Security:	FreeBSD-SA-26:66.jail
Security:	CVE-2026-101305
PR:		262179
Reported by:	[email protected]
Reviewed by:	olce, kib
Differential Revision:	https://reviews.freebsd.org/D59875
2026-09-28 18:17:20 +00:00
Mark Johnston 8e6bc7b3e9 fdescfs: Pass up additional metadata during lookups
When an fdescfs mount has the nodup option set, fdesc_lookup(/dev/fd/n)
returns the vnode referenced by file descriptor n, rather than returning
an fdescfs vnode.  This meant that fd metadata attached to fd n was not
preserved when reopening the file, which is contrary to the expected
semantics for capsicum rights and the UF_RESOLVE_BENEATH fd flag.  For
regular fdescfs mounts, this metadata is copied via dupfdopen().

Fix the problem by passing up this metadata through the nameidata
structure.  Thus, if one opens /dev/fd/n, the returned fd will inherit
UF_RESOLVE_BENEATH and the capability rights of fd n.  Add some
regression tests as well.

Approved by:	so
Security:	FreeBSD-SA-26:66.jail
Security:	CVE-2026-101304
Reported by:	Jan Bramkamp
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59886
2026-09-28 18:17:20 +00:00
Mark Johnston 790bfee896 file: Add filecaps_intersect() and cap_rights_intersect()
These routines let one compute the intersection of two sets of filecaps
or capability rights, just as filecaps_merge() and cap_rights_merge()
compute the union.  This will be useful in an upcoming patch.

filecaps_intersect() is complex due to the need to merge sets of ioctls.
For now this is implemented with a dumb nested loop on the basis that
ioctl lists are typically short enough that this is fine.  It may be
better to instead sort the two lists first and step through them
together.

No functional change intended.

Approved by:	so
Security:	FreeBSD-SA-26:66.jail
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59885
2026-09-28 17:53:19 +00:00
Mark Johnston 4c3de56d28 file: Add a helper function to check whether filecaps are full
In a couple of places we want to know whether someone has limited rights
on an fd.  There, we want a predicate which determines whether the set
of rights is smaller than CAP_ALL, and whether there are explicit ioctl
or fcntl lists.  Factor this out into a helper function, in preparation
for use elsewhere.

No functional change intended.

Approved by:	so
Security:	FreeBSD-SA-26:66.jail
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59884
2026-09-28 17:53:18 +00:00
Mark Johnston ba6c8cdf98 udp: Let jail policy rewrite the dstaddr for v6 sendto()s
When performing an unconnected sendto() on a v6 UDP socket in a classic
jail, we were not applying the usual policy of replacing the loopback
addr with the jail's primary IP.  Compare with, e.g., udp6_connect() or
the IPv4 udp_send().  Fix that.

Approved by:	so
Security:	FreeBSD-SA-26:69.udp
Security:	CVE-2026-101303
Reported by:	Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li,
		and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Reviewed by:	bz, glebius
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59772

(cherry picked from commit fecb9537a8)
(cherry picked from commit 809221661a)
2026-09-28 16:38:56 +00:00
Mark Johnston 11a5387a12 ktls: Fix an off-by-one bug in tls13_find_record_type()
If the entire plaintext is zero-filled, the backwards walk in
tls13_find_record_type() would return the offset of the last byte of the
TLS header.  This causes an underflow when decrypting, resulting in a
null pointer dereference.

Fix the bug and add a regression test.

Approved by:	so
Security:	FreeBSD-SA-26:67.ktls
Security:	CVE-2026-101302
Reviewed by:	gallatin, jhb
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59767

(cherry picked from commit 7c5e457d3a)
(cherry picked from commit fc1a02c93b)
2026-09-28 16:38:56 +00:00
Andrew Gallatin ebea5df751 ktls: Add a tunable to disable TLS receive
TLS receive offload is really only beneficial for in-kernel use cases
(such as NFS over TLS) or when using a hardware offload.  In addition,
several recent SAs have involved the TLS receive path, but the only
current mitigation for those is to disable TLS offload entirely.

Approved by:	so
Security:	FreeBSD-SA-26:67.ktls
Reviewed by:	ziaee, gallatin, markj
Relnotes:	yes
Sponsored by:	Netflix
Sponsored by:	Chelsio Communications
Co-authored-by:	John Baldwin <[email protected]>
Differential Revision:	https://reviews.freebsd.org/D57974

(cherry picked from commit 08cda4bcd4)
(cherry picked from commit f80f8c38fa)
2026-09-28 16:38:55 +00:00
Mark Johnston 9bb6f92b5d sysvsem: Fix another sequence number wraparound race
semop() may sleep waiting for a semaphore.  Upon waking up, it checks to
see if the set's sequence number has changed, indicating that the set
was removed.  The sequence number is not wide enough to prevent a false
negative due to wraparound, in which case the subsequent access of
`semakptr->u.__sem_base[sopptr->sem_num]` may be out of bounds.  This
race can be leveraged to elevate privileges.

Fix this by introducing a 64-bit sequence number for each semaphore
pool.  This is wide enough to make the race impossible to hit.  Allocate
a separate array for them, as we cannot really change the layout of
struct semid_kernel since some userspace tools (e.g., ipcrm(1)) embed
the layout.

While here, use semvalid() instead of open-coding its implementation,
convert a couple of flags to be bool, and use a better variable name to
store required permissions.

Approved by:	so
Security:	FreeBSD-SA-26:64.sysvsem
Security:	CVE-2026-58098
Reported by:	Reo Shiseki
Reported by:	Andrew Griffiths
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59347
2026-09-28 16:24:29 +00:00
Philip Paeps b38d9c709d contrib/tzdata: import tzdata 2026d
Approved by:	so
Security:	FreeBSD-EN-26:24.tzdata
Changes: https://github.com/eggert/tz/blob/2026d/NEWS

(cherry picked from commit fe81d42176)
(cherry picked from commit 7fa0ed470f)
2026-09-28 13:13:06 +00:00
Mark Johnston 53c5c19353 Add UPDATING entries and bump version
Approved by:	so
2026-08-24 19:00:32 +00:00
Mark Johnston 840fd9dc7d posixshm: Fix a TOCTOU race in the FIOSSHMLPGCNF handler
The check for whether shm_lp_psind was assigned was unlocked.  This race
can be exploited to create an object with psind==2 but with only
pagesizes[1] worth of pages populated.  This in turn can be used to
escalate privileges.

Fix this by acquiring the rangelock earlier.  In shm_mmap_large(),
assert that we hold the rangelock.  In shm_write(), annotate an unlocked
load of shm_lp_psind.

Approved by:	so
Security:	FreeBSD-SA-26:63.posixshm
Security:	CVE-2026-58094
Reported by:	tsune of GMO Cybersecurity by Ierae, Inc. working with TrendAI Zero Day Initiative
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59104
2026-08-24 18:59:49 +00:00
Mark Johnston d7883b84b1 tty: Revalidate after dropping the tty lock in ioctl handlers
The TIOCSCTTY ioctl handler drops the tty lock in order to acquire the
proctree relock.  After relocking the tty, it did not revalidate the
tty state, and it could end up linking a doomed tty to the calling
process' session.  This race can be exploited to escalate privileges.

TIOCSPGRP has a similar race, fix that too.

Approved by:	so
Security:	FreeBSD-SA-26:62.tty
Security:	CVE-2026-58093
Reported by:	tsune of GMO Cybersecurity by Ierae, Inc. working with TrendAI Zero Day Initiative
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59126
2026-08-24 18:59:49 +00:00
Gordon Tetlow 275b424d3c openssl: Fix multiple vulnerabilities
This is a rollup commit from upstream to fix:
  Avoid full read buffer allocation when buffering DTLS records
  ssl/record: lower the DTLS unprocessed_rcds queue limit
  Fix heap buffer overflow (8-byte OOB write) in AES-WRAP-PAD unwrap
  Add a test for restricting growth in cmp cert cache
  Fix unbounded cert cache growth in cmp
  Fix Remote NULL deref in ossl_cmp_calc_protection() via crafted protectionAlg

Approved by:	so
Obtained from:	OpenSSL
Security:	FreeBSD-SA-26:61.openssl
Security:	CVE-2026-54874
Security:	CVE-2026-63072
Security:	CVE-2026-63074
Security:	CVE-2026-63076
2026-08-24 18:59:49 +00:00
Mark Johnston 8544e4ce67 ppp: Fix a buffer overflow in the endpoint discriminator set command
Approved by:	so
Security:	FreeBSD-SA-26:60.ppp
Security:	CVE-2026-58097
Reported by:	Reo Shiseki
MFC after:	3 days
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59054

(cherry picked from commit 6cb7e368da)
(cherry picked from commit 55ee29bf35)
2026-08-24 18:59:35 +00:00
Mark Johnston 3e5e24f16e ppp: Reject invalid endpoint discriminator options
Per RFC1717 section 5.1.3, the option length must be at least three.
Processing an undersized option would trigger a large out-of-bounds
write.

Approved by:	so
Security:	FreeBSD-SA-26:60.ppp
Security:	CVE-2026-58096
PR:		271910
Reported by:	Robert Morris
Reported by:	Décio Brandão (0xDBJ)
Reviewed by:	emaste
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D58554

(cherry picked from commit b9d07a4308)
(cherry picked from commit 30b4bdd451)
2026-08-24 18:59:17 +00:00
Mark Johnston 0cd984b41c ppp: Avoid overflow when formatting endpoint discriminator options
Each byte of the address is represented by a pair of characters, so we
should be multiplying len by 2 when figuring out how much buffer space
we have.  Previously, a sufficiently large option could cause an
overflow of the global "result" buffer.

Approved by:	so
Security:	FreeBSD-SA-26:60.ppp
Security:	CVE-2026-58095
Reported by:	Joshua Rogers <[email protected]>
Tested by:	Décio Brandão (0xDBJ)
MFC after:	3 days
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D58555

(cherry picked from commit e004ff15f8)
(cherry picked from commit 607c41d8f8)
2026-08-24 18:59:03 +00:00
Mark Johnston 8668302cb7 dsp: Fix a potential use-after-free in dsp_oss_syncstart()
This function has a loop where it attempts to lock all channels in a
group.  If doing so would block, it releases all locks, sleeps for a
bit, and tries again.  However, once the syncgroup lock is dropped,
nothing prevents the syncgroup structure from being freed.

Fix the inner loop: after waking up, break out of it unconditionally and
start everything again.  I think the old code was also buggy and not
well-exercised: after waking up we'd continue to try and continue
locking channels.  Then we'd try again from the beginning and fail to
lock the channels we had already locked.

Approved by:	so
Security:	FreeBSD-SA-26:58.sound
Security:	CVE-2026-58091
Reported by:	Hazley Samsudin of GovTech CSG
Reviewed by:	christos
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D58912
2026-08-24 18:41:23 +00:00
Mark Johnston 97e1e603bd hwpmc: Fix the execve handler
When a process execve()s, pmc_process_exec() is supposed to evaluate
whether the new image is setuid/setgid and if so, whether to detach
PMCs.  This was handled by pmc_can_attach(), which is effectively an
open-coded copy of cr_xids_subset().

Unfortunately, the test of the result of this function was inverted,
with the result that we'd detach PMCs only if the predicate said it was
okay to do so.  It appears the bug has always been there; it seems the
intent was to return 0 on "success", i.e., it is okay to attach the
PMCs, much like p_candebug().  Commits 1c3c698ba4 and 1c40b15971
obscured this a bit.

I think this check is trying to be too clever.  Let's make it simpler:
simply do not attach PMCs unless the owner is privileged.  This is how,
e.g., ktrace works.  I do not think it's worth trying to be more
sophisticated than this unless we can generalize the policy in a way
that's applicable to other subsystems.

Also fix a bug at the end of pmc_process_exec():
pmc_detach_one_process() will call pmc_remove_process_descriptor() for
us.

Approved by:	so
Security:	FreeBSD-SA-26:56.hwpmc
Security:	CVE-2026-58089
Reported by:	netchild
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D59102
2026-08-24 18:41:23 +00:00
Enji Cooper 357aa8af53 crypto/openssl: correct version numbers for pkg-config files
The files were incorrectly reporting 3.5.1 instead of 3.0.21.

This is a direct commit to stable/14 as stable/15 and later are on
OpenSSL 3.5.

Approved by:	so
Security:	FreeBSD-26:21.openssl
PR:	297144
Fixes:	d03be8cf ("crypto/openssl: make vendor imports easier/less error prone")

For releng/14.4 the version was updated to 3.0.20.

(cherry picked from commit 2e04d98688)
2026-08-24 14:45:11 +00:00
Mark Johnston c905b34120 ucode: Fix validation on Intel platforms
The check for the extended signature table was backwards, so we always
ignored it.

We should verify that the extended signature table fits within the total
image size.

Approved by:	so
Security:	FreeBSD-EN-26:20.microcode
Reviewed by:	jrm, kib
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D57209

(cherry picked from commit 0beb172898)
(cherry picked from commit 38cbd2588f)
2026-08-19 19:00:58 +00:00
Chuck Silvers 6fb0f13275 x86/ucode: add const where appropriate
Approved by:	so
Sponsored by:   Netflix
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D43865

(cherry picked from commit fd24a63a38)
(cherry picked from commit 1e857a9947)
2026-08-19 19:00:46 +00:00
Mark Johnston 3de2d29b08 Add UPDATING entries and bump version
Approved by:	so
2026-07-28 19:21:40 +00:00
Mark Johnston d46ec21610 coredump: Don't assume that the number of ELF segments is consistent
In an ELF coredump, each dumped vm_map_entry is represented by a
segment.  __elfN(coredump) first computes the number of segments by
looping over the vm_map entries (in each_dumpable_segment()), then
allocates a buffer to hold the ELF header and program headers, then
loops over the entries again to populate the program headers.

each_dumpable_segment() holds the vm_map read lock, but that lock is
dropped between the two calls.  If the map is shared with another
process, via rfork(), then the map can change.  cb_put_phdr() did not
account for this, and so could write out of bounds.

Add a check to prevent this; simply do not write out excess segments.

Approved by:	so
Security:	FreeBSD-SA-26:55.elf
Security:	CVE-2026-58088
Reported by:	Maik Muench of Secfault Security
Reviewed by:	kib, emaste
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D58416
2026-07-28 14:38:27 +00:00
Mark Johnston b5eaa00cdb sysvsem: Fix a TOCTOU race in semctl({GET,SET}ALL)
These commands take a snapshot of the size of a semaphore set, then drop
the lock and malloc an appropriately sized array before reacquiring the
lock.  A comment explains why this is (probably) safe.  Unfortunately,
it's wrong; it is indeed possible for a malicious userspace to create
and destroy 2^{15} sets in the window where the lock is dropped.  This
race can lead to out-of-bounds reads and writes, and that can be
exploited to elevate privileges.

Replace the assertions with runtime checks.

Approved by:	so
Security:	FreeBSD-SA-26:54.sysvsem
Security:	CVE-2026-58087
Reported by:	Maik Muench of Secfault Security
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D58421
2026-07-28 14:38:27 +00:00
John Baldwin b20841b471 wg(4): Add a test that the driver handles a decryption failure
The test uses a fail point to inject a decryption error in OCF while
sending a ping across the tunnel.  The driver should then fail to
respond to the ping and increment the input error counter on the
interface.

Approved by:	so
Security:	FreeBSD-SA-26:52.if_wg
Security:	CVE-2026-58085
Reviewed by:	markj
Sponsored by:	Chelsio Communications
2026-07-28 14:38:27 +00:00
John Baldwin 01b53d5d1e wg(4): Check for crypto operation errors
In particular, handle authentication errors due to bad MACs when
decrypting packets.

Since the current dispatch code assumes synchronous OCF sessions by
design, explicitly reject any created OCF session that is not
synchronous.  Software sessions are always synchronous in practice, so
this should be a nop.

Approved by:	so
Security:	FreeBSD-SA-26:52.if_wg
Security:	CVE-2026-58085
Reviewed by:	markj
Sponsored by:	Chelsio Communications
2026-07-28 14:38:27 +00:00
John Baldwin 4ae10ff966 OCF: Add a fail point to inject EBADMSG decryption errors
Approved by:	so
Security:	FreeBSD-SA-26:52.if_wg
Security:	CVE-2026-58085
Reviewed by:	markj
Sponsored by:	Chelsio Communications
2026-07-28 14:38:26 +00:00
Philip Paeps 7a227adc1a contrib/tzdata: import tzdata 2026c
Changes: https://github.com/eggert/tz/blob/2026c/NEWS

Approved by:	so
Security:	FreeBSD-EN-26:18.tzdata

(cherry picked from commit 665bb2d9a4)
(cherry picked from commit 819af80de8)
2026-07-27 17:43:51 +00:00
Mark Johnston 72947d00fc Add a missing UPDATING entry
Approved by:	so
2026-07-03 15:58:06 +00:00
Mark Johnston 3827644480 Add UPDATING entries and bump version
Approved by:	so
2026-06-29 21:26:44 +00:00
Mark Johnston b819674449 iconv: Fix a stack buffer overflow in _ISO2022_sputwchar()
In the ISO2022-CN encoding, characters may require at least seven bytes,
and MB_LEN_MAX==6 is insufficient.  From code inspection,
_ISO2022_sputwchar() can emit 10 bytes in the worst case, so use that to
size buffers.

Add a regression test.

Approved by:	so
Security:	FreeBSD-SA-26:49.iconv
Security:	CVE-2026-58082
Reviewed by:	kevans
Differential Revision:	https://reviews.freebsd.org/D57950
2026-06-29 21:26:44 +00:00
Mark Johnston ce422ff3fc iconv: Fix a buffer overflow in the HZ encoding
wcrtomb may store up to 2 2-byte escape sequences to the state buffer in
addition to the character itself.  In the worst case, a 3-byte heap
overflow is possible.

Approved by:	so
Security:	FreeBSD-SA-26:49.iconv
Security:	CVE-2026-58081
Reviewed by:	kevans
Differential Revision:	https://reviews.freebsd.org/D57949
2026-06-29 21:26:44 +00:00
Taylor R Campbell d760b7f9b0 iconv(3): Draft some automatic tests.
Based on a report by Nick Wellnhofer.

Approved by:	so
Security:	FreeBSD-SA-26:49.iconv
Reviewed by:	markj, kevans
Differential Revision:	https://reviews.freebsd.org/D57948
2026-06-29 21:26:44 +00:00
Taylor R Campbell 07a27f8c8e iconv(3): Fix problems in various encodings
Fix null pointer dereference with HZ8 encoding.

Fix output buffer overrun in UTF-7, VIQR, ZW encodings.

Approved by:	so
Security:	FreeBSD-SA-26:49.iconv
Security:	CVE-2026-58081
Reviewed by:	markj, kevans
Differential Revision:	https://reviews.freebsd.org/D57947
2026-06-29 21:26:44 +00:00
Ed Maste f145e3c02b compat32: Zero struct to avoid stack disclosure
Approved by:	so
Security:	FreeBSD-SA-26:48.compat32
Security:	CVE-2026-49425
Reported by:	Adam Crosser, Praetorian
Reviewed by:	philip
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D55811

(cherry picked from commit 097cb4e9f0)
(cherry picked from commit 4551ea3b3f)
(cherry picked from commit 6a808cd753)
2026-06-29 19:17:30 +00:00
Ed Maste 99d936f985 compat/linux: Avoid waitid() kernel stack disclosure
Approved by:	so
Security:	FreeBSD-SA-26:47.linux
Security:	CVE-2026-49424
Reported by:	Adam Crosser, Praetorian
Reviewed by:	philip
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D55812

(cherry picked from commit 9a9f93bcf1)
(cherry picked from commit 9f8db9cc67)
(cherry picked from commit a347e6e20e)
2026-06-29 19:17:30 +00:00
John Baldwin 5f83a1c159 ktls CBC decrypt: Only increment iovec index when an entry is used
If an mbuf in the chain was skipped because it only contained bytes
from the header, the iovec index ('i') was incremented even though the
entry was not populated.  Only increment 'i' when an iovec entry is
consumed.

Add a new type of KTLS receive test which writes a single TLS record
via two separate write(2) calls over a TCP_NODELAY socket to trigger
a split in the mbuf chain in the kernel.  Test various split locations
including after the "plain" TLS header (5 bytes), after the full TLS
header, in the middle of the data payload, just before the start of
the trailer, and in the middle of the trailer.  These tests are also
run against all supported ciphers, not just CBC.  The 'header' test
for CBC ciphersuites was able to trigger the bug.

Approved by:	so
Security:	FreeBSD-SA-26:46.ktls
Security:	CVE-2026-49423
Sponsored by:	Chelsio Communications
2026-06-29 19:17:30 +00:00
Kyle Evans d68c2e77d7 kern: fix auditing of ptrace(2) syscall requests
`error` here is the return value of syscall_thread_enter() rather than
the syscall itself, so the committed audit records do not reflect
reality.  This is less harmful than them recording an error when the
operation actually succeeded, but it could still possibly be used to
throw off IDS techniques with things like bsmtrace.

Approved by:	so
Security:	FreeBSD-SA-26:45.audit
Security:	CVE-2026-49426
Reviewed by:	des, kib, markj, csjp
Differential Revision:	https://reviews.freebsd.org/D57847
2026-06-29 19:17:30 +00:00
Mark Johnston 0848cdea83 posixshm: Fix handling of sendfile() with largepage objects
sendfile(2) can transmit POSIX shared memory objects.  Typically it will
look up and wire each page before sending it to a socket; once
transmission is complete, the page is unwired and typically released
back into the page queues.  sendfile() has an advisory flag, SF_NOCACHE,
which means, "try to free the page once transmission is complete."  This
is implemented in vm_page_release(), which expects to operate on managed
pages.

Pages belonging a largepage object are de-facto wired not explicitly so.
Thus, vm_page_release() will unwire and, having found no additional
references, free the page.  Because mappings of largepage objects are
unmanaged, userspace can still access the now freed page.

Fix the problem by explicitly wiring largepage pages.  Make the VM
object destructor responsible for unwiring and freeing them.

Add a regression test.

Approved by:	so
Security:	FreeBSD-SA-26:44.posixshm
Security:	CVE-2026-49427
Reported by:	Chris Jarrett-Davies <[email protected]>
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57832
2026-06-29 19:17:30 +00:00
Mark Johnston 9c06b54ab6 posixshm: Disallow truncation of largepage objects
We correctly handled ftruncate(), but not open(O_TRUNC).

Add a regression test.

Approved by:	so
Security:	FreeBSD-SA-26:44.posixshm
Security:	CVE-2026-49428
Reported by:	Chris Jarrett-Davies <[email protected]>
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57831
2026-06-29 19:17:30 +00:00
Mark Johnston 1c49551def posixshm: Disallow fspacectl() on largepage objects
As with truncation, the operation isn't supported, but nothing prevented
it.

Add a regression test.

Approved by:	so
Security:	FreeBSD-SA-26:44.posixshm
Security:	CVE-2026-49428
Reported by:	Chris Jarrett-Davies <[email protected]>
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57830
2026-06-29 19:17:30 +00:00
Mark Johnston 800acf75eb rack: Reload the TCP stack PCB after reacquiring the inpcb lock
Malicious userspace might switch TCP stacks twice while the inpcb lock
is dropped.  If it does so, the validation of tp->t_fb might succeed,
but the saved pointer to the stack PCB might be invalid.  Reload it to
avoid this problem, as BBR already does.

Approved by:	so
Security:	FreeBSD-SA-26:43.tcp
Security:	CVE-2026-49422
Reported by:	Maik Münch
Reviewed by:	tuexen
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57791
2026-06-29 19:17:30 +00:00
Mark Johnston 9a6bccc57c unlinkat: Pass flags down to the work functions
The unlinkat(2) and funlinkat(2) system calls were ignoring
AT_RESOLVE_BENEATH.

Also pass pathseg through instead of assuming it's UIO_USERSPACE.

Add some tests which make sure that AT_RESOLVE_BENEATH is handled
properly by various system calls.

Approved by:	so
Security:	FreeBSD-SA-26:42.unlinkat
Security:	CVE-2026-49421
Reported by:	Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57790
2026-06-29 19:17:30 +00:00
Mark Johnston 0a7dd3d960 tests/libalias: Add a regression test for an alias_smedia bug
Approved by:	so
Security:	FreeBSD-SA-26:41.libalias
Security:	CVE-2026-49420
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57747
2026-06-29 19:17:30 +00:00
Dag-Erling Smørgrav 66efc521e0 libalias: Fix buffer overflow in RTSP aliasing
In alias_rtsp_out(), we construct a new packet in a fixed-length buffer
before copying it back into the original buffer.  We never checked if
the data we were writing to this temporary buffer fit in it, nor if the
result fit in the original buffer.

* Use a dynamically sized allocated buffer instead of a fixed-length
  stack buffer.

* Check for overflow before appending to our temporary buffer.

* Check for overflow before copying the data back to the packet buffer.

* While here, use size_t for sizes and bool for booleans.

Approved by:	so
Security:	FreeBSD-SA-26:41.libalias
Security:	CVE-2026-49420
MFC after:	1 week
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D57753
2026-06-29 19:17:30 +00:00
Mark Johnston 62f64d81b5 zfs: Roll up several upstream commits
This commit squashes the following upstream commits:
  #18604 63a0ff6cd nvpair: Check for un-terminated strings in packed nvlist
  #18617 38cd6adcb Extend dataset zfs_ioc_set_prop() secpolicy
  #18615 738791027 Fix the integer type in zfs_ioc_userspace_many()
  #18623 06d8cfedb Add additional verification of size fields and strings

Approved by:	so
Security:	FreeBSD-SA-26:40.zfs
Security:	CVE-2026-49429
Security:	CVE-2026-49430
Security:	CVE-2026-49431
2026-06-29 19:17:29 +00:00
Konstantin Belousov 8fbbc185a3 execve_block(): a mechanism for mutual exclusion with execve() on the process
(cherry picked from commit e1a84b7708)
(cherry picked from commit dc94d15a71)

proc: Allow to make proc_rwmem() operate on a consistent address space

(cherry picked from commit e1b0d051bb)
(cherry picked from commit e7578e37d8)

kern_proc.c: ensure stability of the vmspace we read the strings from

(cherry picked from commit a22c044cce)
(cherry picked from commit 1f062247ef)

kern_proc.c: ensure stability of the vmspace for sysctl kern.proc.vmmap

(cherry picked from commit 5fe6e08d2d)
(cherry picked from commit e856c10a4d)

kern_proc.c: ensure stability of the vmspace for sysctl kern.proc.vm_layout

(cherry picked from commit 31fa677e4a)
(cherry picked from commit da1398dd69)

kern_proc.c: make kern.proc.osrel atomic

(cherry picked from commit 80626f34ee)
(cherry picked from commit b3f99ce653)

kern_proc.c: disallow execve around sysctl kern.proc.kstacks

(cherry picked from commit 8b5abd9027)
(cherry picked from commit 197f367cdd)

kern_proc.c: disallow execve around sysctl kern.proc.rlimit

(cherry picked from commit 5a91fa5a76)
(cherry picked from commit 35b95beb06)

kern_event: block the target process from execing for sysctl kern.proc.kqueue

(cherry picked from commit 79b384bd8f)
(cherry picked from commit adb14791b7)

kern_resource.c: disallow execve around sysctl kern.proc.rlimitusage

(cherry picked from commit 8367498170)
(cherry picked from commit 190d6677b1)

kern_procctl(PROC_WX_MAPPINGS_PERMIT): ensure stability of the target vmspace

(cherry picked from commit 6a572920f2)
(cherry picked from commit 23ebf0c97a)

linux_prlimit(): block execve for the target

(cherry picked from commit e41c28e67f)
(cherry picked from commit a11c4f036c)

pfs_readdir(): block the target process from execing

(cherry picked from commit 4c0a0909f9)
(cherry picked from commit caa2e5cf7c)

pseudofs: ensure that the target process vmspace is stable for VOP_READ/WRITE

(cherry picked from commit a4993bac41)
(cherry picked from commit ec0d7d01d6)

procfs, linprocfs: ensure target process vmspace stability

(cherry picked from commit 5db31f1b47)
(cherry picked from commit d7d5337291)

sys_set*id(9): wait for the execblocks to pass

(cherry picked from commit d0384f50da)
(cherry picked from commit 34b95f53e7)

kern_exec.c: explicitly include sys/limits.h for UINT_MAX

(cherry picked from commit f5fce0bcc3)
(cherry picked from commit bb1154f3ea)

Approved by:	so
Security:	FreeBSD-SA-26:39.execve
Security:	CVE-2026-49415
2026-06-29 19:17:29 +00:00
Mark Johnston 4c9e89c85d device_pager: Avoid double-insertion of pages into the pager list
Unmanaged device pager objects maintain a linked list of pages that were
returned from the fault handler.  Initially, such pages are valid, but
msync(MS_INVALIDATE) can mark them invalid (and clean).  They are not
removed from page tables (since they are unmanaged), but a subsequent
mlock() call can trigger a page fault that is handled by the pager.
dev_pager_getpages() then re-inserts the page into the linked list even
though it's already present there.

This patch fixes the problem by removing the linked list.  OBJ_PG_DTOR
is set, so vm_object_terminate_pages() does nothing, and
dev_pager_dealloc() instead handles cleanup of the object.

Add a regression test case which triggers a queue.h assertion failure in
unpatched kernels.

Note, in stable branches we should avoid changing the layout of struct
vm_object.

Approved by:	so
Security:	FreeBSD-SA-26:37.vm
Security:	CVE-2026-49418
Reported by:	slidybat
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57743
2026-06-29 19:17:29 +00:00
Piotr Kubaj f902821db0 sys/arm64: fix return values of freebsd32_{set,swap}context()
This patch aligns the return values of freebsd32_{set,swap}context()
with their counterparts on amd64 and powerpc64, fixing the setcontext()
and swapcontext() calls in armv7 applications running on aarch64.

In particular, this fixes random crashes in armv7 Ruby applications
running on aarch64 hosts.

Approved by:	so
Security:	FreeBSD-EN-26:16.arm64
Tested by:	fuz
MFC after:	1 week

(cherry picked from commit 92ae21e8a1)
(cherry picked from commit 58a15fe75c)
2026-06-29 19:17:18 +00:00
Mark Johnston 3d95ec8758 Add UPDATING entries and bump version
Approved by:	so
2026-06-08 15:38:31 +00:00
Gordon Tetlow 410ab2bff3 ldns: Fix query response validation
Approved by:	so
Security:	FreeBSD-SA-26:36.ldns
Security:	CVE-2026-10846
2026-06-08 13:21:34 +00:00
Gordon Tetlow 1929d9e173 openssl: Fix multiple vulnerabilities
This is a rollup commit from upstream to fix:
  Reject oversized inputs in ASN1_mbstring_ncopy()
  cms: kek_unwrap_key: Fix out-of-bounds read in check-byte validation
  cms: kek_unwrap_key: test for fix out-of-bounds read in check-byte validation
  Avoid length truncation in ASN1_STRING_set
  Reject potentially forged encrypted CMS AuthEnvelopedData messages
  Fix potential NULL dereference processing CMS PasswordRecipientInfo
  Match the local q DHX parameter against the peer's q
  Apply the buffered IV on the AES-OCB EVP_Cipher() path
  Fix handling of empty-ciphertext messages in AES-GCM-SIV and AES-SIV
  Fix possible use-after-free in OpenSSL PKCS7_verify()

Approved by:	so
Obtained from:	OpenSSL
Security:	FreeBSD-SA-26:35.openssl
Security:	CVE-2026-7383
Security:	CVE-2026-9076
Security:	CVE-2026-34180
Security:	CVE-2026-34182
Security:	CVE-2026-42766
Security:	CVE-2026-42770
Security:	CVE-2026-45445
Security:	CVE-2026-45446
Security:	CVE-2026-45447
2026-06-08 13:21:34 +00:00
Ed Maste 799e830134 vt: Avoid integer overflow in CONS_HISTORY ioctl
Approved by:	so
Security:	FreeBSD-SA-26:34.vt
Security:	CVE-2026-49416
Reviewed by:	markj, vexeduxr
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57250

(cherry picked from commit 0ae946e722)
(cherry picked from commit deaaddf1d3)
(cherry picked from commit b5a4f4bfbc)
2026-06-08 13:21:34 +00:00
Dag-Erling Smørgrav 857abc1294 unbound: Apply upstream patches
- Use the same EDE removal logic when encoding errors as when encoding
  replies.
- Fix CVE-2026-33278, Possible remote code execution during DNSSEC
  validation. Thanks to Qifan Zhang, Palo Alto Networks, for the report.
- Fix CVE-2026-42944, Heap overflow and crash with multiple nsid,
  cookie, padding EDNS options. Thanks to Qifan Zhang, Palo Alto
  Networks, for the report.
- Fix CVE-2026-42959, Crash during DNSSEC validation of malicious
  content. Thanks to Qifan Zhang, Palo Alto Networks, for the report.
- Fix CVE-2026-32792, Packet of death with DNSCrypt. Thanks to Andrew
  Griffiths from 'calif.io' for the report.
- Fix CVE-2026-40622, "Ghost domain name" variant. Thanks to Qifan
  Zhang, Palo Alto Networks, for the report.
- Fix CVE-2026-41292, Parsing a long list of incoming EDNS options
  degrades performance. Thanks to GitHub user 'N0zoM1z0', also Qifan
  Zhang from Palo Alto Networks, for the report.
- Fix CVE-2026-42534, Jostle logic bypass degrades resolution
  performance. Thanks to Qifan Zhang, Palo Alto Networks, for the
  report.
- Fix CVE-2026-42923, Degradation of service with unbounded NSEC3 hash
  calculations. Thanks to Qifan Zhang, Palo Alto Networks, for the
  report.
- Fix CVE-2026-42960, Possible cache poisoning attack while following
  delegation. Thanks to TaoFei Guo from Peking University, Yang Luo and
  JianJun Chen, Tsinghua University, for the report.
- Fix CVE-2026-44390, Unbounded name compression in certain cases causes
  degradation of service. Thanks to Qifan Zhang, Palo Alto Networks, for
  the report.
- Fix CVE-2026-44608, Use after free and crash in RPZ code. Thanks to
  Qifan Zhang, Palo Alto Networks, for the report.

Approved by:	so
Security:	FreeBSD-SA-26:33.unbound
Security:	CVE-2026-33278
Security:	CVE-2026-42944
Security:	CVE-2026-42959
Security:	CVE-2026-32792
Security:	CVE-2026-40622
Security:	CVE-2026-41292
Security:	CVE-2026-42534
Security:	CVE-2026-42923
Security:	CVE-2026-42960
Security:	CVE-2026-44390
Security:	CVE-2026-44608
2026-06-08 13:21:34 +00:00
Mark Johnston 547fc2a98a imgact_elf: Clear no-ASLR and -WXORX flags earlier for setugid images
Otherwise an unprivileged user can disable randomization of the base
address for PIEs even if they are setugid.

Add a regression test.

Approved by:	so
Security:	FreeBSD-SA-26:32.elf
Security:	CVE-2026-49414
Reported by:	David Berard
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57397
2026-06-08 13:21:34 +00:00
Andrew Turner 889e306ded arm64: Workaround the following errata
- ARM C1-Premium erratum 4193780
 - ARM C1-Ultra erratum 4193780
 - ARM Cortex-A76 erratum 4193800
 - ARM Cortex-A76AE erratum 4193801
 - ARM Cortex-A77 erratum 4193798
 - ARM Cortex-A78 erratum 4193791
 - ARM Cortex-A78AE erratum 4193793
 - ARM Cortex-A78C erratum 4193794
 - ARM Cortex-A710 erratum 4193788
 - ARM Cortex-X1 erratum 4193791
 - ARM Cortex-X1C erratum 4193792
 - ARM Cortex-X2 erratum 4193788
 - ARM Cortex-X3 erratum 4193786
 - ARM Cortex-X4 erratum 4118414
 - ARM Cortex-X925 erratum 4193781
 - ARM Neoverse-N1 erratum 4193800
 - ARM Neoverse-N2 erratum 4193789
 - ARM Neoverse-V1 erratum 4193790
 - ARM Neoverse-V2 erratum 4193787
 - ARM Neoverse-V3 erratum 4193784
 - ARM Neoverse-V3AE erratum 4193784

These are all variants on an erratum where TLBI+DSB instructions on
one CPU may incorrectly complete early leading to stores to an updated
address using an incorrect translation on another CPU.

In all cases the workaround is to add a second TLBI+DSB.

Approved by:	so
Security:	FreeBSD-SA-26:31.arm64
Security:	CVE-2025-10263
Sponsored by:	Arm Ltd
2026-06-08 13:21:34 +00:00
Mark Johnston 3fe0922820 linux: Correct the issetugid check in copyout_auxargs
The runtime linker in glibc relies on the AT_SECURE auxv entry to know
whether the executable is set-ugid, if so then various dangerous
functionality such as LD_PRELOAD is disabled.

The check added in commit 669414e4fb failed to take into account the
fact that during execve, P_SUGID may not yet be set for a set-ugid
process.  Correct the test.

Approved by:	so
Security:	FreeBSD-SA-26:30.linux
Security:	CVE-2026-49413
Reported by:	Minseong Kim
Fixes:		669414e4fb ("Implement AT_SECURE properly.")
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57350
2026-06-08 13:21:34 +00:00
Mark Johnston a7062a6de0 in6_mcast: Fix a race in in6p_set_source_filter()
We drop the inpcb lock in order to copy in the source list, but this
leaves a window where the multicast filter structure might be freed.
This can be exploited to obtain root privileges.

In the v4 code this race is mitigated by holding the global multicast
lock across the gap.

Restructure the code to copy in filters before doing anything else, so
that there's no need to drop the inpcb lock and reason about the
correctness of doing so.  Do the same in the v4 code for consistency.

Approved by:	so
Security:	FreeBSD-SA-26:29.ip6_multicast
Security:	CVE-2026-49412
Reported by:	Andrew Griffiths <[email protected]>
Reported by:	Maik Münch <[email protected]>
Reviewed by:	glebius
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57347
2026-06-08 13:21:33 +00:00
Ed Maste eab757f954 sigqueue: In capability mode, only allow signalling self
This is copied from the check in kern_kill.

Approved by:	so
Security:	FreeBSD-SA-26:28.capsicum
Security:	CVE-2026-45259
Reviewed by:	markj, oshogbo
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57244

(cherry picked from commit b9d16b7fd2)
(cherry picked from commit defd9b86ef)
(cherry picked from commit d11ff01b3a)
2026-06-08 13:21:33 +00:00
Mark Johnston 0e8cc8d8a4 sound: Fix software buffer lifetime issues
The channel buffer mapped by dsp_mmap_single() may be freed when the
device handle is closed, but the mapping persists beyond that, allowing
userspace to read or write memory owned by a different consumer.

Fix the problem by adding a reference counter to the sound buffer.
Define pager ops for the VM object returned by dsp_mmap_single() and use
them to manage the extra reference.

Add a regression test.

Approved by:	so
Security:	FreeBSD-SA-26:27.sound
Security:	CVE-2026-49417
Reported by:	Lexpl0it, 75Acol, Liyw979, Rob1n
Reviewed by	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57393
2026-06-08 13:21:29 +00:00
Christos Margiolis b9128fe195 sound: Check for offset overflow in dsp_mmap_single()
Approved by:	so
Security:	FreeBSD-SA-26:27.sound
Security:	CVE-2026-45258
Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
2026-06-08 13:21:14 +00:00
John Baldwin d43259dd66 ktls: Don't attempt to modify non-anonymous mbufs on the receive path
Normally, data processed on the KTLS receive path is contained in
anonymous mbufs that can be modified in place.  Either the data
originates in receive buffers from a NIC driver, or for loopback
connections the data is anonymous-backed mbufs created when writing to
a socket.  One potential source of non-anonymous mbufs are mbufs
created by sendfile(2) which borrow the pages of the underlying file,
either via M_EXTPG or EXT_SFBUF that are sent over a loopback
connection.  For a well-formed loopback TLS session, the sender should
only use sendfile(2) if KTLS is enabled.  If TLS is fully handled in
userspace, the sender must use write(2) or send(2) which allocate
anonymous mbufs.  If KTLS transmit is enabled, then sendfile(2) on a
loopback connection will always use crypto via OCF and will allocate
anonymous pages to hold the encrypted data.

However, if sendfile(2) is used to send file-backed data directly over
a loopback connection where KTLS is not enabled on the sender side,
the KTLS receive path can modify the file-backed pages in place
overwriting the file's data.  One potential fix would be to replace
non-anonymous mbufs in a received TLS record with anonymous mbufs
(e.g. via m_dup()) before passing the record to OCF.  However, there
is no legitimate use case for using sendfile(2) over a loopback TLS
connection without using KTLS on the sender side, so instead simply
fail decryption requests and close the connection if non-anonymous
mbufs are encountered in the RX decryption path.

Add a test for this that verifies that the original data backing the
file descriptor used as the source for sendfile() is unchanged after
being processed.

Approved by:	so
Security:	FreeBSD-SA-26:26.ktls
Security:	CVE-2026-45257
Co-authored-by:	Drew Gallatin <[email protected]>
Sponsored by:	Chelsio Communications
Sponsored by:	Netflix
2026-06-07 15:53:44 +00:00
Mark Johnston 31f6086db8 thr_kill2: Respect p_cansignal()
Approved by:	so
Security:	FreeBSD-SA-26:25.thr
Security:	CVE-2026-45256
Reported by:	Igor Gabriel Sousa e Souza
Reported by:	Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Reviewed by:	emaste, kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D57237
2026-06-07 15:53:43 +00:00
Enji Cooper 1bfe60bae8 crypto/openssl: Update to 3.0.20
This particular change contains all functional and security fixes made
between 3.0.16 and 3.0.20.

(cherry picked from commit 27ac9d336f)

Approved by:	so
Security:	FreeBSD-EN-26:15.openssl
Security:	CVE-2026-28387
Security:	CVE-2026-28388
Security:	CVE-2026-28389
Security:	CVE-2026-31789
Security:	CVE-2026-31790
2026-06-07 15:53:43 +00:00
Mark Johnston 069cb89611 Add UPDATING entries and bump version
Approved by:	so
2026-05-20 02:17:57 +00:00
Mariusz Zaborski f977328c72 cap_net: do not allow new limits to drop keys from the old ones
If the old limit had family/hosts/sockaddr set, the new limit must
have them too. Before, a missing key in the new limit was treated as
"allow any", which let a caller silently extend their limits.

Approved by:	so
Security:	FreeBSD-SA-26:24.cap_net
Security:	CVE-2026-45254
Reported by:	Joshua Rogers of AISLE Research Team
Reviewed by:	markj
MFC after:	1 day
Differential Revision:	https://reviews.freebsd.org/D56991

(cherry picked from commit d705a51952)
(cherry picked from commit b79faca1c5)
2026-05-20 02:17:57 +00:00
Mark Johnston dd50cc216e bsdconfig: Make sure that SSID names are properly escaped
The f_menu_wpa_scan_results() function returns a list of networks
discovered by a scan.  The untrusted network names are evaluated in
f_dialog_menu_wireless_edit.  The quoting applied in
f_menu_wpa_scan_results() protects against evaluation of something like
"$(whoami)" but one can add single quotes to defeat that.

Pass the SSID names through f_shell_escape to work around this.  Escape
single quotes in f_dialog_wireless_edit() and f_menu_wireless_configs()
too for consistency.

I note that this module doesn't seem to actually work, see e.g.,
bugzilla PR 229883.

Approved by:	so
Security:	FreeBSD-SA-26:23.bsdinstall
Security:	CVE-2026-45255
Reported by:	Austin Ralls
Reviewed by:	dteske, des
Differential Revision:	https://reviews.freebsd.org/D56974
2026-05-20 02:17:57 +00:00
Renato Botelho 70e6a19f3d bsdinstall: Avoid invoking eval on the wlan SSID list
The wlanconfig utility is not careful about handling untrusted network
names, which can contain shell metacharacters.  Factor network selection
into a subroutine and use the `set -- "$@"` trick to build up a list of
positional parameters for bsddialog without evaluating them.

Approved by:	so
Security:	FreeBSD-SA-26:23.bsdinstall
Security:	CVE-2026-45255
Reported by:	Austin Ralls
Reviewed by:	dteske, des, asiciliano
Differential Revision:	https://reviews.freebsd.org/D56973
2026-05-20 02:17:57 +00:00
Mariusz Zaborski ae34dd1a39 libcasper: switch from select(2) to poll(2)
The previous implementation used FD_SET() on a stack-allocated fd_set,
which is an out-of-bounds write whenever the socket fd is >= FD_SETSIZE
(1024).

poll(2) takes an array indexed by slot rather than by fd value, so it
has no FD_SETSIZE limit.

Approved by:	so
Security:	FreeBSD-SA-26:22.libcasper
Security:	CVE-2026-39461
Reported by:    Joshua Rogers
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D56695
2026-05-20 02:17:57 +00:00
Mark Johnston c21d23f0f8 ptrace: Fix validation of PT_SC_REMOTE arguments
- Fix an off-by-one in the system call number check.  A value of
  SYS_MAXSYSCALL was permitted.
- Validate the system call number after we've dealt with
  syscall(2)/__syscall(2), since they pass the syscall number as an
  argument.
- When the syscall number is for syscall(2) or __syscall(2), we must
  make sure that nargs > 0 to avoid an underflow when shifting arguments
  down.

Add regression tests.

Approved by:	so
Security:	FreeBSD-SA-26:21.ptrace
Security:	CVE-2026-45253
Fixes:		140ceb5d95 ("ptrace(2): add PT_SC_REMOTE remote syscall request")
Reported by:	Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
Reviewed by:	kib, emaste
Differential Revision:	https://reviews.freebsd.org/D56978
2026-05-20 02:17:57 +00:00
Alan Somers 6a299460f1 fusefs: Handle buggy servers' LISTXATTR response
The fuse protocol requires server to respond to LISTXATTR with a
NUL-terminated string.  If they don't, report an error rather than
attempt to scan through uninitialized memory for a NUL.

Approved by:	so
Security:	FreeBSD-SA-26:20.fusefs
Security:	CVE-2026-45252
admbugs:	1039
Reported by:	Joshua Rogers
Sponsored by:	ConnectWise
2026-05-20 02:17:57 +00:00
Mark Johnston 8d8694c224 netmap: Drain selinfo sleepers in nm_os_selinfo_uninit()
Approved by:	so
Security:	FreeBSD-SA-26:19.file
Security:	CVE-2026-45251
2026-05-19 23:49:37 +00:00
Mark Johnston 79d6615af7 procdesc: Make sure to drain selinfo sleepers in procdesc_free()
Otherwise they are left on a freed list after procdesc_free() is called.
This can be exploited to elevate privileges.

Remove the PDF_SELECTED micro-optimization.  doselwakeup() is a no-op if
no one ever called selrecord() on the file description, so I see no
reason to complicate the code to avoid the call.

Add some regression tests.

Approved by:	so
Security:	FreeBSD-SA-26:19.file
Security:	CVE-2026-45251
Reported by:	75Acol, Lexpl0it, fcgboy, and robinzeng2015
Reviewed by:	kib, oshogbo
Fixes:		cfb5f76865 ("Add experimental support for process descriptors")
Differential Revision:	https://reviews.freebsd.org/D56887
2026-05-19 23:49:37 +00:00
Dag-Erling Smørgrav 34da5845b8 setcred: Fix buffer overflow
Since groups is a pointer to a pointer to an array of gid_t, we should
use sizeof(**groups) or sizeof(gid_t) when calculating how much to
allocate and copy in.  We were using sizeof(*groups) instead, which
meant that on 64-bit platforms, we would allocate and copy in twice as
much as we should.  Unfortunately, in the smallgroups case, we copy
into a preallocated buffer which has the correct size, which means that
if sc_supp_groups_nb >= CRED_SMALLGROUPS_NB / 2, we overflow smallgroups.

This is a direct commit to stable/14.

Approved by:	so
Security:	FreeBSD-SA-26:18.setcred
Reported by:	Ryan of Calif.io
Fixes:		ddb3eb4efe ("New setcred() system call and associated MAC hooks")
2026-05-19 23:49:37 +00:00
Dag-Erling Smørgrav 081a9e9330 freebsd-update: Skip /etc/ssl/cert.pem
We already run `certctl rehash` at the end, there is no point in asking
users upgrading from 15.0 to 15.1 to manually merge the trust store.

Approved by:	so
Security:	FreeBSD-EN-26:13.freebsd-update
MFC after:	3 days
Reviewed by:	cperciva
Differential Revision:	https://reviews.freebsd.org/D57028

(cherry picked from commit 2509ddee9b)
(cherry picked from commit 7d9c1d3895)
2026-05-19 23:49:37 +00:00
Mark Johnston 49be56ed6f Add UPDATING entries and bump version
Approved by:	so
2026-04-30 21:21:54 +00:00
Dag-Erling Smørgrav dfcb69cdb0 dhclient: Improve server and filename validation
* Don't iterate over each string three times; once is enough.

* Reject control characters (anything below space) in addition to the
  double quote and backslash.

* If an unsafe character is encountered, discard the string instead of
  rejecting the entire lease.

* If backslashes are encountered in the file name option, convert them
  to forward slashes instead of rejecting the option.

* Tweak the warning messages a bit.  Looking through the rest of the
  code, it seems to me that notes generally end with a period while
  warnings generally don't.

Approved by:	so
Security:	FreeBSD-EN-26:11.dhclient
Fixes:		8008e4b88d ("dhclient: Check for unexpected characters in some DHCP server options")
PR:		294886
MFC after:	1 week
Reviewed by:	brooks, markj
Differential Revision:	https://reviews.freebsd.org/D56740

(cherry picked from commit 873a195ba6)
(cherry picked from commit 2f9478ad42)
2026-04-30 21:21:45 +00:00
Mark Johnston d7784de043 Add UPDATING entries and bump version
Approved by:	so
2026-04-28 20:33:59 +00:00
Mariusz Zaborski 4f0992ce23 libnv: fix heap overflow in nvlist_recv()
nvlist_check_header() validated nvlh_size for overflow before
performing conversion. An mallicous user can set
NV_FLAG_BIG_ENDIAN in the header and craft nvlh_size so that
the orginall value passes the check, but after the conversion the
sizeof(nvlist_header) + size can overflow.
This can lead to a heap buffer overflow.

Approved by:	so
Security:	FreeBSD-SA-26:17.libnv
Security:	CVE-2026-35547
Fixes:		36fa90dbde
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D56342
2026-04-28 20:33:58 +00:00
Mariusz Zaborski a5cb4863d6 libnv: switch fd_wait() from select(2) to poll(2)
The previous implementation used FD_SET() on a stack-allocated fd_set,
which is an out-of-bounds write whenever the socket fd is >= FD_SETSIZE
(1024).

Approved by:	so
Security:	FreeBSD-SA-26:16.libnv
Security:	CVE-2026-39457
Reported by:	Joshua Rogers of AISLE Research Team (https://aisle.com/)
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D56689
2026-04-28 20:33:58 +00:00
Mariusz Zaborski adaed0700d libnv: add tests to verify potential overflow issues
Approved by:	so
Differential Revision:  https://reviews.freebsd.org/D46131

(cherry picked from commit 241a7ddd71)
2026-04-28 20:33:58 +00:00
Mariusz Zaborski 64c0919d2c libnv: add test to verify null termination of string in array
Approved by:	so
Differential Revision:  https://reviews.freebsd.org/D46138

(cherry picked from commit 2981431e04)
2026-04-28 20:33:58 +00:00
Kristof Provost 0cbe512c7a pf: improve SCTP validation
As per RFC5061 "4.2.  New Parameter Types" the add/delete IP address
parameters (0xc001, 0xc002) may not be present in an INIT or INIT-ACK
chunk. They are only allowed to be present in an ASCONF chunk.

This also prevents unbounded recursion while parsing an SCTP packet.

Approved by:	so
Security:	FreeBSD-SA-26:14.pf
Security:	CVE-2026-7164
PR:		294799
Reported by:	Igor Gabriel Sousa e Souza
Sponsored by:	Orange Business Services
2026-04-28 20:33:58 +00:00
Mark Johnston d60456d859 dhclient: Fix reallocation of dhclient script environments
When the number of DHCP options exceeds a threshold, script_set_env()
will reallocate the environment, stored as an array of pointers.  The
calculation of the array size failed to multiply by the pointer size,
resulting in a smaller than expected buffer which admits out-of-bounds
writes.

Approved by:	so
Security:	FreeBSD-SA-26:15.dhclient
Security:	CVE-2026-42511
Reported by:	Joshua Rogers of AISLE Research Team (https://aisle.com/)
2026-04-28 20:33:58 +00:00
Mark Johnston 73b801e3b5 dhclient: Check for unexpected characters in some DHCP server options
Some options are written directly to the lease file, which may be parsed
by subsequent dhclient invocations.  We must make sure that a malicious
server can't control the "medium" field of a lease definition, otherwise
they can achieve RCE by injecting one into the lease file, whereupon it
will be passed to dhclient-script, which passes it through eval.

Approved by:	so
Security:	FreeBSD-SA-26:12.dhclient
Security:	CVE-2026-42511
Reported by:	Joshua Rogers of AISLE Research Team (https://aisle.com/)
2026-04-28 20:33:58 +00:00
Mark Johnston 943aa64ba9 execve: Fix an operator precedence bug
The buggy version allowed userspace to overflow the copy into adjacent
execve KVA regions, which enables, among other things, injecting
environment variables into privileged processes.

Approved by:	so
Security:	FreeBSD-SA-26:13.exec
Security:	CVE-2026-7270
Reported by:	Ryan Austin of Calif.io
Reviewed by:	brooks, kib
Fixes:		f373437a01 ("Add helper functions to copy strings into struct image_args.")
Differential Revision:	https://reviews.freebsd.org/D56665
2026-04-28 20:33:58 +00:00
Kyle Evans b007852059 amd64: fix INVLPGB range invalidation
AMD64 Architecture Programmer's Manual Volume 3 says the following:

> ECX[15:0] contains a count of the number of sequential pages to
> invalidate in addition to the original virtual address, starting from
> the virtual address specified in rAX. A count of 0 invalidates a
> single page. ECX[31]=0 indicates to increment the virtual address at
> the 4K boundary. ECX[31]=1 indicates to increment the virtual address
> at the 2M boundary. The maximum count supported is reported in
> CPUID function 8000_0008h, EDX[15:0].

ECX[31] being what we call INVLPGB_2M_CNT, signaling to increment the
VA by 2M.

> This instruction invalidates the TLB entry or entries, regardless of
> the page size (4 Kbytes, 2 Mbytes, 4 Mbytes, or 1 Gbyte). [...]

Combined with this, my interpretation of the current code is: if
<va> is aligned on a PDE boundary, we'll use INVLPGB_2M_CNT to try and
invalidate <cnt> PDEs with a single call, but that only works if <va> is
the start of at least <cnt> 2M pages.  Otherwise, if <va> or any of the
subsequent PDEs isn't actually a superpage, then we would actually only
invalidate the *first* page within the PDE before skipping to the next
PDE, leaving the remainder of the 4K pages in between as they were.

The implication would seem to be that we would need to inspect the range
that we're trying to invalidate if we're planning on using
INVLPGB_2M_CNT at all, so this patch just simplifies it to a series of
4K invalidations.  My gut feeling is that we likely still come out on
top vs. the TLB shootdown we're avoiding.

This seems to explain some issues we've seen lately with fdgrowtable()
and kqueue on recent Zen4/Zen5 EPYC hardware, where we'd experience
corruption that we can't explain.

Approved by:	so
Security:	FreeBSD-EN-26:10.amd64
PR:		293382
Reviewed by:	alc, kib, markj

(cherry picked from commit 1b8e5c02f5)
(cherry picked from commit ff11ae166c)
2026-04-28 20:33:58 +00:00
Philip Paeps 677aeab69b contrib/tzdata: import tzdata 2026a and 2026b
Changes: https://github.com/eggert/tz/blob/2026a/NEWS
Changes: https://github.com/eggert/tz/blob/2026b/NEWS

Approved by:	so
Security:	FreeBSD-EN-26:09.tzdata

(cherry picked from commit 6becc3dff9)
(cherry picked from commit 4830cb713e)
(cherry picked from commit 9b95cab0a2)
(cherry picked from commit 30eb33424e)
2026-04-28 20:33:58 +00:00
Mark Johnston 6dc9b78eb7 Add UPDATING entries and bump version
Approved by:	so
2026-04-21 15:45:06 +00:00
Mark Johnston 5787df30dc pkru: Fix handling of 1GB largepage mappings
pmap_pkru_update_range() did not handle the case where a PDPE has PG_PS
set.  More generally, the SET_PKRU and CLEAR_PKRU sysarch
implementations did not check whether the request covers a "boundary" vm
map entry.  Fix this, add the missing PG_PS test, and add some tests.

Approved by:	so
Security:	FreeBSD-SA-26:11.amd64
Security:	CVE-2026-6386
Reported by:	Nicholas Carlini <[email protected]>
Reviewed by:	kib, alc
Differential Revision:	https://reviews.freebsd.org/D56184
2026-04-21 15:45:06 +00:00
Mark Johnston af294329c5 tty: Avoid leaving dangling pointers in tty_drop_ctty()
The TIOCNOTTY handler detaches the calling process from its controlling
terminal.  It clears the link from the session to the tty, but not the
pointers from the tty to the session and process group.  This means that
sess_release() doesn't call tty_rel_sess(), and that pgdelete() doesn't
call tty_rel_pgrp(), so the pointers are left dangling.

Fix this by clearing pointers in tty_drop_ctty().  Add a standalone
regression test.

Approved by:	so
Security:	FreeBSD-SA-26:10.tty
Security:	CVE-2026-5398
Reported by:	Nicholas Carlini <[email protected]>
Reviewed by:	kib, kevans
Fixes:		1b50b999f9 ("tty: implement TIOCNOTTY")
Differential Revision:	https://reviews.freebsd.org/D56046
2026-04-21 15:45:06 +00:00
Jake Freeland df8d2f9450 timerfd: Fix interval callout scheduling
When a timerfd interval callout misses its scheduled activation time, a
differential is calculated based on the actual activation time and the
scheduled activation time. This differential is divided by the timerfd's
interval time and the quotient is added to the timerfd's counter.

Before this change, the next callout was scheduled to activate at:
scheduled activation time + timerfd interval.

This change fixes the scheduling of the next callout to activate at:
actual activation time + timerfd interval - remainder.

Security:		FreeBSD-26:06.timerfd
Approved by:		so
Reviewed by:		markj
Differential Revision:	https://reviews.freebsd.org/D55790
MFC after:		2 weeks

(cherry picked from commit 85c0f1a87d)
(cherry picked from commit 3c00f603a2)
2026-04-21 15:45:06 +00:00
Mark Johnston 1abe7ead45 vm_fault: Reset m_needs_zeroing properly
- When allocating a page, we should only consider the PG_ZERO flag when
  handling the top-level page.
- Unconditionally reset the flag when restarting the fault handler.
  Previously, vm_fault_busy_sleep() would fail to reset it.

Approved by:	so
Security:	FreeBSD-EN-26:05.vm
PR:		294039
Reviewed by:	kib
Tested by:	Peter Much <[email protected]>
MFC after:	3 days
Fixes:		cff67bc43d ("vm_fault: only rely on PG_ZERO when the page was newly allocated")
Differential Revision:	https://reviews.freebsd.org/D56234

(cherry picked from commit 04132e0100)
(cherry picked from commit 9b7c0f4f81)
2026-04-21 15:45:02 +00:00
Philip Paeps a5812c7763 Add UPDATING entries and bump version
Approved by:	so
2026-03-26 00:11:11 +08:00
Kristof Provost b6865bca4b pf: include all elements when hashing rules
Approved by:	so
Security:	FreeBSD-SA:26:09.pf
Security:	CVE-2026-4748
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit c6bcf6e6fd)
(cherry picked from commit e3b801edde)
2026-03-26 00:11:07 +08:00
Kristof Provost a429dbb47f pfctl: always warn if a duplicate rule was detected
Approved by:	so
Security:	FreeBSD-SA:26:09.pf
Security:	CVE-2026-4748
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit 66d66dd0f6)
(cherry picked from commit e79818ec36)
2026-03-26 00:11:03 +08:00
Kristof Provost 984b570b49 pf tests: verify that we handle address range rules correctly
There's been a problem where rules which differed only in address ranges
were considered duplicates and not added. Test for this.

Approved by:	so
Security:	FreeBSD-SA:26:09.pf
Security:	CVE-2026-4748
Sponsored by:	Rubicon Communications, LLC ("Netgate")

(cherry picked from commit ab74151e8d)
(cherry picked from commit 958dbc87e9)
2026-03-26 00:10:59 +08:00
Michael Gmelin 4708ee4543 pf: Fix hashing of IP address ranges
This corrects the false detection of duplicate rules.

Approved by:	so
Security:	FreeBSD-SA:26:09.pf
Security:	CVE-2026-4748
Reviewed by:	kp

(cherry picked from commit 1fa873c93c)
(cherry picked from commit ac6bb58a71)
2026-03-26 00:10:16 +08:00
Mark Johnston 7ea03a4238 rpcsec_gss: Fix a stack overflow in svc_rpc_gss_validate()
svc_rpc_gss_validate() copies the input message into a stack buffer
without ensuring that the buffer is large enough.  Sure enough,
oa_length may be up to 400 bytes, much larger than the provided space.
This enables an unauthenticated user to trigger an overflow and obtain
remote code execution.

Add a runtime check which verifies that the copy won't overflow.

Approved by:	so
Security:	FreeBSD-SA-26:08.rpcsec_gss
Security:	CVE-2026-4747
Reported by:	Nicholas Carlini <[email protected]>
Reviewed by:	rmacklem
Fixes:		a9148abd9d
2026-03-25 14:54:10 +08:00
Michael Tuexen 44dd8b5839 tcp: plug an mbuf leak
When a challenge ACK should be sent via tcp_send_challenge_ack(),
but the rate limiter suppresses the sending, free the mbuf chain.
The caller of tcp_send_challenge_ack() expects this similar to the
callers of tcp_respond().

Approved by:	so
Security:	FreeBSD-SA-26:06.tcp
Security:	CVE-2026-4247
Reviewed by:	lstewart
Tested by:	lstewart
Sponsored by:	Netflix, Inc.
2026-03-25 14:53:41 +08:00
Colin Percival a456f852d1 Update in preparation for 14.4-RELEASE
- Bump BRANCH to RELEASE
- Add the anticipated RELEASE announcement date
- Set a static __FreeBSD_version

Approved by:	re (implicit)
Sponsored by:	OpenSats Initiative
2026-03-06 00:00:00 +00:00
Colin Percival 041aa28386 14.4: Update to RC1
Approved by:	re (implicit)
Sponsored by:	OpenSats Initiative
2026-02-27 00:00:00 +00:00
Colin Percival 12143e3e3a Switch from "quarterly" to "release" pkgs on DVD
Approved by:	re (implicit)
Sponsored by:	OpenSats Initiative
2026-02-26 14:41:52 -08:00
Dag-Erling Smørgrav ca76ec7c4e libfetch: Fail hard if interrupted while connecting
This fixes an issue where the first address that DNS returns is blocked
by a packet filter, so we hang for a while, then the user hits Ctrl-C,
interrupting connect(2), whereupon we move on to the next address, get
a connection, request the file, and return to fetch(1), which sees that
SIGINT was caught and bails.

Note that we make no attempt to enforce fetchTimeout in the connection
phase, and never have.  It's feasible, but non-trivial, so we'll leave
it as an exercise for future us.

PR:		293312
MFC after:	1 week
Reviewed by:	imp
Differential Revision:	https://reviews.freebsd.org/D55406

(cherry picked from commit afbdcd402b)
(cherry picked from commit cca6f5eadb)
2026-02-26 10:00:38 -08:00
Ahmad Khalifa 3cf73e195a bsdinstall: fix EFI boot entry creation
update_uefi_bootentry assumes that the caller sets FREEBSD_BOOTNAME and
mntpt, which isn't the case anymore. The result is that there is no
"FreeBSD" boot entry created/updated after install. Most machines manage
to boot from the removable media path (if the loader is installed there
too), but some don't.

Take the loader's path as an argument and rename the variable used in
the ZFS mirror loop so mntpt can be reused below.

Also mark nentries as a local variable so it doesn't leak out of the
function.

PR:		293385
Fixes:		494de51bc0
MFC after:	2 days
Reviewed by:	imp
Differential Revision:	https://reviews.freebsd.org/D55469

(cherry picked from commit 0fd91c4891)
(cherry picked from commit cfdd90abab)
2026-02-26 08:50:15 -08:00
Mark Johnston 49684d7d93 nullfs: Fix handling of doomed vnodes in nullfs_unlink_lowervp()
nullfs_unlink_lowervp() is called with the lower vnode locked, so the
nullfs vnode is locked too.  The following can occur:
1. the vunref() call decrements the usecount 2->1,
2. a different thread calls vrele() on the vnode, decrements the
   usecount 0->1, then blocks on the vnode lock,
3. the first thread tests vp->v_usecount == 0 and observes that it is
   true,
4. the first thread incorrectly unlocks the lower vnode.

Fix this by testing VN_IS_DOOMED directly.  Since
nullfs_unlink_lowervp() holds the vnode lock, the value of the
VIRF_DOOMED flag is stable.

Thanks to leres@ for patiently helping to track this down.

PR:		288345
MFC after:	1 week
Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D55446

(cherry picked from commit 8b64d46fab)
(cherry picked from commit 6ed3732276)
2026-02-25 19:12:43 -08:00
Colin Percival 20cff160e1 pkg-stage.sh: Add ext2 and ntfs
Having these packages available on release media may help users who
need to sneakernet other packages (e.g. firmware) from systems running
Linux or Windows.

Suggested by:	vladlen, ziaee
MFC after:	3 days

(cherry picked from commit 6881fd278d)
(cherry picked from commit a2c2de82c0)
2026-02-25 16:23:37 -08:00
Colin Percival 6ecd231b9e pkg-stage.sh: Add emacs@nox and vim
We have a bit of space left on the 14.4 DVDs; add packages for two
editors, one of which is useful.

Direct commit to stable/14: These packages were added to 15.0 but
at the same time as removing kde, because shipping distribution sets
*and* a pkgbase repository on 15 significantly cuts into the space
available.  On 14 we can keep kde and still add these packages.

With hat:	re
MFC after:	3 days

(cherry picked from commit d982b7bd4e)
2026-02-25 16:23:31 -08:00
Mark Johnston 7465d0b094 rtsock: Fix stack overflow
Approved by:	so
Approved by:	re (cperciva)
Security:	FreeBSD-SA-26:05.route
Security:	CVE-2026-3038
Fixes:		92be2847e8 ("rtsock: Avoid copying uninitialized padding bytes")

(cherry picked from commit f3be7df50f)
(cherry picked from commit 1eb2beb368)
2026-02-24 16:02:21 +00:00
Colin Percival 0c49d9fafc 14.3: Update to BETA3
Approved by:	re (implicit)
Sponsored by:	OpenSats Initiative
2026-02-20 00:00:00 +00:00
Gleb Smirnoff 7c81bf5191 ng_ksocket: use new macros to lock socket buffers
PR:		292885
Reported by:	Walker R. Thompson <[email protected]>

(cherry picked from commit 1a3d1be496)
(cherry picked from commit 4dc38e71cc)
2026-02-19 14:54:18 -08:00
Baptiste Daroussin 02138275ef usb_vendors: update to 2025.12.13
(cherry picked from commit 8d4c1043bb)
(cherry picked from commit 2f866e0547)
2026-02-19 11:22:24 -08:00
Baptiste Daroussin 7805899ed7 pci_vendors: update to 2026-02-10
(cherry picked from commit 1acfc913e6)
(cherry picked from commit b28b6c6d33)
2026-02-19 11:22:24 -08:00
Baptiste Daroussin 65338ff41f tr: fix class handling in unicode world
toupper/tolower logic was only handled for CCLASS_TOUPPER and
CCLASS_TOLOWER, add support for CCLASS ([:alpha:])

PR:		219900
MFC After: 	1 week

(cherry picked from commit 625dc44832)
(cherry picked from commit 45d84c2f06)
2026-02-19 11:22:24 -08:00
Timo Völker 28b5b653a5 icmp6: clear csum_flags on mbuf reuse
When icmp6 sends an ICMPv6 message, it reuses the mbuf of the packet
that triggered the ICMPv6 message and prepends an IPv6 and ICMPv6
header. For a locally generated packet with checksum offloading, the
mbuf still has csum_flags set indicating that a SCTP/TCP/UDP checksum
has to be computed and inserted. Since this not the case anymore,
csum_flags need to be cleared.

PR:			293227
Reviewed by:		kp, zlei, tuexen
MFC after:		3 days
Differential Revision:	https://reviews.freebsd.org/D55367

(cherry picked from commit ada4dc7757)
(cherry picked from commit 0a87ae1833)
2026-02-19 11:21:55 -08:00
Jessica Clarke 0d08a243f2 Merge commit bfb276e55c from upstream OpenZFS (by Jessica Clarke)
Once upon a time, 32-bit PowerPC did indeed have a 32-bit time_t, but
  FreeBSD 12.0 switched to a 64-bit time_t for PowerPC as an ABI break,
  which predates the addition of FreeBSD support to OpenZFS. Moreover,
  64-bit PowerPC has existed since FreeBSD 9.0, where __powerpc__ is also
  defined (alongside __powerpc64__ to disambiguate), which has always had
  a 64-bit time_t. This code has therefore always been wrong for all
  PowerPC variants. Fix this by limiting the 32-bit case to just i386,
  which is the only architecture in FreeBSD to have a 32-bit time_t and
  not have broken ABI, due to its special legacy compatibility status.

  Reviewed-by: Brian Behlendorf <[email protected]>
  Reviewed-by: Alexander Motin <[email protected]>
  Signed-off-by: Jessica Clarke <[email protected]>
  Closes #18217
  Closes #18218

Reported by:	fuz
MFC after:	1 day

(cherry picked from commit 45c1e44779)
(cherry picked from commit 354cc5e142)
2026-02-19 11:21:28 -08:00
Dag-Erling Smørgrav 8755b5f3a5 libfetch: Restore timeout functionality
PR:		293124
MFC after:	1 week
Fixes:		792ef1ae7b ("Refactor fetch_connect() and fetch_bind() to improve readability and avoid repeating the same DNS lookups.")
Reverts:	8f8a7f6fff ("libfetch: apply timeout to SSL_read()")
Reviewed by:	eugen, imp
Differential Revision:	https://reviews.freebsd.org/D55293

(cherry picked from commit 73b82d1b0a)
(insta-mfc requested by re@)
(cherry picked from commit d97c824f5b)
2026-02-19 11:21:21 -08:00
Dmitry Morozovsky 7f1e9f9451 pw: make manual page more friendly for uid/gid search
pw.8 structure is quite different from usual manual page, especially in
describing -o option usage.  Specifically, these paragraphs do not
contain "uid/gid" terms, and have "user id"/"group id" instead,
making searching for "override duplicate safety belt" difficult.
Try to simplify such searches.

Also, clarify uid/gid space between 100 and 1000 as "somewhat special",
as it actually is.

Discussed on:   russian telegram FreeBSD group
Reviewed by:	eugen, novel
MFC after:      1 week

(cherry picked from commit e89454417b)
(cherry picked from commit 8a2d04cf8c)
2026-02-18 08:28:43 -08:00
Dag-Erling Smørgrav f16fc39527 ngctl: Fix buffer overflow in config command
Keep track of our buffer length when assembling the argument list.

PR:		293075
MFC after:	1 week
Reviewed by:	zlei, markj
Differential Revision:	https://reviews.freebsd.org/D55259

(cherry picked from commit 59906a163e)
(cherry picked from commit e5bf728058)
2026-02-17 17:48:33 -08:00
Dag-Erling Smørgrav 6316ab68d3 ngctl: Check hook name length
Check the length of the hook name when copying it into the sockaddr.

MFC after:	1 week
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D55258

(cherry picked from commit 585190dff4)
(cherry picked from commit 71c0f48ab1)
2026-02-17 17:48:33 -08:00
Konstantin Belousov 71ed9ae5e6 kern/vfs_unmount.c: promote flags to uint64_t
(cherry picked from commit 8066b8923e)
(cherry picked from commit 00095a0896)
2026-02-17 17:47:16 -08:00
Konstantin Belousov 0235e9e569 unmount(2): do not allow MNT_DEFERRED or MNT_RECURSE flags from userspace
(cherry picked from commit cd8d44173a)
(cherry picked from commit a893e8463a)
2026-02-17 17:47:16 -08:00
Konstantin Belousov 39dd0d8a0d kqtimer_proc_continue(): correct calculation of 'now'
PR:	293141

(cherry picked from commit e7f86f8b13)
(cherry picked from commit cf941029dd)
2026-02-17 17:47:15 -08:00
Konstantin Belousov 37fa2e7695 filt_timerexpire_l(): re-insert restarted timer into head instead of tail
PR:	293141

(cherry picked from commit 75a30ea09f)
(cherry picked from commit 119af90d48)
2026-02-17 17:47:15 -08:00
Dimitry Andric d2136eeb14 BSD.usr.dist: remove obsolete usr/share/examples/drivers entry
In base 8f0a6a9aad, usr/share/examples/drivers was cleaned up,
because it contained unmaintained scripts. The directory itself is
cleaned up by ObsoleteFiles.inc, but there was still an entry in
BSD.usr.dist that re-created the directory. Remove it.

Fixes:		8f0a6a9aad
MFC after:	3 days

(cherry picked from commit ac2f284258)
(cherry picked from commit c44a4859c3)
2026-02-14 13:59:15 -08:00
Colin Percival f2dc20d2d2 14.3: Update to BETA2
Approved by:	re (implicit)
Sponsored by:	OpenSats Initiative
2026-02-13 00:00:00 +00:00
Dag-Erling Smørgrav 53e0a1d1ff libfetch: Check for failure to create SSL context
* Drop the ssl_meth member, there is no reason to hang on to it.

* Replace deprecated SSLv23_client_method() with TLS_client_method().

* Check the return value from SSL_CTX_new().

Approved by:	re (cperciva)
MFC after:	1 week
PR:		292903
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D55098

(cherry picked from commit 4e160c6197)
(cherry picked from commit 4781aeb5b9)
2026-02-12 13:24:34 -08:00
Colin Percival e8918d58a2 release: Turn off debugging in pkg(8)
Running `pkg -d` in pkg-stage.sh results in multiple GB of network
traffic being written into the log files, which is less than helpful
when it comes to tracking down build failures.  Remove the -d flag.

Approved by:	re (cperciva)
MFC after:	5 days
X-MFC-note:	The code in 15 has diverged from 14, but the flag is
		there, just in a different place.

(cherry picked from commit 18721be356)
(cherry picked from commit 721dfa7e5a)
2026-02-12 13:24:30 -08:00
Colin Percival 8b34da3d3e Makefile.incl1: .WAIT before distribute in etc
In order to make sure that man pages are all installed before we run
makewhatis to generate mandoc.db files, we have long placed etc at the
end of the list of subdirectories being recursed into by the build.
In order to support installworld -jN, a .WAIT was more recently added
here.

With the recent adoption by the release engineering team of parallel
*release* builds (aka 'make release -jN') it is now also necessary to
add the same .WAIT before recursing for the 'distribute' target, as we
otherwise end up with distribution sets containing incomplete mandoc.db
files.

Approved by:	re (cperciva)
Reviewed by:	bdrewery
PR:		289683
MFC after:	3 days
Sponsored by:	https://www.patreon.com/cperciva
Differential Revision:	https://reviews.freebsd.org/D53533

(cherry picked from commit dcb6706ba4)
(cherry picked from commit cd8a5000b3)
2026-02-12 13:24:27 -08:00
Colin Percival fce4758b71 uart: Add ns8250 ACPI entry for SPCR rev 2
This is an MFC "in spirit" of a685a263b803; the code in this area has
been significantly restructured between 14.x and 15.x, but the general
concept of adding ACPI_DBG2_16550_WITH_GAS (aka 0x12) as a recognized
flavour of ns8250 UART which can be configured via SPCR remains.

Approved by:	re (cperciva)
Reviewed by:	imp
Tested by:	David Woodhouse
Sponsored by:	Amazon
Differential Revision:	https://reviews.freebsd.org/D55173

(cherry picked from commit 1dd5b197b7)
2026-02-12 13:24:22 -08:00
Boris Lytochkin 969e2b4068 ipfw: add ability to run ipfw(8) binary with 15.0+ kernel module
After D46183 the KBI was changed and this made the upgrade procedure
to 15.0+ version a bit difficult, because the old binary can not load
firewall rules when the new kernel is loaded.

This commit adds the sbin/ipfw15 binary that uses new KBI, and then
original sbin/ipfw can detect new KBI and run the new binary instead.

Approved by:	re (cperciva)
PR:		291562
Reviewed by:	jhb, glebius
Fixes:		4a77657cbc
MFC after:	3 days
Differential Revision:	https://reviews.freebsd.org/D54763

(cherry picked from commit 704ec5e68c)
2026-02-12 11:28:43 -08:00
Zhenlei Huang 2f47676012 qlnxe: Overhaul setting the multicast MAC filters
When operating the multicast MAC filters, the current usage of
ECORE_FILTER_ADD and ECORE_FILTER_REMOVE are rather misleading.
ECORE_FILTER_ADD reads "adding new filter", but it actually removes
any existing filters and then addes a new one. ECORE_FILTER_REMOVE
reads "removing a filter", but it actually removes all filters.
Let's use ECORE_FILTER_REPLACE and ECORE_FILTER_FLUSH instead to
avoid confusion.

In the current implementation, only one MAC address is passed to
ecore_sp_eth_filter_mcast() and any previously installed filters are
removed, hence it breaks the multicast function. That can be observed
via either assigning new IPv6 addresses to the interface or putting
the interface as a member of lagg(4) interface with LACP aggregation
protocol. Fix that by calculating the multicast filter bins directly
from multicast MAC addresses and replace the filters every time
the bins changes.

Due to the nature of the multicast filter, which is hash based, a
full 1's multicast filter bin means all multicast packets are to be
accepted. Thus there's no need to make the vport into allmulti mode
when the number of multicast MAC addresses exceeds the limit
(ECORE_MAX_MC_ADDRS, 64).

Tested with a FastLinQ QL41212HLCU 25GbE adapter, both MFW_Version
8.35.23.0 and 8.59.16.0 are tested.

Note: Currently the VF port is set to promiscuous mode unconditionally,
and the setting of the multicast MAC filters for VF ports is
short-circuited, so the VF port functions as it did.

Approved by:	re (cperciva)
PR:		265857
PR:		290973
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54892

(cherry picked from commit 70256d2b86)
(cherry picked from commit 0cfc1145cd)
(cherry picked from commit 87942d7f8f)
2026-02-11 12:29:25 -08:00
Zhenlei Huang 572d4096d3 qlnxe: Allow tapping the TX packets
Currently only the packets in the RX path can be captured by tcpdump
as the ETHER_BPF_MTAP call in the TX path is missing. Add it so that
packets in both directions can be captured.

Approved by:	re (cperciva)
PR:		290973
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54891

(cherry picked from commit 968647502e)
(cherry picked from commit 425b9cec0b)
(cherry picked from commit ddfe98e8cc)
2026-02-11 12:29:22 -08:00
Zhenlei Huang 1e23939306 qlnxe: Refactor setting the promiscuous and allmulti mode
There are two entry points to set the promiscuous and allmulti mode.
One is ioctl, and another is the init routine. Given they share almost
the identical logic, refactor a little to make the code more clear.

While here, for the ioctl, translate the error to EINVAL to avoid
confusing the net stack.

Approved by:	re (cperciva)
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54890

(cherry picked from commit 45b1718fad)
(cherry picked from commit b8d2c1c367)
(cherry picked from commit 00ab0df793)
2026-02-11 12:29:19 -08:00
Zhenlei Huang 133eae6afd qlnxev: Remove now unneeded include for opt_inet.h
Since the change [1], this is not required anymore.

This change partially reverts commit 8a84794715.

[1] 4012b63889 qlnxe: Let ether_ioctl() handle SIOCSIFADDR ioctl

Approved by:	re (cperciva)
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54889

(cherry picked from commit ec7950fe42)
(cherry picked from commit 926e44b498)
(cherry picked from commit e1a051fd53)
2026-02-11 12:29:16 -08:00
Zhenlei Huang be256934d6 qlnxe: Let ether_ioctl() handle SIOCSIFADDR ioctl
Since the change [1], the init routine qlnx_init() works as intended.
Let ether_ioctl() handle SIOCSIFADDR to simplify the code.

Combined with the change [1], this shall be a better fix for PR 287445.

[1] c10e6bc0f0 qlnxe: Avoid reinitializing the interface when it is already initialized

Approved by:	re (cperciva)
PR:		287445
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54888

(cherry picked from commit 4012b63889)
(cherry picked from commit 0f383f74b7)
(cherry picked from commit 20ffe22fcf)
2026-02-11 12:29:13 -08:00
Zhenlei Huang 7d0345d32b qlnxe: Avoid reinitializing the interface when it is already initialized
qlnx_init_locked() unconditionally uninitialize the interface thus is
actually reinitializing the interface. Well the init routine qlnx_init()
is to initialize the interface by net stack when assigned with the first
inet or inet6 address. The ioctl SIOCSIFADDR for the first inet6 address
is handled by ether_ioctl() thus the interface is reinitialized no matter
it was initialized or not.

Add a driver status check for that to avoid reinitializing. Further plan
is removing SIOCSIFADDR ioctl from the driver and let ether_ioctl() handle
it.

Approved by:	re (cperciva)
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54887

(cherry picked from commit c10e6bc0f0)
(cherry picked from commit 8731ff4871)
(cherry picked from commit ee64955809)
2026-02-11 12:29:10 -08:00
Zhenlei Huang 0671ffe268 qlnxe: Prevent potential concurrency between ioctls
The driver-managed status flags should be lock protected to be touched.
Also this can serialize ioctls those check the IFF_DRV_RUNNING status.

Approved by:	re (cperciva)
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54886

(cherry picked from commit 0df8a998a9)
(cherry picked from commit 285b25c080)
(cherry picked from commit 6e5b12acb6)
2026-02-11 12:29:07 -08:00
Zhenlei Huang f8e20e75a6 qlnxe: Fix setting the unicast MAC filter of RX path
When an Ethernet interface is added to lagg(4) as a child interface, its
type, aka if_type, is changed from IFT_ETHER to IFT_IEEE8023ADLAG. Well
changing the link-layer address of the lagg(4) interface will be
propagated to all child interfaces, hence the drivers of child interfaces
shall not presume the type of the interface will not be changed.

Meanwhile, on initializing, an ifnet has been fully attached and it is
guaranteed to have non-null link-layer address so stop NULL checking for
it.

Approved by:	re (cperciva)
Reviewed by:	kbowling
Fixes:		792226e530 qlnxe: Allow MAC address override
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54885

(cherry picked from commit f250852c9a)
(cherry picked from commit 6d138e958f)
(cherry picked from commit 93719f8c83)
2026-02-11 12:29:04 -08:00
Zhenlei Huang 36ebcb4f82 qlnxe: Avoid memcpy with same source and destination
In case the device is VF, qlnx_get_mac_addr() returns ha->primary_mac
hence it ends up memcpy with same source and destination. Refactor
slightly to avoid that.

Approved by:	re (cperciva)
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54884

(cherry picked from commit 3aeeedc7e0)
(cherry picked from commit 6462189595)
(cherry picked from commit ea1143bddb)
2026-02-11 12:29:01 -08:00
Zhenlei Huang 6444869020 qlnxe: Remove a pointless copy back from the link-layer address
On ifnet attaching, ether_ifattach() makes the link-layer address by
shadow copying the ha->primary_mac. Well, the link-layer address will
not be altered during attaching, thus it is pointless to copy it back.

No functional change intended.

Approved by:	re (cperciva)
Reviewed by:	kbowling
MFC after:	5 days
Differential Revision:	https://reviews.freebsd.org/D54883

(cherry picked from commit 4ac3081b28)
(cherry picked from commit 23ffd1650c)
(cherry picked from commit 7d7cee09b9)
2026-02-11 12:28:56 -08:00
Jose Luis Duran 4690a369ff Adapt changes from blocklist 2026-02-07 (10a907f)
Also apply the fix from PR 258411.

This is a direct commit to stable/14, as blacklist has been renamed to
blocklist upstream.

Approved by:	re (cperciva)

(cherry picked from commit 30c04399f2)
2026-02-10 22:14:53 -08:00
Dag-Erling Smørgrav 3c10ed2ba3 diff: Report I/O errors in Stone algorithm
In the legacy Stone algorithm, we do a first pass over the files to
check if they're identical before we start diffing them.  That code
would correctly set the exit status if an I/O error was encountered,
but would not emit an error message.  Do so.

Approved by:	re (cperciva)
PR:		292198
MFC after:	1 week
Sponsored by:	Klara, Inc.
Reviewed by:	thj
Differential Revision:	https://reviews.freebsd.org/D55125

(cherry picked from commit f8c12e6e38)
(cherry picked from commit 37ceb8794c)
2026-02-10 22:14:50 -08:00
Dag-Erling Smørgrav 7cf7c711d9 diff: Correctly declare tests
Approved by:	re (cperciva)
Sponsored by:	Klara, Inc.
Fixes:		5fc739eb59 ("diff: Fix integer overflows in Stone algorithm")
Fixes:		270492602b ("diff: Add test case for pagination resource leak")
Fixes:		590126789c ("diff: Don't compare a file or directory to itself")

(cherry picked from commit 157d6664ae)
(cherry picked from commit b8bcf04d6d)
2026-02-10 22:14:46 -08:00
Dag-Erling Smørgrav b4139147bb diff: Don't compare a file or directory to itself
While here, stop abusing struct dirent for something we don't even need
to store.

Approved by:	re (cperciva)
PR:		254455
MFC after:	1 week
Sponsored by:	Klara, Inc.
Reviewed by:	thj, kevans
Differential Revision:	https://reviews.freebsd.org/D55113

(cherry picked from commit 590126789c)

diff: Fix build

rc must be defined first.

Fixes:		590126789c
MFC after:	1 week
X-MFC with:	590126789c

(cherry picked from commit ee44ab936e)
(cherry picked from commit 7f412c6f88)
2026-02-10 22:14:30 -08:00
Dag-Erling Smørgrav 6761e55537 diff: Fix pagination leak
* Drop an unnecessary variable and rename pidfd to procd.

* Rewinding stdout serves no purpose, so stop doing it.

* Don't bother freeing memory or setting the global status right
  before erroring out.

* Error out if dup(2) or dup2(2) fail.

* In the unlikely case that our pipe is equal to stdout, we need to
  record that information so we don't close it when cleaning up.

* Don't bother closing a descriptor before dup2(2)ing to it.

* Don't forget to close the the process descriptor after reaping the
  child process.

Approved by:	re (cperciva)
PR:		266592
MFC after:	1 week
Sponsored by:	Klara, Inc.
Reviewed by:	kevans, markj
Differential Revision:	https://reviews.freebsd.org/D55112

(cherry picked from commit c3904a7de7)
(cherry picked from commit 144455c333)
2026-02-10 22:14:26 -08:00
Dag-Erling Smørgrav 2434f3b279 diff: Add test case for pagination resource leak
The pagination code leaks either processes or descriptors or both,
depending on the exact version of the code you have.  Add a test case
which exercises this leak to facilitate fixing it.

Approved by:	re (cperciva)
MFC after:	1 week
Sponsored by:	Klara, Inc.
Reviewed by:	thj, kevans
Differential Revision:	https://reviews.freebsd.org/D55111

(cherry picked from commit 270492602b)
(cherry picked from commit 51c2384ce0)
2026-02-10 22:14:23 -08:00
Dag-Erling Smørgrav 238bf5ebf6 diff: Fix integer overflows in Stone algorithm
Fix integer overflows that may occur when the context window is very
large and add tests to exercise those conditions.

Approved by:	re (cperciva)
PR:		267032
MFC after:	1 week
Sponsored by:	Klara, Inc.
Reviewed by:	thj, kevans
Differential Revision:	https://reviews.freebsd.org/D55110

(cherry picked from commit 5fc739eb59)
(cherry picked from commit 237fd8dd96)
2026-02-10 22:14:04 -08:00
Mark Johnston 61dbfaa13c amd64/conf: Remove a config committed by accident
Approved by:	re (cperciva)
Reported by:	kib, kp
Fixes:		350ba9672a ("unix: Set O_RESOLVE_BENEATH on fds transferred between jails")

(cherry picked from commit 3ef39f58e5)
(cherry picked from commit 302120bcb9)
2026-02-09 13:37:40 -08:00
Michael Osipov 11b616d9de sockstat: Surround explicit IPv6 addresses with brackets
Approved by:	re (cperciva)
PR:		254611
Approved by:	otis, tuexen, des
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D54375

(cherry picked from commit fe81e3944c)
(cherry picked from commit 03c8e3e771)
2026-02-08 19:09:35 -08:00
Bojan Novković 5d7d22588d pmc: Import Intel Granite Rapids events
Approved by:	re (cperciva)
Reviewed by:	mhorne
Sponsored by:	Klara, Inc.
Obtained from:	Intel perfmon (JSON event definitions)
Differential Revision:	https://reviews.freebsd.org/D55081
MFC after:	2 days

(cherry picked from commit a3ff85e119)
(cherry picked from commit 625ed65183)
2026-02-08 19:09:29 -08:00
Colin Percival df3c9a8a5f Revert "release: Ship firmware from kmods repo on DVD"
While all of the net/wifi-firmware-*-kmod packages are in the "kmod" pkg
repository, the net/wifi-firmware-kmod metapackage itself is not; this
results in the DVD build failing when it can't fetch that.

I'm not sure if the correct fix here is to add kmod-related metapackages
to the kmod repository (even if they themselves do not contain kmods) or
something else; but this needs to be backed out at least temporarily so
that 14.4-BETA1 can happen.

This reverts commit 8c1de31097.

This is a direct commit to releng/14.4 since it is not yet clear whether
this should be permanently removed from other branches and there is no
urgency to do so (since DVD builds are disabled by default).

With hat:	re
Approved by:	re (cperciva)
2026-02-06 12:58:55 -08:00
Alexander Ziaee 7fa4ccb8e4 mandoc: Vendor import of upstream at 2025-09-26
Interesting changes:
+ mandoc db: Improve case sorting, found by our very own markj
+ history: Add macros for version 8 and 10 AT&T Unix
+ linter: Warn on blank lines in man(7) like mdoc(7)
+ manuals: Improve precision, man(7) syntax table, and roff(7) specifics
+ manuals: Fix PDF/PS footer regression detailed in our PR: 289786

Approved by:	re (cperciva)
PR:		289786
MFC after:	3 days

(cherry picked from commit 59fc2b0166)
(cherry picked from commit f763f12ed5)
2026-02-05 17:07:07 -08:00
Ingo Schwarze e261ea9105 mandoc: Improve width calculation for GCC compat
Avoid implicitly converting a potentially negative page offset
to size_t and then back to int.  While this was not a bug and the end
result was portably correct, Alexander Ziaee@ privately reported to me
that the GCC 14 in the FreeBSD Jenkins CI felt uneasy about it.

For clarity and readability, rewrite the truncation statement
to not mix signed and unsigned types, to not use explicit casts,
and make handling of the lower and upper cutoff more similar
to each other.

Approved by:	re (cperciva)
Fixes:  6410c1b51637 (mandoc: vendor import of upstream at 2025-07-27)
MFC after:		3 days
Reported by:		ivy
Reviewed by:		ivy
Differential Revision:	https://reviews.freebsd.org/D52127

(cherry picked from commit 93bc3d83a1)
(cherry picked from commit 0d066d2166)
2026-02-05 17:06:59 -08:00
Alexander Ziaee 8039d22f6a mandoc: Vendor import of upstream at 2025-07-27
Groff Compat Edition -- Interesting changes:
+ italics in section/subsection headers are now also bold, like groff
+ display "LOCAL" in response to invalid section numbers, like groff
+ tbl(7) rendering has been tweaked to be more like groff
+ scaling has been improved to better render poorly generated manuals
+ display "UNTITLED" in response to invalid man(7) titles, like groff
+ improve mandocd error handling of broken pipes
+ manual footers now always show NAME(SECTION) on the right, like groff

Approved by:	re (cperciva)
MFC after:	3 days

(cherry picked from commit 06410c1b51)
(cherry picked from commit a1f4ccd6c7)
2026-02-05 17:06:51 -08:00
Colin Percival 9bbe9bfc66 14.4: create releng/14.4 branch
Update from PRERELEASE to BETA1
Switch pkg(8) configuration to use the quarterly repository
Bump __FreeBSD_version

Approved by:	re (implicit)
Sponsored by:	OpenSats Initiative
2026-02-06 00:00:00 +00:00
3294 changed files with 217157 additions and 143682 deletions

No files matched your search

+1 -1
View File
@@ -437,7 +437,7 @@ SUBDIR+= ${_DIR}
# by calling 'makedb' in share/man. This is only relevant for
# install/distribute so they build the whatis file after every manpage is
# installed.
.if make(installworld) || make(install)
.if make(installworld) || make(install) || make(distributeworld) || make(distribute)
SUBDIR+=.WAIT
.endif
SUBDIR+=etc
+84
View File
@@ -51,6 +51,90 @@
# xargs -n1 | sort | uniq -d;
# done
# 20261020: Regenerate trust store
OLD_FILES+=usr/share/certs/trusted/Atos_TrustedRoot_2011.pem
OLD_FILES+=usr/share/certs/trusted/SecureSign_Root_CA12.pem
OLD_FILES+=usr/share/certs/trusted/ePKI_Root_Certification_Authority.pem
OLD_FILES+=usr/share/certs/trusted/emSign_ECC_Root_CA_-_C3.pem
OLD_FILES+=usr/share/certs/trusted/emSign_ECC_Root_CA_-_G3.pem
OLD_FILES+=usr/share/certs/trusted/emSign_Root_CA_-_C1.pem
OLD_FILES+=usr/share/certs/untrusted/Entrust_Root_Certification_Authority.pem
# 20260430: Regenerate trust store
OLD_FILES+=usr/share/certs/trusted/Entrust_net_Premium_2048_Secure_Server_CA.pem
OLD_FILES+=usr/share/certs/trusted/AffirmTrust_Premium.pem
OLD_FILES+=usr/share/certs/trusted/Starfield_Class_2_CA.pem
OLD_FILES+=usr/share/certs/trusted/GTS_Root_R2.pem
OLD_FILES+=usr/share/certs/trusted/GLOBALTRUST_2020.pem
OLD_FILES+=usr/share/certs/trusted/Secure_Global_CA.pem
OLD_FILES+=usr/share/certs/trusted/GlobalSign_Root_CA.pem
OLD_FILES+=usr/share/certs/trusted/CommScope_Public_Trust_RSA_Root-01.pem
OLD_FILES+=usr/share/certs/trusted/Trustwave_Global_ECC_P384_Certification_Authority.pem
OLD_FILES+=usr/share/certs/trusted/SwissSign_Gold_CA_-_G2.pem
OLD_FILES+=usr/share/certs/trusted/Go_Daddy_Class_2_CA.pem
OLD_FILES+=usr/share/certs/trusted/FIRMAPROFESIONAL_CA_ROOT-A_WEB.pem
OLD_FILES+=usr/share/certs/trusted/Trustwave_Global_Certification_Authority.pem
OLD_FILES+=usr/share/certs/trusted/Trustwave_Global_ECC_P256_Certification_Authority.pem
OLD_FILES+=usr/share/certs/trusted/CommScope_Public_Trust_ECC_Root-01.pem
OLD_FILES+=usr/share/certs/trusted/Entrust_Root_Certification_Authority_-_EC1.pem
OLD_FILES+=usr/share/certs/trusted/Certigna.pem
OLD_FILES+=usr/share/certs/trusted/AffirmTrust_Commercial.pem
OLD_FILES+=usr/share/certs/trusted/DigiCert_Assured_ID_Root_CA.pem
OLD_FILES+=usr/share/certs/trusted/Baltimore_CyberTrust_Root.pem
OLD_FILES+=usr/share/certs/trusted/CommScope_Public_Trust_ECC_Root-02.pem
OLD_FILES+=usr/share/certs/trusted/Entrust_Root_Certification_Authority.pem
OLD_FILES+=usr/share/certs/trusted/AffirmTrust_Premium_ECC.pem
OLD_FILES+=usr/share/certs/trusted/CommScope_Public_Trust_RSA_Root-02.pem
OLD_FILES+=usr/share/certs/trusted/TeliaSonera_Root_CA_v1.pem
OLD_FILES+=usr/share/certs/trusted/QuoVadis_Root_CA_2.pem
OLD_FILES+=usr/share/certs/trusted/COMODO_Certification_Authority.pem
OLD_FILES+=usr/share/certs/trusted/SecureTrust_CA.pem
OLD_FILES+=usr/share/certs/trusted/Comodo_AAA_Services_root.pem
OLD_FILES+=usr/share/certs/trusted/Entrust_Root_Certification_Authority_-_G2.pem
OLD_FILES+=usr/share/certs/trusted/QuoVadis_Root_CA_3.pem
OLD_FILES+=usr/share/certs/trusted/DigiCert_High_Assurance_EV_Root_CA.pem
OLD_FILES+=usr/share/certs/trusted/certSIGN_ROOT_CA.pem
OLD_FILES+=usr/share/certs/trusted/DigiCert_Global_Root_CA.pem
OLD_FILES+=usr/share/certs/trusted/AffirmTrust_Networking.pem
OLD_FILES+=usr/share/certs/trusted/XRamp_Global_CA_Root.pem
OLD_FILES+=usr/share/certs/untrusted/Security_Communication_RootCA3.pem
OLD_FILES+=usr/share/certs/untrusted/GeoTrust_Primary_Certification_Authority_-_G3.pem
OLD_FILES+=usr/share/certs/untrusted/E-Tugra_Global_Root_CA_ECC_v3.pem
OLD_FILES+=usr/share/certs/untrusted/Symantec_Class_2_Public_Primary_Certification_Authority_-_G4.pem
OLD_FILES+=usr/share/certs/untrusted/EE_Certification_Centre_Root_CA.pem
OLD_FILES+=usr/share/certs/untrusted/EC-ACC.pem
OLD_FILES+=usr/share/certs/untrusted/Hellenic_Academic_and_Research_Institutions_RootCA_2011.pem
OLD_FILES+=usr/share/certs/untrusted/GeoTrust_Universal_CA.pem
OLD_FILES+=usr/share/certs/untrusted/Global_Chambersign_Root_-_2008.pem
OLD_FILES+=usr/share/certs/untrusted/Camerfirma_Global_Chambersign_Root.pem
OLD_FILES+=usr/share/certs/untrusted/Verisign_Class_1_Public_Primary_Certification_Authority_-_G3.pem
OLD_FILES+=usr/share/certs/untrusted/Symantec_Class_1_Public_Primary_Certification_Authority_-_G6.pem
OLD_FILES+=usr/share/certs/untrusted/GeoTrust_Primary_Certification_Authority_-_G2.pem
OLD_FILES+=usr/share/certs/untrusted/TrustCor_RootCert_CA-2.pem
OLD_FILES+=usr/share/certs/untrusted/GeoTrust_Universal_CA_2.pem
OLD_FILES+=usr/share/certs/untrusted/Network_Solutions_Certificate_Authority.pem
OLD_FILES+=usr/share/certs/untrusted/thawte_Primary_Root_CA.pem
OLD_FILES+=usr/share/certs/untrusted/E-Tugra_Global_Root_CA_RSA_v3.pem
OLD_FILES+=usr/share/certs/untrusted/GeoTrust_Primary_Certification_Authority.pem
OLD_FILES+=usr/share/certs/untrusted/Taiwan_GRCA.pem
OLD_FILES+=usr/share/certs/untrusted/Verisign_Class_2_Public_Primary_Certification_Authority_-_G3.pem
OLD_FILES+=usr/share/certs/untrusted/Symantec_Class_2_Public_Primary_Certification_Authority_-_G6.pem
OLD_FILES+=usr/share/certs/untrusted/VeriSign_Class_3_Public_Primary_Certification_Authority_-_G5.pem
OLD_FILES+=usr/share/certs/untrusted/SwissSign_Platinum_CA_-_G2.pem
OLD_FILES+=usr/share/certs/untrusted/TrustCor_RootCert_CA-1.pem
OLD_FILES+=usr/share/certs/untrusted/thawte_Primary_Root_CA_-_G3.pem
OLD_FILES+=usr/share/certs/untrusted/Camerfirma_Chambers_of_Commerce_Root.pem
OLD_FILES+=usr/share/certs/untrusted/SwissSign_Silver_CA_-_G2.pem
OLD_FILES+=usr/share/certs/untrusted/TrustCor_ECA-1.pem
OLD_FILES+=usr/share/certs/untrusted/VeriSign_Class_3_Public_Primary_Certification_Authority_-_G4.pem
OLD_FILES+=usr/share/certs/untrusted/SecureSign_RootCA11.pem
OLD_FILES+=usr/share/certs/untrusted/Chambers_of_Commerce_Root_-_2008.pem
OLD_FILES+=usr/share/certs/untrusted/Verisign_Class_3_Public_Primary_Certification_Authority_-_G3.pem
OLD_FILES+=usr/share/certs/untrusted/VeriSign_Universal_Root_Certification_Authority.pem
OLD_FILES+=usr/share/certs/untrusted/LuxTrust_Global_Root_2.pem
OLD_FILES+=usr/share/certs/untrusted/thawte_Primary_Root_CA_-_G2.pem
OLD_FILES+=usr/share/certs/untrusted/Symantec_Class_1_Public_Primary_Certification_Authority_-_G4.pem
# 20251218: Remove old MLINK to apmconf(8)
OLD_FILES+=usr/share/man/man8/apmconf.8.gz
+249
View File
@@ -12,6 +12,255 @@ Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before updating system packages
and/or ports.
20261021:
14.4-RELEASE-p12 SA-26:73.caroot
TLS certificate store updates. [SA-26:73.caroot]
20261014:
14.4-RELEASE-p11 EN-26:25.tzdata
EN-26:26.hastd
EN-26:27.tcp
SA-26:71.sound
SA-26:72.bhyve
Timezone database information update. [EN-26:25.tzdata]
Multiple issues in hastd(8). [EN-26:26.hastd]
TCP timers may overflow and fire late or not at all. [EN-26:27.tcp]
TOCTOU race between sound(4) buffer resizing and mmap. [SA-26:71.sound]
Multiple vulnerabilities in bhyve device models. [SA-26:72.bhyve]
20290928:
14.4-RELEASE-p10 EN-26:24.tzdata
SA-26:64.sysvsem
SA-26:66.jail
SA-26:67.ktls
SA-26:68.openssl
SA-26:69.udp
Timezone database information update. [EN-26:24.tzdata]
Heap out-of-bounds access in semop(2). [SA-26:64.sysvsem]
Multiple jail filesystem root escapes. [SA-26:66.jail]
Remote DOS via receive-side kernel TLS. [SA-26:67.ktls]
OpenSSL CVE-2026-84782. [SA-26:68.openssl]
UDP sendto(2) bypasses jail network isolation. [SA-26:69.udp]
20260825:
14.4-RELEASE-p9 EN-26:20.microcode
EN-26:21.openssl
SA-26:56.hwpmc
SA-26:58.sound
SA-26:60.ppp
SA-26:61.openssl
SA-26:62.tty
SA-26:63.posixshm
Intel CPU microcode not applied during early loading for some CPUs. [EN-26:20.microcode]
OpenSSL pkg-config files contain incorrect versions. [EN-26:21.openssl]
hwpmc fails to detach PMCs during exec credential transitions. [SA-26:56.hwpmc]
Kernel use-after-free via the SNDCTL_DSP_SYNCSTART ioctl. [SA-26:58.sound]
Multiple vulnerabilities in ppp. [SA-26:60.ppp]
Multiple vulnerabilities in OpenSSL. [SA-26:61.openssl]
Kernel use-after-free via tty ioctls. [SA-26:62.tty]
TOCTOU in POSIX shared memory large page configuration. [SA-26:63.posixshm]
20260729:
14.4-RELEASE-p8 EN-26:18.tzdata
SA-26:52.if_wg
SA-26:54.sysvsem
SA-26:55.elf
Timezone database information update. [EN-26:18.tzdata]
Missing MAC validation in wg(4) packet decryption. [SA-26:52.if_wg]
Heap out-of-bounds access in semctl(2). [SA-26:54.sysvsem]
Race condition in ELF core dump segment counting. [SA-26:55.elf]
20260630:
14.4-RELEASE-p7 EN-26:16.arm64
SA-26:37.vm
SA-26:39.execve
SA-26:40.zfs
SA-26:41.libalias
SA-26:42.unlinkat
SA-26:43.tcp
SA-26:44.posixshm
SA-26:45.audit
SA-26:46.ktls
SA-26:47.linux
SA-26:48.compat32
SA-26:49.iconv
32-bit setcontext(2) and swapcontext(2) fail on arm64. [EN-26:16.arm64]
Use-after-free in device pager page list. [SA-26:37.vm]
Local privilege escalation via execve(2) TOCTOU race. [SA-26:39.execve]
Multiple vulnerabilities in OpenZFS. [SA-26:40.zfs]
Buffer overflow in libalias RTSP handler. [SA-26:41.libalias]
unlinkat(2) ignores AT_RESOLVE_BENEATH flag. [SA-26:42.unlinkat]
Use-after-free in TCP RACK stack option handler. [SA-26:43.tcp]
Multiple vulnerabilities in POSIX largepage objects. [SA-26:44.posixshm]
Incorrect audit records for ptrace(2) syscall requests. [SA-26:45.audit]
Remote DOS via uninitialized memory access in KTLS receive. [SA-26:46.ktls]
Kernel stack disclosure in Linux compatibility layer. [SA-26:47.linux]
Kernel stack disclosure in 32-bit compatibility support. [SA-26:48.compat32]
Multiple vulnerabilities in iconv(3). [SA-26:49.iconv]
20260609:
14.4-RELEASE-p6 EN-26:15.openssl
SA-26:25.thr
SA-26:26.ktls
SA-26:27.sound
SA-26:28.capsicum
SA-26:29.ip6_multicast
SA-26:30.linux
SA-26:31.arm64
SA-26:32.elf
SA-26:33.unbound
SA-26:34.vt
SA-26:35.openssl
SA-26:36.ldns
Update OpenSSL to 3.0.20 and 3.5.6. [EN-26:15.openssl]
Missing permission check in thr_kill2(2). [SA-26:25.thr]
Arbitrary file overwrite via the KTLS receive path. [SA-26:26.ktls]
Multiple vulnerabilities in the sound(4) mmap path. [SA-26:27.sound]
sigqueue(2) missing capability mode restriction. [SA-26:28.capsicum]
Use-after-free bug in the IPV6_MSFILTER socket option handler. [SA-26:29.ip6_multicast]
Flaw in Linuxulator execution of setugid binaries. [SA-26:30.linux]
Arm CPU errata may bypass page table permission changes. [SA-26:31.arm64]
ASLR bypass for setuid executables via procctl(2). [SA-26:32.elf]
Multiple vulnerabilities in unbound. [SA-26:33.unbound]
Integer overflow in vt(4) CONS_HISTORY ioctl. [SA-26:34.vt]
Multiple vulnerabilities in OpenSSL. [SA-26:35.openssl]
Insufficient response validation in the ldns stub resolver. [SA-26:36.ldns]
20260520:
14.4-RELEASE-p5 SA-26:18.setcred
SA-26:19.file
SA-26:20.fusefs
SA-26:21.ptrace
SA-26:22.libcasper
SA-26:23.bsdinstall
SA-26:24.cap_net
EN-26:13.freebsd-update
Stack buffer overflow via setcred(2). [SA-26:18.setcred]
Kernel use-after-free via file descriptor syscalls. [SA-26:19.file]
Heap overflow in FUSE_LISTXATTR. [SA-26:20.fusefs]
Missing validation in ptrace(PT_SC_REMOTE). [SA-26:21.ptrace]
Stack overflow via select() file descriptor set overflow. [SA-26:22.libcasper]
Remote code execution via Wi-Fi access point scans. [SA-26:23.bsdinstall]
Incorrect libcap_net limitation list manipulation. [SA-26:24.cap_net]
freebsd-update attempts to merge a generated file. [EN-26:13.freebsd-update]
20260430:
14.4-RELEASE-p4 EN-26:11.dhclient
dhclient(8) lease validation is too strict. [EN-26:11.dhclient]
20260429:
14.4-RELEASE-p3 SA-26:12.dhclient
SA-26:13.exec
SA-26:14.pf
SA-26:15.dhclient
SA-26:16.libnv
SA-26:17.libnv
EN-26:09.tzdata
EN-26:10.amd64
Remote code execution via malicious DHCP options. [SA-26:12.dhclient]
Local privilege escalation via execve(). [SA-26:13.exec]
pf can overflow the stack parsing crafted SCTP packets. [SA-26:14.pf]
Remotely triggerable out-of-bounds heap write in dhclient. [SA-26:15.dhclient]
Stack overflow via select() file descriptor set overflow. [SA-26:16.libnv]
Heap overflow in libnv. [SA-26:17.libnv]
Timezone database information update. [EN-26:09.tzdata]
TLB invalidation bug on AMD systems with INVLPGB. [EN-26:10.amd64]
20260421:
14.4-RELEASE-p2 SA-26:10.tty
SA-26:11.amd64
EN-26:05.vm
EN-26:06.timerfd
Kernel use-after-free bug in the TIOCNOTTY handler. [SA-26:10.tty]
Missing large page handling in pmap_pkru_update_range(). [SA-26:11.amd64]
The page fault handler fails to zero memory. [EN-26:05.vm]
Periodic timerfd(2) timers may produce incorrect results. [EN-26:06.timerfd]
20260325:
14.4-RELEASE-p1 SA-26:06.tcp
SA-26:08.rpcsec_gss
SA-26:09.pf
TCP: remotely exploitable DoS vector (mbuf leak). [SA-26:06.tcp]
Remote code execution via RPCSEC_GSS packet validation. [SA-26:08.rpcsec_gss]
pf silently ignores certain rules. [SA-26:09.pf]
20260310:
14.4-RELEASE.
20260116:
Bump __FreeBSD_version to 1403508 for various LinuxKPI changes
so they could be detected if needed.
+15 -14
View File
@@ -339,10 +339,10 @@ addfd(struct pollfd **pfdp, bl_t **blp, size_t *nfd, size_t *maxfd,
exit(EXIT_FAILURE);
if (*nfd >= *maxfd) {
*maxfd += 10;
*blp = realloc(*blp, sizeof(**blp) * *maxfd);
*blp = reallocarray(*blp, *maxfd, sizeof(**blp));
if (*blp == NULL)
err(EXIT_FAILURE, "malloc");
*pfdp = realloc(*pfdp, sizeof(**pfdp) * *maxfd);
*pfdp = reallocarray(*pfdp, *maxfd, sizeof(**pfdp));
if (*pfdp == NULL)
err(EXIT_FAILURE, "malloc");
}
@@ -366,7 +366,7 @@ uniqueadd(struct conf ***listp, size_t *nlist, size_t *mlist, struct conf *c)
}
if (*nlist == *mlist) {
*mlist += 10;
void *p = realloc(*listp, *mlist * sizeof(*list));
void *p = reallocarray(*listp, *mlist, sizeof(*list));
if (p == NULL)
err(EXIT_FAILURE, "Can't allocate for rule list");
list = *listp = p;
@@ -451,8 +451,8 @@ main(int argc, char *argv[])
case 's':
if (nblsock >= maxblsock) {
maxblsock += 10;
void *p = realloc(blsock,
sizeof(*blsock) * maxblsock);
void *p = reallocarray(blsock, maxblsock,
sizeof(*blsock));
if (p == NULL)
err(EXIT_FAILURE,
"Can't allocate memory for %zu sockets",
@@ -527,14 +527,15 @@ main(int argc, char *argv[])
state = state_open(dbfile, flags, 0600);
if (state == NULL)
state = state_open(dbfile, flags | O_CREAT, 0600);
if (state == NULL)
return EXIT_FAILURE;
if (restore) {
if (!flush)
rules_flush();
rules_restore();
else {
if (restore) {
if (!flush)
rules_flush();
rules_restore();
}
}
if (state == NULL)
exit(EXIT_FAILURE);
if (!debug) {
if (daemon(0, 0) == -1)
@@ -556,7 +557,7 @@ main(int argc, char *argv[])
if (errno == EINTR)
continue;
(*lfun)(LOG_ERR, "poll (%m)");
return EXIT_FAILURE;
exit(EXIT_FAILURE);
case 0:
state_sync(state);
break;
@@ -572,5 +573,5 @@ main(int argc, char *argv[])
update();
}
state_close(state);
return 0;
exit(EXIT_SUCCESS);
}
+2 -2
View File
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd May 18, 2020
.Dd January 13, 2026
.Dt BLACKLISTD.CONF 5
.Os
.Sh NAME
@@ -102,7 +102,7 @@ The syntax for the
.Va location
is:
.Bd -literal -offset indent
[<address>|<interface>][/<mask>][:<port>]
[<address>|<interface>[/<mask>]:]<port>
.Ed
.Pp
The
+7 -6
View File
@@ -62,10 +62,10 @@ static char *
run(const char *cmd, const char *name, ...)
{
const char *argv[20];
size_t i;
size_t i, len;
va_list ap;
FILE *fp;
char buf[10240], *res;
char *line, *res;
argv[0] = "control";
argv[1] = cmd;
@@ -77,6 +77,7 @@ run(const char *cmd, const char *name, ...)
va_end(ap);
if (debug) {
char buf[2048];
size_t z;
int r;
@@ -97,10 +98,10 @@ run(const char *cmd, const char *name, ...)
(*lfun)(LOG_ERR, "popen %s failed (%m)", controlprog);
return NULL;
}
if (fgets(buf, sizeof(buf), fp) != NULL)
res = strdup(buf);
else
res = NULL;
line = res = NULL;
len = 0;
if (getline(&line, &len, fp) >= 0)
res = line;
pclose(fp);
if (debug)
(*lfun)(LOG_DEBUG, "%s returns %s", cmd, res);
-1
View File
@@ -117,7 +117,6 @@ fmtydhms(char *b, size_t l, time_t t)
y = t;
z = 0;
o = 0;
#define APPEND(a) \
if (a) { \
+37 -34
View File
@@ -45,19 +45,19 @@ __RCSID("$NetBSD: popenve.c,v 1.2 2015/01/22 03:10:50 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef __weak_alias
__weak_alias(popen,_popen)
@@ -71,8 +71,8 @@ static struct pid {
int fd;
#endif
pid_t pid;
} *pidlist;
} *pidlist;
#ifdef _REENTRANT
static rwlock_t pidlist_lock = RWLOCK_INITIALIZER;
#endif
@@ -109,11 +109,25 @@ pdes_get(int *pdes, const char **type)
#endif
}
if ((cur = malloc(sizeof(*cur))) != NULL)
return cur;
if ((cur = malloc(sizeof(*cur))) != NULL) {
if (**type == 'r') {
cur->fp = fdopen(pdes[0], *type);
#ifdef _REENTRANT
cur->fd = pdes[0];
#endif
} else {
cur->fp = fdopen(pdes[1], *type);
#ifdef _REENTRANT
cur->fd = pdes[1];
#endif
}
if (cur->fp != NULL)
return cur;
}
serrno = errno;
(void)close(pdes[0]);
(void)close(pdes[1]);
free(cur);
errno = serrno;
return NULL;
}
@@ -123,16 +137,6 @@ pdes_child(int *pdes, const char *type)
{
struct pid *old;
/* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
from previous popen() calls that remain open in the
parent process are closed in the new child process. */
for (old = pidlist; old; old = old->next)
#ifdef _REENTRANT
(void)close(old->fd); /* don't allow a flush */
#else
(void)close(fileno(old->fp)); /* don't allow a flush */
#endif
if (type[0] == 'r') {
(void)close(pdes[0]);
if (pdes[1] != STDOUT_FILENO) {
@@ -148,31 +152,30 @@ pdes_child(int *pdes, const char *type)
(void)close(pdes[0]);
}
}
/* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
from previous popen() calls that remain open in the
parent process are closed in the new child process. */
for (old = pidlist; old; old = old->next) {
#ifdef _REENTRANT
(void)close(old->fd); /* don't allow a flush */
#else
(void)close(fileno(old->fp)); /* don't allow a flush */
#endif
}
}
static void
pdes_parent(int *pdes, struct pid *cur, pid_t pid, const char *type)
{
FILE *iop;
/* Parent; assume fdopen can't fail. */
if (*type == 'r') {
iop = fdopen(pdes[0], type);
#ifdef _REENTRANT
cur->fd = pdes[0];
#endif
/* Parent */
if (*type == 'r')
(void)close(pdes[1]);
} else {
iop = fdopen(pdes[1], type);
#ifdef _REENTRANT
cur->fd = pdes[1];
#endif
else
(void)close(pdes[0]);
}
/* Link into list of file descriptors. */
cur->fp = iop;
cur->pid = pid;
cur->pid = pid;
cur->next = pidlist;
pidlist = cur;
}
@@ -198,7 +201,7 @@ popenve(const char *cmd, char *const *argv, char *const *envp, const char *type)
#ifdef _REENTRANT
(void)rwlock_rdlock(&pidlist_lock);
#endif
switch (pid = vfork()) {
switch (pid = fork()) {
case -1: /* Error. */
serrno = errno;
#ifdef _REENTRANT
+9 -3
View File
@@ -747,8 +747,8 @@ FORK_TEST(Capmode, NewThread) {
close(thread_pipe[1]);
}
static volatile sig_atomic_t had_signal = 0;
static void handle_signal(int) { had_signal = 1; }
static volatile sig_atomic_t signal_cnt = 0;
static void handle_signal(int) { signal_cnt++; }
FORK_TEST(Capmode, SelfKill) {
pid_t me = getpid();
@@ -766,7 +766,13 @@ FORK_TEST(Capmode, SelfKill) {
// Can only kill(2) to own pid.
EXPECT_CAPMODE(kill(child, SIGUSR1));
EXPECT_OK(kill(me, SIGUSR1));
EXPECT_EQ(1, had_signal);
EXPECT_EQ(1, signal_cnt);
union sigval sv;
sv.sival_int = 0x1234;
EXPECT_CAPMODE(sigqueue(child, SIGUSR1, sv));
EXPECT_OK(sigqueue(me, SIGUSR1, sv));
EXPECT_EQ(2, signal_cnt);
signal(SIGUSR1, original);
}
+13
View File
@@ -184,6 +184,19 @@ ldns_lookup_table ldns_error_str[] = {
{ LDNS_STATUS_INVALID_SVCPARAM_VALUE,
"Invalid wireformat of a value "
"in the ServiceParam rdata field of SVCB or HTTPS RR" },
{ LDNS_STATUS_NOT_EDE,
"The EDNS option is not an extended error code" },
{ LDNS_STATUS_EDE_OPTION_MALFORMED,
"The extended error code option is malformed, expected "
"at least 2 bytes of option data" },
{ LDNS_STATUS_EQUAL_RR,
"An identical RR already existed in the zone" },
{ LDNS_STATUS_ID_DID_NOT_MATCH,
"Response ID did not match the query ID" },
{ LDNS_STATUS_QDCOUNT_MUST_BE_ONE,
"The query section MUST contain exactly one question" },
{ LDNS_STATUS_QUERY_DID_NOT_MATCH,
"The question in the response did not match the query" },
{ 0, NULL }
};
+7 -1
View File
@@ -141,7 +141,13 @@ enum ldns_enum_status {
LDNS_STATUS_RESERVED_SVCPARAM_KEY,
LDNS_STATUS_NO_SVCPARAM_VALUE_EXPECTED,
LDNS_STATUS_SVCPARAM_KEY_MORE_THAN_ONCE,
LDNS_STATUS_INVALID_SVCPARAM_VALUE
LDNS_STATUS_INVALID_SVCPARAM_VALUE,
LDNS_STATUS_NOT_EDE,
LDNS_STATUS_EDE_OPTION_MALFORMED,
LDNS_STATUS_EQUAL_RR,
LDNS_STATUS_ID_DID_NOT_MATCH,
LDNS_STATUS_QDCOUNT_MUST_BE_ONE,
LDNS_STATUS_QUERY_DID_NOT_MATCH
};
typedef enum ldns_enum_status ldns_status;
+90 -2
View File
@@ -441,6 +441,50 @@ ldns_udp_bgsend2(ldns_buffer *qbin,
return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
}
/** helper sockaddr compare function. returns -1, 0 or 1. */
static int
ldns_sockaddr_cmp(const struct sockaddr_storage* addr1, socklen_t len1,
const struct sockaddr_storage* addr2, socklen_t len2)
{
struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
if(len1 < len2)
return -1;
if(len1 > len2)
return 1;
assert(len1 == len2);
if( p1_in->sin_family < p2_in->sin_family)
return -1;
if( p1_in->sin_family > p2_in->sin_family)
return 1;
assert( p1_in->sin_family == p2_in->sin_family );
/* compare ip4 */
if( p1_in->sin_family == AF_INET ) {
/* just order it, ntohs not required */
if(p1_in->sin_port < p2_in->sin_port)
return -1;
if(p1_in->sin_port > p2_in->sin_port)
return 1;
assert(p1_in->sin_port == p2_in->sin_port);
return memcmp(&p1_in->sin_addr, &p2_in->sin_addr,
sizeof(p1_in->sin_addr));
} else if (p1_in6->sin6_family == AF_INET6) {
/* just order it, ntohs not required */
if(p1_in6->sin6_port < p2_in6->sin6_port)
return -1;
if(p1_in6->sin6_port > p2_in6->sin6_port)
return 1;
assert(p1_in6->sin6_port == p2_in6->sin6_port);
return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
sizeof(p1_in6->sin6_addr));
} else {
/* eek unknown type, perform this comparison for sanity. */
return memcmp(addr1, addr2, len1);
}
}
static ldns_status
ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
const struct sockaddr_storage *to , socklen_t tolen,
@@ -449,6 +493,8 @@ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
{
int sockfd;
uint8_t *answer;
struct sockaddr_storage reply_addr;
socklen_t reply_addr_len;
sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
@@ -467,13 +513,21 @@ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
* but returns a 'NETWORK_ERROR' much like a timeout. */
ldns_sock_nonblock(sockfd);
answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
reply_addr_len = sizeof(reply_addr);
memset(&reply_addr, 0, reply_addr_len);
answer = ldns_udp_read_wire(sockfd, answer_size, &reply_addr,
&reply_addr_len);
close_socket(sockfd);
if (!answer) {
/* oops */
return LDNS_STATUS_NETWORK_ERR;
}
/* Check that the reply came from the to addr. */
if(ldns_sockaddr_cmp(to, tolen, &reply_addr, reply_addr_len) != 0) {
free(answer);
return LDNS_STATUS_NETWORK_ERR;
}
*result = answer;
return LDNS_STATUS_OK;
@@ -512,6 +566,10 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
assert(r != NULL);
/* The query should at least have one question */
if(ldns_buffer_limit(qb) < 6 || ldns_buffer_read_u16_at(qb, 4) != 1)
return LDNS_STATUS_QDCOUNT_MUST_BE_ONE;
status = LDNS_STATUS_OK;
rtt = ldns_resolver_rtt(r);
ns_array = ldns_resolver_nameservers(r);
@@ -599,6 +657,16 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
status = send_status;
}
if(reply_bytes && ldns_buffer_limit(qb) >= 2) {
uint16_t txid = ldns_buffer_read_u16_at(qb, 0);
if(reply_size < 2 ||
ldns_read_uint16(reply_bytes) != txid) {
status = LDNS_STATUS_ID_DID_NOT_MATCH;
LDNS_FREE(reply_bytes);
reply_bytes = NULL;
reply_size = 0;
}
}
/* obey the fail directive */
if (!reply_bytes) {
@@ -608,7 +676,7 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
LDNS_FREE(src);
}
LDNS_FREE(ns);
return LDNS_STATUS_ERR;
return status ? status : LDNS_STATUS_ERR;
} else {
LDNS_FREE(ns);
continue;
@@ -670,6 +738,26 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
#endif /* HAVE_SSL */
LDNS_FREE(reply_bytes);
if (reply) {
ldns_pkt *query = NULL;
if(ldns_pkt_qdcount(reply) != 1) {
status = LDNS_STATUS_QDCOUNT_MUST_BE_ONE;
ldns_pkt_free(reply);
reply = NULL;
} else if(ldns_wire2pkt(&query
, ldns_buffer_begin(qb)
, ldns_buffer_position(qb)) != LDNS_STATUS_OK
|| ldns_pkt_qdcount(query) != 1
|| ldns_rr_compare(ldns_rr_list_rr(ldns_pkt_question(query),0)
,ldns_rr_list_rr(ldns_pkt_question(reply),0))){
status = LDNS_STATUS_QUERY_DID_NOT_MATCH;
ldns_pkt_free(reply);
reply = NULL;
}
ldns_pkt_free(query);
}
if (result) {
*result = reply;
}
+1 -1
View File
@@ -15,7 +15,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
VERSION = 1.14.6s20250613
VERSION = 1.14.6s20250926
# === LIST OF FILES ====================================================
+10 -1
View File
@@ -1,6 +1,6 @@
************************************************************************
* Official mandoc TODO.
* $Id: TODO,v 1.337 2025/04/08 21:53:14 schwarze Exp $
* $Id: TODO,v 1.338 2025/07/22 13:36:54 schwarze Exp $
************************************************************************
Many issues are annotated for difficulty as follows:
@@ -505,6 +505,15 @@ are mere guesses, and some may be wrong.
re-reported by tb@ Mon, 16 Mar 2015 16:47:21 +0100
loc ** exist ** algo ** size * imp **
- Check for bad line breaks caused by PostScript and PDF using variable-
width fonts, for example in .Bl -width "string". The difficulty line
below describes a naive solution by simply scaling up widths internally
or adding default spacing (like in terminal output). If fixes are
needed in width measurements, it might be a bit harder, but likely
not unreasonably so.
reported by Jan Stary 20 May 2024 10:19:01 +0200
loc * exist * algo ** size * imp **
--- HTML issues --------------------------------------------------------
- support the idiom .TP .IP .TP for multi-paragraph list item bodies
+216 -28
View File
@@ -1,6 +1,6 @@
.\" $Id: catman.8,v 1.8 2017/03/18 19:56:01 schwarze Exp $
.\" $Id: catman.8,v 1.15 2025/07/13 14:15:26 schwarze Exp $
.\"
.\" Copyright (c) 2017 Ingo Schwarze <[email protected]>
.\" Copyright (c) 2017, 2025 Ingo Schwarze <[email protected]>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: March 18 2017 $
.Dd $Mdocdate: July 13 2025 $
.Dt CATMAN 8
.Os
.Sh NAME
@@ -37,9 +37,9 @@ and
format and formats all of them, storing the formatted versions in
the same relative paths below
.Ar dstdir .
Subdirectories of
Unless they already exist,
.Ar dstdir
are created as needed.
itself and any required subdirectories are created.
Existing files are not explicitly deleted, but possibly overwritten.
.Pp
The options are as follows:
@@ -71,6 +71,18 @@ output mode, the
.Cm fragment
output option is implied.
Other output options are not supported.
.It Fl v
Verbose mode, printing additional information to standard error output.
Specifying this once prints a summary about the number of files
and directories processed at the end of the iteration.
Specifying it twice additionally prints debugging information
about the backchannel from
.Xr mandocd 8
to
.Nm
that is used to limit the number of files in flight at any given time.
For details, see
.Sx DIAGNOSTICS .
.El
.Sh IMPLEMENTATION NOTES
Since this version avoids
@@ -87,33 +99,209 @@ implementations.
.Sh EXIT STATUS
.Ex -std
.Pp
Possible errors include:
.Bl -bullet
.It
missing, invalid, or excessive command line arguments
.It
failure to change the current working directory to
.Ar srcdir
.It
failure to open
.Ar dstdir
.It
communication failure with
.Xr mandocd 8
.It
resource exhaustion, for example file descriptor, process table,
or memory exhaustion
.El
.Pp
Except for memory exhaustion and similar system-level failures,
failures while trying to open, read, parse, or format individual
manual pages, to save individual formatted files to the file system,
or even to create directories do not cause
Failures while trying to open individual manual pages for reading,
to save individual formatted files to the file system,
or even to read or create subdirectories do not cause
.Nm
to return an error exit status.
In such cases,
.Nm
will simply continue with the next file or subdirectory.
simply continues with the next file or subdirectory.
.Sh DIAGNOSTICS
Some fatal errors cause
.Nm
to exit before the iteration over input files is even started:
.Bl -tag -width Ds -offset indent
.It unknown option \-\- Ar option
An invalid option was passed on the command line.
.It missing arguments: srcdir and dstdir
No argument was provided.
Both
.Ar srcdir
and
.Ar dstdir
are mandatory.
.It missing argument: dstdir
Only one argument was provided.
The second argument,
.Ar dstdir ,
is mandatory, too.
.It too many arguments: Ar third argument
Three or more arguments were provided, but only two are supported.
.It Sy socketpair : Ar reason
The sockets needed for communication with
.Xr mandocd 8
could not be created, for example due to file descriptor or memory exhaustion.
.It Sy fork : Ar reason
The new process needed to run
.Xr mandocd 8
could not be created, for example due to process table exhaustion
or system resource limits.
.It Sy exec Ns Po Sy mandocd Pc : Ar reason
The
.Xr mandocd 8
child program could not be started, for example because it is not in the
.Ev PATH
or has no execute permission.
.It Sy mkdir No destination Ar dstdir : reason
The
.Ar dstdir
does not exist and could not be created, for example because
the parent directory does not exist or permission is denied.
.It Sy open No destination Ar dstdir : reason
The
.Ar dstdir
could not be opened for reading, for example because
it is not a directory or permission is denied.
.It Sy chdir No to source Ar srcdir : reason
The current working directory could not be changed to
.Ar srcdir ,
for example because it does not exist, it is not a directory,
or permission is denied.
.It Sy fts_open : Ar reason
Starting the iteration was attempted but failed,
for example due to memory exhaustion.
.El
.Pp
Some fatal errors cause the iteration over input files to be aborted
prematurely:
.Bl -tag -width Ds -offset indent
.It FATAL: Sy fts_read : Ar reason
A call to
.Xr fts_read 3
returned
.Dv NULL ,
meaning that the iteration failed before being complete.
.It FATAL: mandocd child died: got Ar SIGNAME
This message appears if
.Nm
gets the
.Dv SIGCHLD
or
.Dv SIGPIPE
signal, most likely due to a fatal bug in
.Xr mandocd 8 .
.It FATAL: Sy sendmsg : Ar reason
The file descriptors needed to process one of the manual pages
could not be sent to
.Xr mandocd 8 ,
for example because
.Xr mandocd 8
could not be started or died unexpectedly.
.It FATAL: Sy recv : Ar reason
Trying to read a reply message from
.Xr mandocd 8
failed, most likely because
.Xr mandocd 8
unexpectedly died or closed the socket.
.It FATAL: signal Ar SIGNAME
This message appears if
.Nm
gets a
.Dv SIGHUP ,
.Dv SIGINT ,
or
.Dv SIGTERM
signal, for example because the user deliberately killed it.
.El
.Pp
Some non-fatal errors cause a single subdirectory to be skipped.
The iteration is not aborted but continues with the next subdirectory,
and the exit status is unaffected:
.Bl -tag -width Ds -offset indent
.It directory Ar subdirectory No unreadable : Ar reason
A directory below
.Ar srcdir
could not be read and is skipped.
.It directory Ar subdirectory No causes cycle
A directory below
.Ar srcdir
is skipped because it would cause cyclic processing.
.It Sy mkdirat Ar subdirectory : reason
A required directory below
.Ar dstdir
does not exist and could not be created.
The corresponding subdirectory below
.Ar srcdir
is skipped.
.El
.Pp
Some non-fatal errors cause a single source file to be skipped.
The iteration is not aborted but continues with the next file,
and the exit status is unaffected:
.Bl -tag -width Ds -offset indent
.It file Ar filename : reason
The function
.Xr fts_read 3
reported a non-fatal error with respect to
.Ar filename .
.It file Ar filename : No not a regular file
For example, it might be a symbolic link or a device file.
.It Sy open Ar filename No for reading : Ar reason
A file below
.Ar srcdir
could not be read, for example due to permission problems.
.It Sy openat Ar filename No for writing : Ar reason
A file below
.Ar dstdir
could not be created or truncated, for example due to permission problems.
.El
.Pp
If errors occur, the applicable summary messages appear
after the end of the iteration:
.Pp
.Bl -tag -width Ds -offset indent -compact
.It skipped Ar number No directories due to errors
.It skipped Ar number No files due to errors
.It processing aborted due to fatal error
.El
.Pp
If the
.Fl v
flag is specified, the following summary message also appears:
.Bl -tag -width Ds -offset indent
.It processed Ar nfiles No files in Ar ndirs No directories
A file is counted if it could be opened for reading and the
corresponding output file could be opened for writing;
this does not necessarily mean that it is a useful manual page.
A directory is counted if it could be opened for reading and the
corresponding output directory existed or could be created;
this does not necessarily mean that any files could be
processed inside.
.El
.Pp
If the
.Fl v
flag is specified twice, the following messages also appear:
.Bl -tag -width Ds -offset indent
.It allowing up to Ar number No files in flight
This is printed at the beginning of the iteration,
showing the maximum number of files that
.Nm
allows to be in flight at any given time.
.It files in flight: Ar old No \- Ar decrement No = Ar new
This message is printed when
.Nm
learns about
.Xr mandocd 8
accepting more than one file at the same time.
The three numbers printed are the old number of files in flight,
the amount this number is being reduced, and the resulting
new number of files in flight.
.It waiting for Ar number No files in flight
This message is printed at the end of the iteration, after
.Nm
has submitted all files to
.Xr mandocd 8
that it intends to.
THe message informs about the number of files still in flight
at this point.
The
.Nm
program then waits until
.Xr mandocd 8
has accepted them all or until an error occurs.
.El
.Sh SEE ALSO
.Xr mandoc 1 ,
.Xr mandocd 8
+205 -26
View File
@@ -1,7 +1,7 @@
/* $Id: catman.c,v 1.23 2021/10/15 15:04:02 schwarze Exp $ */
/* $Id: catman.c,v 1.30 2025/07/13 14:15:26 schwarze Exp $ */
/*
* Copyright (c) 2017, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -25,6 +25,7 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <assert.h>
#if HAVE_ERR
#include <err.h>
#endif
@@ -35,26 +36,44 @@
#else
#include "compat_fts.h"
#endif
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
int verbose_flag = 0;
sig_atomic_t got_signal = 0;
int process_manpage(int, int, const char *);
int process_tree(int, int);
void run_mandocd(int, const char *, const char *)
__attribute__((__noreturn__));
void signal_handler(int);
ssize_t sock_fd_write(int, int, int, int);
void usage(void) __attribute__((__noreturn__));
void
signal_handler(int signum)
{
got_signal = signum;
}
void
run_mandocd(int sockfd, const char *outtype, const char* defos)
{
char sockfdstr[10];
int len;
if (snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd) == -1)
len = snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd);
if (len >= (int)sizeof(sockfdstr)) {
errno = EOVERFLOW;
len = -1;
}
if (len < 0)
err(1, "snprintf");
if (defos == NULL)
execlp("mandocd", "mandocd", "-T", outtype,
@@ -109,10 +128,11 @@ sock_fd_write(int fd, int fd0, int fd1, int fd2)
* to neither cause more than a handful of retries
* in normal operation nor unnecessary delays.
*/
for (;;) {
if ((sz = sendmsg(fd, &msg, 0)) != -1 ||
errno != EAGAIN)
while ((sz = sendmsg(fd, &msg, 0)) == -1) {
if (errno != EAGAIN) {
warn("FATAL: sendmsg");
break;
}
nanosleep(&timeout, NULL);
}
return sz;
@@ -125,14 +145,16 @@ process_manpage(int srv_fd, int dstdir_fd, const char *path)
int irc;
if ((in_fd = open(path, O_RDONLY)) == -1) {
warn("open(%s)", path);
warn("open %s for reading", path);
fflush(stderr);
return 0;
}
if ((out_fd = openat(dstdir_fd, path,
O_WRONLY | O_NOFOLLOW | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
warn("openat(%s)", path);
warn("openat %s for writing", path);
fflush(stderr);
close(in_fd);
return 0;
}
@@ -142,20 +164,22 @@ process_manpage(int srv_fd, int dstdir_fd, const char *path)
close(in_fd);
close(out_fd);
if (irc < 0) {
warn("sendmsg");
return -1;
}
return 0;
return irc;
}
int
process_tree(int srv_fd, int dstdir_fd)
{
const struct timespec timeout = { 0, 10000000 }; /* 0.01 s */
const int max_inflight = 16;
FTS *ftsp;
FTSENT *entry;
const char *argv[2];
const char *path;
int inflight, irc, decr, fatal;
int gooddirs, baddirs, goodfiles, badfiles;
char dummy[1];
argv[0] = ".";
argv[1] = (char *)NULL;
@@ -166,13 +190,59 @@ process_tree(int srv_fd, int dstdir_fd)
return -1;
}
while ((entry = fts_read(ftsp)) != NULL) {
if (verbose_flag >= 2) {
warnx("allowing up to %d files in flight", max_inflight);
fflush(stderr);
}
inflight = fatal = gooddirs = baddirs = goodfiles = badfiles = 0;
while (fatal == 0 && got_signal == 0 &&
(entry = fts_read(ftsp)) != NULL) {
if (inflight >= max_inflight) {
while (recv(srv_fd, dummy, sizeof(dummy), 0) == -1) {
if (errno != EAGAIN) {
warn("FATAL: recv");
fatal = errno;
break;
}
nanosleep(&timeout, NULL);
}
if (fatal != 0)
break;
decr = 1;
while ((irc = recv(srv_fd, dummy, sizeof(dummy),
MSG_DONTWAIT)) > 0)
decr++;
assert(inflight >= decr);
if (verbose_flag >= 2 && decr > 1) {
warnx("files in flight: %d - %d = %d",
inflight, decr, inflight - decr);
fflush(stderr);
}
inflight -= decr;
if (irc == 0) {
errno = ECONNRESET;
inflight = -1;
}
if (errno != EAGAIN) {
warn("FATAL: recv");
fatal = errno;
break;
}
}
path = entry->fts_path + 2;
switch (entry->fts_info) {
case FTS_F:
if (process_manpage(srv_fd, dstdir_fd, path) == -1) {
fts_close(ftsp);
return -1;
switch (process_manpage(srv_fd, dstdir_fd, path)) {
case -1:
fatal = errno;
break;
case 0:
badfiles++;
break;
default:
goodfiles++;
inflight++;
break;
}
break;
case FTS_D:
@@ -180,25 +250,96 @@ process_tree(int srv_fd, int dstdir_fd)
mkdirat(dstdir_fd, path, S_IRWXU | S_IRGRP |
S_IXGRP | S_IROTH | S_IXOTH) == -1 &&
errno != EEXIST) {
warn("mkdirat(%s)", path);
warn("mkdirat %s", path);
fflush(stderr);
(void)fts_set(ftsp, entry, FTS_SKIP);
}
baddirs++;
} else
gooddirs++;
break;
case FTS_DP:
break;
case FTS_DNR:
warnx("directory %s unreadable: %s",
path, strerror(entry->fts_errno));
fflush(stderr);
baddirs++;
break;
case FTS_DC:
warnx("directory %s causes cycle", path);
fflush(stderr);
baddirs++;
break;
case FTS_ERR:
case FTS_NS:
warnx("file %s: %s",
path, strerror(entry->fts_errno));
fflush(stderr);
badfiles++;
break;
default:
warnx("%s: not a regular file", path);
warnx("file %s: not a regular file", path);
fflush(stderr);
badfiles++;
break;
}
}
if (got_signal != 0) {
switch (got_signal) {
case SIGCHLD:
warnx("FATAL: mandocd child died: got SIGCHLD");
break;
case SIGPIPE:
warnx("FATAL: mandocd child died: got SIGPIPE");
break;
default:
warnx("FATAL: signal SIG%s", sys_signame[got_signal]);
break;
}
inflight = -1;
fatal = 1;
} else if (fatal == 0 && (fatal = errno) != 0)
warn("FATAL: fts_read");
fts_close(ftsp);
return 0;
if (verbose_flag >= 2 && inflight > 0) {
warnx("waiting for %d files in flight", inflight);
fflush(stderr);
}
while (inflight > 0) {
irc = recv(srv_fd, dummy, sizeof(dummy), 0);
if (irc > 0)
inflight--;
else if (irc == -1 && errno == EAGAIN)
nanosleep(&timeout, NULL);
else {
if (irc == 0)
errno = ECONNRESET;
warn("recv");
inflight = -1;
}
}
if (verbose_flag)
warnx("processed %d files in %d directories",
goodfiles, gooddirs);
if (baddirs > 0)
warnx("skipped %d %s due to errors", baddirs,
baddirs == 1 ? "directory" : "directories");
if (badfiles > 0)
warnx("skipped %d %s due to errors", badfiles,
badfiles == 1 ? "file" : "files");
if (fatal != 0) {
warnx("processing aborted due to fatal error, "
"results are probably incomplete");
inflight = -1;
}
return inflight;
}
int
main(int argc, char **argv)
{
struct sigaction sa;
const char *defos, *outtype;
int srv_fds[2];
int dstdir_fd;
@@ -207,7 +348,7 @@ main(int argc, char **argv)
defos = NULL;
outtype = "ascii";
while ((opt = getopt(argc, argv, "I:T:")) != -1) {
while ((opt = getopt(argc, argv, "I:T:v")) != -1) {
switch (opt) {
case 'I':
defos = optarg;
@@ -215,6 +356,9 @@ main(int argc, char **argv)
case 'T':
outtype = optarg;
break;
case 'v':
verbose_flag += 1;
break;
default:
usage();
}
@@ -224,8 +368,36 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
}
if (argc != 2)
if (argc != 2) {
switch (argc) {
case 0:
warnx("missing arguments: srcdir and dstdir");
break;
case 1:
warnx("missing argument: dstdir");
break;
default:
warnx("too many arguments: %s", argv[2]);
break;
}
usage();
}
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &signal_handler;
sa.sa_flags = SA_NOCLDWAIT;
if (sigfillset(&sa.sa_mask) == -1)
err(1, "sigfillset");
if (sigaction(SIGHUP, &sa, NULL) == -1)
err(1, "sigaction(SIGHUP)");
if (sigaction(SIGINT, &sa, NULL) == -1)
err(1, "sigaction(SIGINT)");
if (sigaction(SIGPIPE, &sa, NULL) == -1)
err(1, "sigaction(SIGPIPE)");
if (sigaction(SIGTERM, &sa, NULL) == -1)
err(1, "sigaction(SIGTERM)");
if (sigaction(SIGCHLD, &sa, NULL) == -1)
err(1, "sigaction(SIGCHLD)");
if (socketpair(AF_LOCAL, SOCK_STREAM, AF_UNSPEC, srv_fds) == -1)
err(1, "socketpair");
@@ -242,11 +414,18 @@ main(int argc, char **argv)
}
close(srv_fds[1]);
if ((dstdir_fd = open(argv[1], O_RDONLY | O_DIRECTORY)) == -1)
err(1, "open(%s)", argv[1]);
if ((dstdir_fd = open(argv[1], O_RDONLY | O_DIRECTORY)) == -1) {
if (errno != ENOENT)
err(1, "open destination %s", argv[1]);
if (mkdir(argv[1], S_IRWXU |
S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
err(1, "mkdir destination %s", argv[1]);
if ((dstdir_fd = open(argv[1], O_RDONLY | O_DIRECTORY)) == -1)
err(1, "open destination %s", argv[1]);
}
if (chdir(argv[0]) == -1)
err(1, "chdir(%s)", argv[0]);
err(1, "chdir to source %s", argv[0]);
return process_tree(srv_fds[0], dstdir_fd) == -1 ? 1 : 0;
}
+4 -3
View File
@@ -1,6 +1,6 @@
/* $Id: dba.c,v 1.10 2017/02/17 14:43:54 schwarze Exp $ */
/* $Id: dba.c,v 1.11 2025/09/24 13:13:30 schwarze Exp $ */
/*
* Copyright (c) 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2016, 2017, 2025 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -318,7 +318,8 @@ compare_names(const void *vp1, const void *vp2)
cp1 = *(const char * const *)vp1;
cp2 = *(const char * const *)vp2;
return (diff = *cp2 - *cp1) ? diff :
strcasecmp(cp1 + 1, cp2 + 1);
(diff = strcasecmp(cp1 + 1, cp2 + 1)) ? diff :
strcmp(cp1 + 1, cp2 + 1);
}
static int
+2 -2
View File
@@ -45,8 +45,8 @@ while [ -n "$1" ]; do
file=$1
shift
echo " ========== $file ========== "
$ROFF -mandoc $file | $COLPIPE 2> /tmp/roff.err > /tmp/roff.out
${MANDOC:=mandoc} $MOPT $file | $COLPIPE \
($ROFF -mandoc $file | $COLPIPE) 2> /tmp/roff.err > /tmp/roff.out
(${MANDOC:=mandoc} $MOPT $file | $COLPIPE) \
2> /tmp/mandoc.err > /tmp/mandoc.out
for i in roff mandoc; do
[ -s /tmp/$i.err ] && echo "$i errors:" && cat /tmp/$i.err
+10 -42
View File
@@ -1,6 +1,6 @@
/* $Id: main.c,v 1.361 2022/04/14 16:43:43 schwarze Exp $ */
/* $Id: main.c,v 1.364 2025/09/24 21:30:20 schwarze Exp $ */
/*
* Copyright (c) 2010-2012, 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010-2012,2014-2021,2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
*
@@ -109,7 +109,7 @@ static void parse(struct mparse *, int, const char *,
struct outstate *, struct manconf *);
static void passthrough(int, int);
static void process_onefile(struct mparse *, struct manpage *,
int, struct outstate *, struct manconf *);
struct outstate *, struct manconf *);
static void run_pager(struct outstate *, char *);
static pid_t spawn_pager(struct outstate *, char *);
static void usage(enum argmode) __attribute__((__noreturn__));
@@ -144,7 +144,6 @@ main(int argc, char *argv[])
int options; /* Parser options. */
int show_usage; /* Invalid argument: give up. */
int prio, best_prio;
int startdir;
int c;
enum mandoc_os os_e; /* Check base system conventions. */
enum outmode outmode; /* According to command line. */
@@ -514,7 +513,7 @@ main(int argc, char *argv[])
if (resnsz == 0)
(void)fs_search(&search, &conf.manpath,
*argv, &resn, &resnsz);
if (resnsz == 0 && strchr(*argv, '/') == NULL) {
if (resnsz == 0) {
if (search.arch != NULL &&
arch_valid(search.arch, OSENUM) == 0)
warnx("Unknown architecture \"%s\".",
@@ -529,20 +528,6 @@ main(int argc, char *argv[])
mandoc_msg_setrc(MANDOCLEVEL_BADARG);
continue;
}
if (resnsz == 0) {
if (access(*argv, R_OK) == -1) {
mandoc_msg_setinfilename(*argv);
mandoc_msg(MANDOCERR_BADARG_BAD,
0, 0, "%s", strerror(errno));
mandoc_msg_setinfilename(NULL);
continue;
}
resnsz = 1;
resn = mandoc_calloc(resnsz, sizeof(*res));
resn->file = mandoc_strdup(*argv);
resn->ipath = SIZE_MAX;
resn->form = FORM_SRC;
}
if (outmode != OUTMODE_ONE || resnsz == 1) {
res = mandoc_reallocarray(res,
ressz + resnsz, sizeof(*res));
@@ -559,7 +544,8 @@ main(int argc, char *argv[])
best_prio = 40;
for (ib = i = 0; i < resnsz; i++) {
sec = resn[i].file;
sec = resn[i].file +
strlen(conf.manpath.paths[resn[i].ipath]);
sec += strcspn(sec, "123456789");
if (sec[0] == '\0')
continue; /* No section at all. */
@@ -647,23 +633,13 @@ main(int argc, char *argv[])
mchars_alloc();
mp = mparse_alloc(options, os_e, os_s);
/*
* Remember the original working directory, if possible.
* This will be needed if some names on the command line
* are page names and some are relative file names.
* Do not error out if the current directory is not
* readable: Maybe it won't be needed after all.
*/
startdir = open(".", O_RDONLY | O_DIRECTORY);
for (i = 0; i < ressz; i++) {
process_onefile(mp, res + i, startdir, &outst, &conf);
if (i > 0)
mparse_reset(mp);
process_onefile(mp, res + i, &outst, &conf);
if (outst.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK)
break;
}
if (startdir != -1) {
(void)fchdir(startdir);
close(startdir);
}
if (conf.output.tag != NULL && conf.output.tag_found == 0) {
mandoc_msg(MANDOCERR_TAG, 0, 0, "%s", conf.output.tag);
conf.output.tag = NULL;
@@ -909,7 +885,7 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
}
static void
process_onefile(struct mparse *mp, struct manpage *resp, int startdir,
process_onefile(struct mparse *mp, struct manpage *resp,
struct outstate *outst, struct manconf *conf)
{
int fd;
@@ -921,8 +897,6 @@ process_onefile(struct mparse *mp, struct manpage *resp, int startdir,
*/
if (resp->ipath != SIZE_MAX)
(void)chdir(conf->manpath.paths[resp->ipath]);
else if (startdir != -1)
(void)fchdir(startdir);
mandoc_msg_setinfilename(resp->file);
if (resp->file != NULL) {
@@ -982,18 +956,12 @@ parse(struct mparse *mp, int fd, const char *file,
struct outstate *outst, struct manconf *conf)
{
static struct manpaths basepaths;
static int previous;
struct roff_meta *meta;
assert(fd >= 0);
if (file == NULL)
file = "<stdin>";
if (previous)
mparse_reset(mp);
else
previous = 1;
mparse_readfd(mp, fd, file);
if (fd != STDIN_FILENO)
close(fd);
+89 -62
View File
@@ -1,7 +1,8 @@
.\" $Id: man.7,v 1.150 2023/10/23 22:57:54 schwarze Exp $
.\" $Id: man.7,v 1.154 2025/08/05 21:16:20 schwarze Exp $
.\"
.\" Copyright (c) 2011-2015, 2017-2020, 2023, 2025
.\" Ingo Schwarze <[email protected]>
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <[email protected]>
.\" Copyright (c) 2011-2015,2017-2020,2023 Ingo Schwarze <[email protected]>
.\" Copyright (c) 2017 Anthony Bentley <[email protected]>
.\" Copyright (c) 2010 Joerg Sonnenberger <[email protected]>
.\"
@@ -17,7 +18,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: October 23 2023 $
.Dd $Mdocdate: August 5 2025 $
.Dt MAN 7
.Os
.Sh NAME
@@ -89,7 +90,7 @@ but can be found in the alphabetical reference below.
.Ss Page header and footer meta-data
.Bl -column "RS, RE" description
.It Ic TH Ta set the title: Ar name section date Op Ar source Op Ar volume
.It Ic AT Ta display AT&T UNIX version in the page footer (<= 1 argument)
.It Ic AT Ta display AT&T UNIX version in the page footer (<= 2 arguments)
.It Ic UC Ta display BSD version in the page footer (<= 1 argument)
.El
.Ss Sections and paragraphs
@@ -99,6 +100,7 @@ but can be found in the alphabetical reference below.
.It Ic PP Ta start an undecorated paragraph (no arguments)
.It Ic IP Ta indented paragraph: Op Ar head Op Ar width
.It Ic TP Ta tagged paragraph: Op Ar width
.It Ic HP Ta hanged paragraph: Op Ar width
.It Ic PD Ta set vertical paragraph distance: Op Ar height
.It Ic EX , EE Ta display an example (no arguments)
.It Ic RS , RE Ta reset the left margin: Op Ar width
@@ -198,11 +200,6 @@ argument is a
scaling width.
If specified, it's saved for later paragraph left margins;
if unspecified, the saved or default width is used.
.Pp
This macro is portable, but deprecated
because it has no good representation in HTML output,
usually ending up indistinguishable from
.Ic PP .
.It Ic I
Text is rendered in italics.
.It Ic IB
@@ -239,6 +236,17 @@ A synonym for
End a mailto block started with
.Ic MT .
This is a GNU extension.
.It Ic MR
Reference another manual page.
This is a Plan 9 extension also supported by GNU.
It has the following syntax:
.Pp
.D1 Pf . Ic MR Ar name section Op Ar suffix
.Pp
The optional, single
.Ar suffix
argument is appended without preceding whitespace
and typically used for trailing punctuation.
.It Ic MT
Begin a mailto block.
This is a GNU extension.
@@ -250,8 +258,12 @@ link description to be shown
.Ed
.It Ic OP
Optional command-line argument.
This is a rarely used DWB extension.
It has the following syntax:
This is a deprecated GNU extension.
The name and purpose of the macro match an earlier DWB extension,
but both the syntax and semantics are incompatible.
In GNU and
.Xr mandoc 1 ,
it has the following syntax:
.Pp
.D1 Pf . Ic OP Ar key Op Ar value
.Pp
@@ -503,43 +515,56 @@ raised.
.Pp
The syntax is as follows:
.Bd -literal -offset indent
\&.YO \(lBbody...\(rB
\(lBbody...\(rB
\&.\e" current-line syntax
\&.YO \(lBbody ...\(rB
\&.\e" next-line syntax
\&.YO
body ...
.Ed
.Bl -column "MacroX" "ArgumentsX" "ScopeXXXXX" "CompatX" -offset indent
.It Em Macro Ta Em Arguments Ta Em Scope Ta Em Notes
.It Ic AT Ta <=1 Ta current Ta \&
.It Ic B Ta n Ta next-line Ta \&
.It Ic BI Ta n Ta current Ta \&
.It Ic BR Ta n Ta current Ta \&
.It Ic DT Ta 0 Ta current Ta \&
.It Ic EE Ta 0 Ta current Ta Version 9 At
.It Ic EX Ta 0 Ta current Ta Version 9 At
.It Ic I Ta n Ta next-line Ta \&
.It Ic IB Ta n Ta current Ta \&
.It Ic IR Ta n Ta current Ta \&
.It Ic OP Ta >=1 Ta current Ta DWB
.It Ic PD Ta 1 Ta current Ta \&
.It Ic RB Ta n Ta current Ta \&
.It Ic RI Ta n Ta current Ta \&
.It Ic SB Ta n Ta next-line Ta \&
.It Ic SM Ta n Ta next-line Ta \&
.It Ic TH Ta >1, <6 Ta current Ta \&
.It Ic UC Ta <=1 Ta current Ta \&
.It Ic in Ta 1 Ta current Ta Xr roff 7
.Bl -column -offset indent\
"Macro" "Arguments" "curr and next" "Version 9 AT&T UNIX"
.It Em Macro Ta Em Arguments Ta Em Line Scope Ta Em Notes
.It Ic AT Ta 0 to 2 Ta current Ta \&
.It Ic B Ta 1 or more Ta curr or next Ta \&
.It Ic BI Ta 2 or more Ta current Ta \&
.It Ic BR Ta 2 or more Ta current Ta \&
.It Ic DT Ta 0 Ta none Ta \&
.It Ic EE Ta 0 Ta none Ta Version 9 At
.It Ic EX Ta 0 Ta none Ta Version 9 At
.It Ic I Ta 1 or more Ta curr or next Ta \&
.It Ic IB Ta 2 or more Ta current Ta \&
.It Ic IR Ta 2 or more Ta current Ta \&
.It Ic MR Ta 2 or 3 Ta current Ta Plan 9
.It Ic OP Ta 1 or 2 Ta current Ta GNU
.It Ic PD Ta 0 or 1 Ta current Ta \&
.It Ic RB Ta 2 or more Ta current Ta \&
.It Ic RI Ta 2 or more Ta current Ta \&
.It Ic SB Ta 1 or more Ta curr or next Ta \&
.It Ic SM Ta 1 or more Ta curr or next Ta \&
.It Ic TH Ta 3 to 5 Ta current Ta \&
.It Ic UC Ta 0 or 1 Ta current Ta \&
.It Ic in Ta 0 or 1 Ta current Ta Xr roff 7
.El
.Ss Block Macros
Block macros comprise a head and body.
As with in-line macros, the head is scoped to the current line and, in
one circumstance, the next line (the next-line stipulations as in
As with in-line macros, the head is scoped to the current line or,
for some macros, to the next line (the next-line stipulations as in
.Sx Line Macros
apply here as well).
.Pp
The syntax is as follows:
.Bd -literal -offset indent
\&.YO \(lBhead...\(rB
\(lBhead...\(rB
\(lBbody...\(rB
\&.\e" current-line syntax
\&.YO \(lBhead ...\(rB
body ...
\&...
\&.\e" next-line syntax
\&.YO \(lBhead\(rB
head ...
body ...
\&...
.Ed
.Pp
The closure of body scope may be to the section, where a macro is closed
@@ -547,40 +572,42 @@ by
.Ic SH ;
sub-section, closed by a section or
.Ic SS ;
or paragraph, closed by a section, sub-section,
paragraph, closed by a section, sub-section,
.Ic HP ,
.Ic IP ,
.Ic LP ,
.Ic P ,
.Ic PP ,
.Ic RE ,
.Ic RS ,
.Ic SY ,
.Ic TP ,
or
.Ic TP .
No closure refers to an explicit block closing macro.
.Ic TQ ;
or to an explicit block closing macro.
.Pp
As a rule, block macros may not be nested; thus, calling a block macro
while another block macro scope is open, and the open scope is not
implicitly closed, is syntactically incorrect.
.Bl -column "MacroX" "ArgumentsX" "Head ScopeX" "sub-sectionX" "compatX" -offset indent
.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope Ta Em Notes
.It Ic HP Ta <2 Ta current Ta paragraph Ta \&
.It Ic IP Ta <3 Ta current Ta paragraph Ta \&
.It Ic LP Ta 0 Ta current Ta paragraph Ta \&
.It Ic ME Ta 0 Ta none Ta none Ta GNU
.It Ic MT Ta 1 Ta current Ta to \&ME Ta GNU
.It Ic P Ta 0 Ta current Ta paragraph Ta \&
.It Ic PP Ta 0 Ta current Ta paragraph Ta \&
.It Ic RE Ta <=1 Ta current Ta none Ta \&
.It Ic RS Ta 1 Ta current Ta to \&RE Ta \&
.It Ic SH Ta >0 Ta next-line Ta section Ta \&
.It Ic SS Ta >0 Ta next-line Ta sub-section Ta \&
.It Ic SY Ta 1 Ta current Ta to \&YS Ta GNU
.It Ic TP Ta n Ta next-line Ta paragraph Ta \&
.It Ic TQ Ta n Ta next-line Ta paragraph Ta GNU
.It Ic UE Ta 0 Ta current Ta none Ta GNU
.It Ic UR Ta 1 Ta current Ta part Ta GNU
.It Ic YS Ta 0 Ta none Ta none Ta GNU
.Bl -column -offset indent\
"Macro" "Arguments" "curr and next" "sub-section" "Notes"
.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope Ta Em Notes
.It Ic HP Ta 0 or 1 Ta current Ta paragraph Ta \&
.It Ic IP Ta 0 to 2 Ta current Ta paragraph Ta \&
.It Ic LP Ta 0 Ta none Ta paragraph Ta \&
.It Ic ME Ta 0 or 1 Ta current Ta none Ta GNU
.It Ic MT Ta 1 Ta current Ta to \&ME Ta GNU
.It Ic P Ta 0 Ta none Ta paragraph Ta \&
.It Ic PP Ta 0 Ta none Ta paragraph Ta \&
.It Ic RE Ta 0 or 1 Ta current Ta none Ta \&
.It Ic RS Ta 0 or 1 Ta current Ta to \&RE Ta \&
.It Ic SH Ta 1 or more Ta curr or next Ta section Ta \&
.It Ic SS Ta 1 or more Ta curr or next Ta sub-section Ta \&
.It Ic SY Ta 1 Ta current Ta to \&YS Ta GNU
.It Ic TP Ta 0 or 1 Ta curr and next Ta paragraph Ta \&
.It Ic TQ Ta 0 or 1 Ta curr and next Ta paragraph Ta GNU
.It Ic UE Ta 0 or 1 Ta current Ta none Ta GNU
.It Ic UR Ta 1 Ta current Ta to \&UE Ta GNU
.It Ic YS Ta 0 Ta none Ta none Ta GNU
.El
.Pp
If a block macro is next-line scoped, it may only be followed by in-line
+2 -1
View File
@@ -1,4 +1,4 @@
/* $Id: man.c,v 1.189 2022/08/16 23:01:09 schwarze Exp $ */
/* $Id: man.c,v 1.190 2025/08/22 13:17:06 schwarze Exp $ */
/*
* Copyright (c) 2013-2015,2017-2019,2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -134,6 +134,7 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
*ep = '\0';
return 1;
}
mandoc_msg(MANDOCERR_FI_BLANK, line, i, NULL);
roff_elem_alloc(man, line, offs, ROFF_sp);
man->next = ROFF_NEXT_SIBLING;
return 1;
+34 -6
View File
@@ -1,6 +1,6 @@
.\" $Id: man.options.1,v 1.7 2017/07/04 23:40:01 schwarze Exp $
.\" $Id: man.options.1,v 1.9 2025/08/28 13:46:57 schwarze Exp $
.\"
.\" Copyright (c) 2017 Ingo Schwarze <[email protected]>
.\" Copyright (c) 2017, 2025 Ingo Schwarze <[email protected]>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: July 4 2017 $
.Dd $Mdocdate: August 28 2025 $
.Dt MAN.OPTIONS 1
.Os
.Sh NAME
@@ -39,9 +39,18 @@
.de At5
.At V Pq January 1983 \\$1
..
.de At8
.No Version 8 At Pq February 1985 \\$1
..
.de Bx43
.Bx 4.3 Pq June 1986 \\$1
..
.de At9
.No Version 9 At Pq September 1986 \\$1
..
.de At10
.No Version 10 At Pq October 1989 \\$1
..
.\" option was present in groff-1.01 as contained in 4.3BSD-Net/2
.\" and no mention of it could be found in the ChangeLog,
.\" so it's probably older than groff-0.4, where the log started
@@ -49,7 +58,7 @@
.No probably before groff-0.4 Pq before July 14, 1990 \\$1
..
.de Eaton
.No Eaton Pq before July 7, 1993; 1990/91? \\$1
.No Eaton Pq before July 7, 1993; 1990/91?\& \\$1
..
.\" man-1.5e was released on July 11, 1998.
.de man15e
@@ -399,6 +408,12 @@ do not feed out paper nor stop phototypesetter
.br
.Nm troff :
.At7
.Pp
.Bq superseded by Fl l
interpret arguments as file names
.br
.Nm man :
.At10
.It Fl G
preprocess with
.Xr grap 1
@@ -549,6 +564,7 @@ mode
.br
.Nm man :
.Bx4 ,
.At10 ,
.Eaton ;
.No POSIX , Ox , Fx , Nx , No man-db , man-1.6 , illumos , Solaris 9-11
.br
@@ -720,7 +736,9 @@ specify a page number for the first page
output mode
.br
.Nm man :
.At7
.At7 ,
.At8 ,
.At10
.Pp
do not create the
.Xr whatis 1
@@ -852,6 +870,12 @@ invoke the simultaneous input-output mode of the .rd request
.Nm nroff , troff :
.At7
.Pp
quick mode: prefer preformatted page if available
.br
.Nm man :
.At8 ,
.At10
.Pp
issue no warnings
.br
.Nm manpath :
@@ -1046,6 +1070,8 @@ output mode
.Bx 2 Pq May 10, 1979 ,
.At3 ,
.At5 ,
.At8 ,
.At10 ,
.Eaton ;
.Fx , No man-db , man-1.6 , illumos , Solaris 9-11
.br
@@ -1113,7 +1139,8 @@ print version number
verbose mode
.br
.Nm catman :
.Fx Pq March 15, 1995
.Fx Pq March 15, 1995 ,
.No mandoc Pq June 30, 2025
.br
.Nm makewhatis :
.man15g
@@ -1161,6 +1188,7 @@ list pathnames
.At7 ,
.At3 ,
.At5 ,
.At8 ,
.Eaton ;
.Ox , Fx , Nx , No man-db , man-1.6
.br
+14 -5
View File
@@ -1,6 +1,6 @@
/* $Id: man_html.c,v 1.187 2023/10/24 20:53:12 schwarze Exp $ */
/* $Id: man_html.c,v 1.188 2025/06/26 17:06:34 schwarze Exp $ */
/*
* Copyright (c) 2013-15,2017-20,2022-23 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2013-2020,2022-2023,2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -293,21 +293,30 @@ static void
man_root_post(const struct roff_meta *man, struct html *h)
{
struct tag *t;
char *title;
assert(man->title != NULL);
if (man->msec == NULL)
title = mandoc_strdup(man->title);
else
mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
t = print_otag(h, TAG_DIV, "cr?", "foot", "doc-pagefooter",
"aria-label", "Manual footer line");
print_otag(h, TAG_SPAN, "c", "foot-left");
if (man->os != NULL)
print_text(h, man->os);
print_stagq(h, t);
print_otag(h, TAG_SPAN, "c", "foot-date");
print_text(h, man->date);
print_stagq(h, t);
print_otag(h, TAG_SPAN, "c", "foot-os");
if (man->os != NULL)
print_text(h, man->os);
print_otag(h, TAG_SPAN, "c", "foot-right");
print_text(h, title);
print_tagq(h, t);
free(title);
}
static int
+60 -73
View File
@@ -1,6 +1,6 @@
/* $Id: man_term.c,v 1.244 2023/11/13 19:13:01 schwarze Exp $ */
/* $Id: man_term.c,v 1.248 2025/07/27 15:27:28 schwarze Exp $ */
/*
* Copyright (c) 2010-15,2017-20,2022-23 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010-2020,2022-23,2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -38,14 +38,14 @@
#include "term_tag.h"
#include "main.h"
#define MAXMARGINS 64 /* maximum number of indented scopes */
#define MAXMARGINS 64 /* Maximum number of indented scopes. */
struct mtermp {
int lmargin[MAXMARGINS]; /* margins (incl. vis. page) */
int lmargincur; /* index of current margin */
int lmarginsz; /* actual number of nested margins */
size_t offset; /* default offset to visible page */
int pardist; /* vert. space before par., unit: [v] */
int lmargin[MAXMARGINS]; /* Margins in basic units. */
int lmargincur; /* Index of current margin. */
int lmarginsz; /* Actual number of nested margins. */
size_t offset; /* Default offset in basic units. */
int pardist; /* Vert. space before par., unit: [v]. */
};
#define DECL_ARGS struct termp *p, \
@@ -194,12 +194,10 @@ terminal_man(void *arg, const struct roff_meta *man)
}
/*
* Printing leading vertical space before a block.
* This is used for the paragraph macros.
* The rules are pretty simple, since there's very little nesting going
* on here. Basically, if we're the first within another block (SS/SH),
* then don't emit vertical space. If we are (RS), then do. If not the
* first, print it.
* Print leading vertical space before a paragraph, unless
* it is the first paragraph in a section or subsection.
* If it is the first paragraph in an .RS block, consider
* that .RS block instead of the paragraph, recursively.
*/
static void
print_bvspace(struct termp *p, struct roff_node *n, int pardist)
@@ -214,9 +212,13 @@ print_bvspace(struct termp *p, struct roff_node *n, int pardist)
nch->type == ROFFT_TBL)
return;
if (n->parent->tok != MAN_RS && roff_node_prev(n) == NULL)
return;
while (roff_node_prev(n) == NULL) {
n = n->parent;
if (n->tok != MAN_RS)
return;
if (n->type == ROFFT_BODY)
n = n->parent;
}
for (i = 0; i < pardist; i++)
term_vspace(p);
}
@@ -372,8 +374,8 @@ static int
pre_in(DECL_ARGS)
{
struct roffsu su;
const char *cp;
size_t v;
const char *cp; /* Request argument. */
size_t v; /* Indentation in basic units. */
int less;
term_newln(p);
@@ -386,17 +388,18 @@ pre_in(DECL_ARGS)
cp = n->child->string;
less = 0;
if (*cp == '-')
if (*cp == '-') {
less = -1;
else if (*cp == '+')
cp++;
} else if (*cp == '+') {
less = 1;
else
cp--;
cp++;
}
if (a2roffsu(++cp, &su, SCALE_EN) == NULL)
if (a2roffsu(cp, &su, SCALE_EN) == NULL)
return 0;
v = term_hen(p, &su);
v = term_hspan(p, &su);
if (less < 0)
p->tcol->offset -= p->tcol->offset > v ? v : p->tcol->offset;
@@ -424,7 +427,7 @@ pre_HP(DECL_ARGS)
{
struct roffsu su;
const struct roff_node *nn;
int len;
int len; /* Indentation in basic units. */
switch (n->type) {
case ROFFT_BLOCK:
@@ -450,7 +453,7 @@ pre_HP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
len = term_hen(p, &su);
len = term_hspan(p, &su);
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -518,7 +521,7 @@ pre_IP(DECL_ARGS)
{
struct roffsu su;
const struct roff_node *nn;
int len;
int len; /* Indentation in basic units. */
switch (n->type) {
case ROFFT_BLOCK:
@@ -539,7 +542,7 @@ pre_IP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
(nn = nn->next) != NULL &&
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
len = term_hen(p, &su);
len = term_hspan(p, &su);
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -591,7 +594,7 @@ pre_TP(DECL_ARGS)
{
struct roffsu su;
struct roff_node *nn;
int len;
int len; /* Indentation in basic units. */
switch (n->type) {
case ROFFT_BLOCK:
@@ -614,7 +617,7 @@ pre_TP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
nn->string != NULL && ! (NODE_LINE & nn->flags) &&
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
len = term_hen(p, &su);
len = term_hspan(p, &su);
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -691,10 +694,11 @@ pre_SS(DECL_ARGS)
term_vspace(p);
break;
case ROFFT_HEAD:
p->fontibi = 1;
term_fontrepl(p, TERMFONT_BOLD);
p->tcol->offset = term_len(p, 3);
p->tcol->offset = term_len(p, p->defindent) / 2 + 1;
p->tcol->rmargin = mt->offset;
p->trailspace = mt->offset;
p->trailspace = mt->offset / term_len(p, 1);
p->flags |= TERMP_NOBREAK | TERMP_BRIND;
break;
case ROFFT_BODY:
@@ -732,10 +736,11 @@ pre_SH(DECL_ARGS)
term_vspace(p);
break;
case ROFFT_HEAD:
p->fontibi = 1;
term_fontrepl(p, TERMFONT_BOLD);
p->tcol->offset = 0;
p->tcol->rmargin = mt->offset;
p->trailspace = mt->offset;
p->trailspace = mt->offset / term_len(p, 1);
p->flags |= TERMP_NOBREAK | TERMP_BRIND;
break;
case ROFFT_BODY:
@@ -757,6 +762,8 @@ post_SH(DECL_ARGS)
case ROFFT_BLOCK:
break;
case ROFFT_HEAD:
p->fontibi = 0;
/* FALLTHROUGH */
case ROFFT_BODY:
term_newln(p);
break;
@@ -787,7 +794,7 @@ pre_RS(DECL_ARGS)
if (n->child == NULL)
n->aux = mt->lmargin[mt->lmargincur];
else if (a2roffsu(n->child->string, &su, SCALE_EN) != NULL)
n->aux = term_hen(p, &su);
n->aux = term_hspan(p, &su);
if (n->aux < 0 && (size_t)(-n->aux) > mt->offset)
n->aux = -mt->offset;
else if (n->aux > SHRT_MAX)
@@ -827,7 +834,7 @@ static int
pre_SY(DECL_ARGS)
{
const struct roff_node *nn;
int len;
int len; /* Indentation in basic units. */
switch (n->type) {
case ROFFT_BLOCK:
@@ -842,7 +849,9 @@ pre_SY(DECL_ARGS)
}
nn = n->parent->head->child;
len = nn == NULL ? 1 : term_strlen(p, nn->string) + 1;
len = term_len(p, 1);
if (nn != NULL)
len += term_strlen(p, nn->string);
switch (n->type) {
case ROFFT_HEAD:
@@ -1015,40 +1024,26 @@ static void
print_man_foot(struct termp *p, const struct roff_meta *meta)
{
char *title;
size_t datelen, titlen;
size_t datelen, titlen; /* In basic units. */
assert(meta->title);
assert(meta->msec);
assert(meta->date);
assert(meta->title != NULL);
assert(meta->msec != NULL);
term_fontrepl(p, TERMFONT_NONE);
if (meta->hasbody)
term_vspace(p);
/*
* Temporary, undocumented option to imitate mdoc(7) output.
* In the bottom right corner, use the operating system
* instead of the title.
*/
if ( ! p->mdocstyle) {
mandoc_asprintf(&title, "%s(%s)",
meta->title, meta->msec);
} else if (meta->os != NULL) {
title = mandoc_strdup(meta->os);
} else {
title = mandoc_strdup("");
}
datelen = term_strlen(p, meta->date);
mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
titlen = term_strlen(p, title);
/* Bottom left corner: operating system. */
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
p->trailspace = 1;
p->tcol->offset = 0;
p->tcol->rmargin = p->maxrmargin > datelen ?
(p->maxrmargin + term_len(p, 1) - datelen) / 2 : 0;
p->trailspace = 1;
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
if (meta->os)
term_word(p, meta->os);
@@ -1057,7 +1052,6 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
/* At the bottom in the middle: manual date. */
p->tcol->offset = p->tcol->rmargin;
titlen = term_strlen(p, title);
p->tcol->rmargin = p->maxrmargin > titlen ?
p->maxrmargin - titlen : 0;
p->flags |= TERMP_NOSPACE;
@@ -1067,11 +1061,11 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
/* Bottom right corner: manual title and section. */
p->flags &= ~TERMP_NOBREAK;
p->flags |= TERMP_NOSPACE;
p->trailspace = 0;
p->tcol->offset = p->tcol->rmargin;
p->tcol->rmargin = p->maxrmargin;
p->trailspace = 0;
p->flags &= ~TERMP_NOBREAK;
p->flags |= TERMP_NOSPACE;
term_word(p, title);
term_flushln(p);
@@ -1086,7 +1080,6 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
p->tcol->offset = 0;
p->flags = 0;
free(title);
}
@@ -1095,7 +1088,7 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
{
const char *volume;
char *title;
size_t vollen, titlen;
size_t vollen, titlen; /* In basic units. */
assert(meta->title);
assert(meta->msec);
@@ -1111,7 +1104,8 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
p->trailspace = 1;
p->tcol->offset = 0;
p->tcol->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
p->tcol->rmargin =
titlen * 2 + term_len(p, 2) + vollen < p->maxrmargin ?
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
@@ -1123,7 +1117,7 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
p->flags |= TERMP_NOSPACE;
p->tcol->offset = p->tcol->rmargin;
p->tcol->rmargin = p->tcol->offset + vollen + titlen <
p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin;
p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin;
term_word(p, volume);
term_flushln(p);
@@ -1143,13 +1137,6 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
p->flags &= ~TERMP_NOSPACE;
p->tcol->offset = 0;
p->tcol->rmargin = p->maxrmargin;
/*
* Groff prints three blank lines before the content.
* Do the same, except in the temporary, undocumented
* mode imitating mdoc(7) output.
*/
term_vspace(p);
free(title);
}
+13 -5
View File
@@ -1,6 +1,6 @@
/* $Id: man_validate.c,v 1.159 2023/10/24 20:53:12 schwarze Exp $ */
/* $Id: man_validate.c,v 1.161 2025/07/09 12:51:06 schwarze Exp $ */
/*
* Copyright (c) 2010, 2012-2020, 2023 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010-2020, 2023, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -299,6 +299,14 @@ post_SH(CHKARGS)
nc = n->child;
switch (n->type) {
case ROFFT_BLOCK:
if ((nc = n->prev) != NULL && nc->tok == ROFF_br) {
mandoc_msg(MANDOCERR_PAR_SKIP, nc->line, nc->pos,
"%s before first %s", roff_name[nc->tok],
roff_name[n->tok]);
roff_node_delete(man, nc);
}
return;
case ROFFT_HEAD:
tag = NULL;
deroff(&tag, n);
@@ -473,7 +481,7 @@ post_TH(CHKARGS)
/* ->TITLE<- MSEC DATE OS VOL */
n = n->child;
if (n != NULL && n->string != NULL) {
if (n != NULL && n->string != NULL && *n->string != '\0') {
for (p = n->string; *p != '\0'; p++) {
/* Only warn about this once... */
if (isalpha((unsigned char)*p) &&
@@ -486,8 +494,8 @@ post_TH(CHKARGS)
}
man->meta.title = mandoc_strdup(n->string);
} else {
man->meta.title = mandoc_strdup("");
mandoc_msg(MANDOCERR_TH_NOTITLE, nb->line, nb->pos, "TH");
man->meta.title = mandoc_strdup("UNTITLED");
mandoc_msg(MANDOCERR_DT_NOTITLE, nb->line, nb->pos, "TH");
}
/* TITLE ->MSEC<- DATE OS VOL */
+18 -25
View File
@@ -1,4 +1,4 @@
.\" $Id: mandoc.1,v 1.270 2025/03/03 14:07:51 schwarze Exp $
.\" $Id: mandoc.1,v 1.273 2025/08/22 13:17:06 schwarze Exp $
.\"
.\" Copyright (c) 2012, 2014-2023, 2025 Ingo Schwarze <[email protected]>
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <[email protected]>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: March 3 2025 $
.Dd $Mdocdate: August 22 2025 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -292,19 +292,6 @@ Increasing this is not recommended; it may result in degraded formatting,
for example overfull lines or ugly line breaks.
When output is to a pager on a terminal that is less than 66 columns
wide, the default is reduced to three columns.
.It Cm mdoc
Format
.Xr man 7
input files in
.Xr mdoc 7
output style.
This prints the operating system name rather than the page title
on the right side of the footer line.
One useful application is for checking that
.Fl T Cm man
output formats in the same way as the
.Xr mdoc 7
source it was generated from.
.It Cm tag Ns Op = Ns Ar term
If the formatted manual page is opened in a pager,
go to the definition of the
@@ -1015,14 +1002,14 @@ macro that could be represented using
or
.Ic \&Dx .
.It Sy "errnos out of order"
.Pq mdoc, Nx
.Pq mdoc , Nx
The
.Ic \&Er
items in a
.Ic \&Bl
list are not in alphabetical order.
.It Sy "duplicate errno"
.Pq mdoc, Nx
.Pq mdoc , Nx
A
.Ic \&Bl
list contains two consecutive
@@ -1121,17 +1108,21 @@ but leaving out the backslash might not be portable.
.Ss Warnings related to the document prologue
.Bl -ohang
.It Sy "missing manual title, using UNTITLED"
.Pq mdoc
.Pq mdoc , man
A
.Ic \&Dt
macro has no arguments, or there is no
or
.Ic \&TH
macro has no arguments, its first argument is an empty string, or there is no
.Ic \&Dt
macro before the first non-prologue macro.
macro before the first non-prologue
.Xr mdoc 7
macro.
.It Sy "missing manual title, using \(dq\(dq"
.Pq man
There is no
An input document does not contain any
.Ic \&TH
macro, or it has no arguments.
macro.
.It Sy "missing manual section, using \(dq\(dq"
.Pq mdoc , man
A
@@ -1159,7 +1150,7 @@ The
argument is used as provided anyway.
Consider checking whether the file name or the argument need a correction.
.It Sy "missing date, using \(dq\(dq"
.Pq mdoc, man
.Pq mdoc , man
The document was parsed as
.Xr mdoc 7
and it has no
@@ -1741,7 +1732,7 @@ or
macro contains an opening or closing parenthesis; that's probably wrong,
parentheses are added automatically.
.It Sy "unknown library name"
.Pq mdoc, not on Ox
.Pq mdoc , not on Ox
An
.Ic \&Lb
macro has an unknown name argument and will be rendered as
@@ -1799,7 +1790,7 @@ The last character is mapped to the blank character.
.Ss "Warnings related to plain text"
.Bl -ohang
.It Sy "blank line in fill mode, using .sp"
.Pq mdoc
.Pq mdoc , man
The meaning of blank input lines is only well-defined in non-fill mode:
In fill mode, line breaks of text input lines are not supposed to be
significant.
@@ -1809,6 +1800,8 @@ are formatted like
requests.
To request a paragraph break, use
.Ic \&Pp
or
.Ic \&PP
instead of a blank line.
.It Sy "tab in filled text"
.Pq mdoc , man
+2 -2
View File
@@ -1,4 +1,4 @@
/* $Id: mandoc.css,v 1.54 2025/01/25 03:18:55 schwarze Exp $ */
/* $Id: mandoc.css,v 1.55 2025/06/26 17:06:34 schwarze Exp $ */
/*
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
*
@@ -73,7 +73,7 @@ div[role=doc-pagefooter] {
.foot-left { flex: 1; }
.foot-date { flex: 0 1 auto;
text-align: center; }
.foot-os { flex: 1;
.foot-right { flex: 1;
text-align: right; }
/* Sections and paragraphs. */
+20 -6
View File
@@ -1,6 +1,6 @@
.\" $Id: mandocd.8,v 1.3 2021/09/28 15:41:41 schwarze Exp $
.\" $Id: mandocd.8,v 1.5 2025/06/30 15:07:38 schwarze Exp $
.\"
.\" Copyright (c) 2017 Ingo Schwarze <[email protected]>
.\" Copyright (c) 2017, 2025 Ingo Schwarze <[email protected]>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: September 28 2021 $
.Dd $Mdocdate: June 30 2025 $
.Dt MANDOCD 8
.Os
.Sh NAME
@@ -78,6 +78,19 @@ or
input, the second one for formatted output, and the third one
for error output.
.Pp
After accepting each message,
.Nm
replies with a one-byte message of its own,
such that the parent process can keep track of how many messages
.Nm
has already accepted and how many file descriptors
consequently are still in flight, such that the parent process
can limit the number of file descriptors in flight at any given time
in order to prevent
.Er EMFILE
failure of
.Xr sendmsg 2 .
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl I Cm os Ns = Ns Ar name
@@ -112,7 +125,7 @@ Other output options are not supported.
After exhausting one input file descriptor, all three file descriptors
are closed before reading the next dummy byte and control message.
.Pp
When a zero-byte message is read, when the
When a zero-byte message or a misformatted message is read, when the
.Ar socket_fd
is closed by the parent process,
or when an error occurs,
@@ -131,9 +144,10 @@ missing, invalid, or excessive
.Xr exec 3
arguments
.It
communication failure with the parent, for example failure in
.Xr recvmsg 2
failure, for example due to
.Er EMSGSIZE
or
.Xr send 2
.It
missing or unexpected control data, in particular a
.Fa cmsg_level
+30 -4
View File
@@ -1,7 +1,7 @@
/* $Id: mandocd.c,v 1.13 2022/04/14 16:43:44 schwarze Exp $ */
/* $Id: mandocd.c,v 1.15 2025/06/30 15:04:57 schwarze Exp $ */
/*
* Copyright (c) 2017-2019, 2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
* Copyright (c) 2017, 2019, 2021 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,11 +27,14 @@
#if HAVE_ERR
#include <err.h>
#endif
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "mandoc.h"
@@ -61,6 +64,7 @@ static void usage(void) __attribute__((__noreturn__));
static int
read_fds(int clientfd, int *fds)
{
const struct timespec timeout = { 0, 10000000 }; /* 0.01 s */
struct msghdr msg;
struct iovec iov[1];
unsigned char dummy[1];
@@ -98,6 +102,15 @@ read_fds(int clientfd, int *fds)
break;
}
*dummy = '\0';
while (send(clientfd, dummy, sizeof(dummy), 0) == -1) {
if (errno != EAGAIN) {
warn("send");
return -1;
}
nanosleep(&timeout, NULL);
}
if ((cmsg = CMSG_FIRSTHDR(&msg)) == NULL) {
warnx("CMSG_FIRSTHDR: missing control message");
return -1;
@@ -120,6 +133,7 @@ read_fds(int clientfd, int *fds)
int
main(int argc, char *argv[])
{
struct sigaction sa;
struct manoutput options;
struct mparse *parser;
void *formatter;
@@ -170,13 +184,25 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
}
if (argc != 1)
if (argc != 1) {
if (argc == 0)
warnx("missing argument: socket_fd");
else
warnx("too many arguments: %s", argv[1]);
usage();
}
errstr = NULL;
clientfd = strtonum(argv[0], 3, INT_MAX, &errstr);
if (errstr)
errx(1, "file descriptor %s %s", argv[1], errstr);
errx(1, "file descriptor %s is %s", argv[0], errstr);
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
if (sigfillset(&sa.sa_mask) == -1)
err(1, "sigfillset");
if (sigaction(SIGPIPE, &sa, NULL) == -1)
err(1, "sigaction(SIGPIPE)");
mchars_alloc();
parser = mparse_alloc(MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1 |
+4 -7
View File
@@ -1,6 +1,6 @@
/* $Id: manpath.c,v 1.44 2021/11/05 18:03:08 schwarze Exp $ */
/* $Id: manpath.c,v 1.45 2025/06/26 17:26:23 schwarze Exp $ */
/*
* Copyright (c) 2011,2014,2015,2017-2019 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011,2014,2015,2017-2021 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -218,7 +218,7 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
/* Token taking an optional argument. */
"tag",
/* Tokens not taking arguments. */
"fragment", "mdoc", "noval", "toc"
"fragment", "noval", "toc"
};
const size_t ntoks = sizeof(toks) / sizeof(toks[0]);
@@ -328,12 +328,9 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
conf->fragment = 1;
return 0;
case 10:
conf->mdoc = 1;
return 0;
case 11:
conf->noval = 1;
return 0;
case 12:
case 11:
conf->toc = 1;
return 0;
default:
+23 -12
View File
@@ -1,4 +1,4 @@
.\" $Id: mdoc.7,v 1.299 2025/06/13 16:18:28 schwarze Exp $
.\" $Id: mdoc.7,v 1.300 2025/08/19 14:08:59 schwarze Exp $
.\"
.\" Copyright (c) 2010-2021, 2024, 2025 Ingo Schwarze <[email protected]>
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <[email protected]>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: June 13 2025 $
.Dd $Mdocdate: August 19 2025 $
.Dt MDOC 7
.Os
.Sh NAME
@@ -979,7 +979,7 @@ Unless the
.Fl compact
argument is specified, list entries are separated by vertical space.
.Pp
A list must specify one of the following list types:
The following list types are commonly used:
.Bl -tag -width 12n -offset indent
.It Fl bullet
No item heads can be specified, but a bullet will be printed at the head
@@ -994,7 +994,14 @@ The
.Fl width
argument has no effect; instead, the string length of each argument
specifies the width of one column.
If the first line of the body of a
The width specification for the last column does not affect formatting.
.Pp
For two-column lists, using
.Fl tag
often results in simpler code, identical terminal output, and better HTML
output, especially when the first column contains short identifiers.
.Pp
For compatibility with legacy documents, if the first line of the body of a
.Fl column
list is not an
.Ic \&It
@@ -1016,7 +1023,7 @@ Like
except that item heads are not parsed for macro invocations.
Most often used in the
.Em DIAGNOSTICS
section with error constants in the item heads.
section with error messages in the item heads.
.It Fl enum
A numbered list.
No item heads can be specified.
@@ -1024,6 +1031,17 @@ Formatted like
.Fl bullet ,
except that ordinal numbers are used in place of bullets,
starting at 1.
.It Fl tag
Item bodies are indented according to the
.Fl width
argument.
When an item head fits inside the indentation, the item body follows
this head on the same output line.
Otherwise, the body starts on the output line following the head.
.El
.Pp
The following list types are rarely useful:
.Bl -tag -width 12n -offset indent
.It Fl hang
Like
.Fl tag ,
@@ -1050,13 +1068,6 @@ Item bodies start on the line following item heads and are not indented.
The
.Fl width
argument is ignored.
.It Fl tag
Item bodies are indented according to the
.Fl width
argument.
When an item head fits inside the indentation, the item body follows
this head on the same output line.
Otherwise, the body starts on the output line following the head.
.El
.Pp
Lists may be nested within lists and displays.
+12 -3
View File
@@ -1,4 +1,4 @@
/* $Id: mdoc_html.c,v 1.353 2025/01/25 00:22:28 schwarze Exp $ */
/* $Id: mdoc_html.c,v 1.354 2025/06/26 17:06:34 schwarze Exp $ */
/*
* Copyright (c) 2014-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -454,20 +454,29 @@ static void
mdoc_root_post(const struct roff_meta *meta, struct html *h)
{
struct tag *t;
char *title;
assert(meta->title != NULL);
if (meta->msec == NULL)
title = mandoc_strdup(meta->title);
else
mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
t = print_otag(h, TAG_DIV, "cr?", "foot", "doc-pagefooter",
"aria-label", "Manual footer line");
print_otag(h, TAG_SPAN, "c", "foot-left");
print_text(h, meta->os);
print_stagq(h, t);
print_otag(h, TAG_SPAN, "c", "foot-date");
print_text(h, meta->date);
print_stagq(h, t);
print_otag(h, TAG_SPAN, "c", "foot-os");
print_text(h, meta->os);
print_otag(h, TAG_SPAN, "c", "foot-right");
print_text(h, title);
print_tagq(h, t);
free(title);
}
static int
+2 -3
View File
@@ -1,4 +1,4 @@
/* $Id: mdoc_man.c,v 1.139 2025/01/24 22:37:24 schwarze Exp $ */
/* $Id: mdoc_man.c,v 1.141 2025/07/02 19:57:48 schwarze Exp $ */
/*
* Copyright (c) 2011-2021, 2025 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -494,6 +494,7 @@ print_offs(const char *v, int keywords)
const char *end;
int sz;
outflags &= ~MMAN_PP;
print_line(".RS", MMAN_Bk_susp);
/* Convert v into a number (of characters). */
@@ -1616,9 +1617,7 @@ pre_lk(DECL_ARGS)
}
/* Link target. */
font_push('B');
print_word(link->string);
font_pop();
/* Trailing punctuation. */
while (punct != NULL) {
+9 -1
View File
@@ -1,4 +1,4 @@
/* $Id: mdoc_markdown.c,v 1.39 2025/01/20 07:01:17 schwarze Exp $ */
/* $Id: mdoc_markdown.c,v 1.40 2025/06/26 17:06:34 schwarze Exp $ */
/*
* Copyright (c) 2017, 2018, 2020, 2025 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -292,6 +292,14 @@ markdown_mdoc(void *arg, const struct roff_meta *mdoc)
md_word(mdoc->os);
md_word("-");
md_word(mdoc->date);
md_word("-");
md_word(mdoc->title);
if (mdoc->msec != NULL) {
outflags &= ~MD_spc;
md_word("(");
md_word(mdoc->msec);
md_word(")");
}
putchar('\n');
}
+68 -54
View File
@@ -1,6 +1,6 @@
/* $Id: mdoc_term.c,v 1.383 2023/11/13 19:13:01 schwarze Exp $ */
/* $Id: mdoc_term.c,v 1.387 2025/07/27 15:27:28 schwarze Exp $ */
/*
* Copyright (c) 2010, 2012-2020, 2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010,2012-2020,2022,2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
*
@@ -302,7 +302,7 @@ print_mdoc_node(DECL_ARGS)
{
const struct mdoc_term_act *act;
struct termpair npair;
size_t offset, rmargin;
size_t offset, rmargin; /* In basic units. */
int chld;
/*
@@ -441,70 +441,62 @@ print_mdoc_node(DECL_ARGS)
static void
print_mdoc_foot(struct termp *p, const struct roff_meta *meta)
{
size_t sz;
char *title;
size_t datelen, titlen; /* In basic units. */
assert(meta->title != NULL);
datelen = term_strlen(p, meta->date);
if (meta->msec == NULL)
title = mandoc_strdup(meta->title);
else
mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
titlen = term_strlen(p, title);
term_fontrepl(p, TERMFONT_NONE);
/*
* Output the footer in new-groff style, that is, three columns
* with the middle being the manual date and flanking columns
* being the operating system:
*
* SYSTEM DATE SYSTEM
*/
term_vspace(p);
/* Bottom left corner: operating system. */
p->tcol->offset = 0;
sz = term_strlen(p, meta->date);
p->tcol->rmargin = p->maxrmargin > sz ?
(p->maxrmargin + term_len(p, 1) - sz) / 2 : 0;
p->tcol->rmargin = p->maxrmargin > datelen ?
(p->maxrmargin + term_len(p, 1) - datelen) / 2 : 0;
p->trailspace = 1;
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
term_word(p, meta->os);
term_flushln(p);
/* At the bottom in the middle: manual date. */
p->tcol->offset = p->tcol->rmargin;
sz = term_strlen(p, meta->os);
p->tcol->rmargin = p->maxrmargin > sz ? p->maxrmargin - sz : 0;
p->tcol->rmargin = p->maxrmargin > titlen ?
p->maxrmargin - titlen : 0;
p->flags |= TERMP_NOSPACE;
term_word(p, meta->date);
term_flushln(p);
/* Bottom right corner: manual title and section. */
p->tcol->offset = p->tcol->rmargin;
p->tcol->rmargin = p->maxrmargin;
p->trailspace = 0;
p->flags &= ~TERMP_NOBREAK;
p->flags |= TERMP_NOSPACE;
term_word(p, meta->os);
term_word(p, title);
term_flushln(p);
p->tcol->offset = 0;
p->tcol->rmargin = p->maxrmargin;
p->flags = 0;
free(title);
}
static void
print_mdoc_head(struct termp *p, const struct roff_meta *meta)
{
char *volume, *title;
size_t vollen, titlen;
/*
* The header is strange. It has three components, which are
* really two with the first duplicated. It goes like this:
*
* IDENTIFIER TITLE IDENTIFIER
*
* The IDENTIFIER is NAME(SECTION), which is the command-name
* (if given, or "unknown" if not) followed by the manual page
* section. These are given in `Dt'. The TITLE is a free-form
* string depending on the manual volume. If not specified, it
* switches on the manual section.
*/
size_t vollen, titlen; /* In basic units. */
assert(meta->vol);
if (NULL == meta->arch)
@@ -514,6 +506,8 @@ print_mdoc_head(struct termp *p, const struct roff_meta *meta)
meta->vol, meta->arch);
vollen = term_strlen(p, volume);
/* Top left corner: manual title and section. */
if (NULL == meta->msec)
title = mandoc_strdup(meta->title);
else
@@ -524,13 +518,16 @@ print_mdoc_head(struct termp *p, const struct roff_meta *meta)
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
p->trailspace = 1;
p->tcol->offset = 0;
p->tcol->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
p->tcol->rmargin =
titlen * 2 + term_len(p, 2) + vollen < p->maxrmargin ?
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
term_word(p, title);
term_flushln(p);
/* At the top in the middle: manual volume. */
p->flags |= TERMP_NOSPACE;
p->tcol->offset = p->tcol->rmargin;
p->tcol->rmargin = p->tcol->offset + vollen + titlen <
@@ -539,6 +536,8 @@ print_mdoc_head(struct termp *p, const struct roff_meta *meta)
term_word(p, volume);
term_flushln(p);
/* Top right corner: title and section, again. */
p->flags &= ~TERMP_NOBREAK;
p->trailspace = 0;
if (p->tcol->rmargin + titlen <= p->maxrmargin) {
@@ -556,6 +555,11 @@ print_mdoc_head(struct termp *p, const struct roff_meta *meta)
free(volume);
}
/*
* Interpret the string v as a scaled width or, if the syntax is invalid,
* measure how much width it takes up when printed. In both cases,
* return the width in basic units.
*/
static int
a2width(const struct termp *p, const char *v)
{
@@ -564,10 +568,10 @@ a2width(const struct termp *p, const char *v)
end = a2roffsu(v, &su, SCALE_MAX);
if (end == NULL || *end != '\0') {
su.unit = SCALE_EN;
su.scale = term_strlen(p, v) / term_strlen(p, "0");
su.unit = SCALE_BU;
su.scale = term_strlen(p, v);
}
return term_hen(p, &su);
return term_hspan(p, &su);
}
/*
@@ -623,8 +627,11 @@ termp_it_pre(DECL_ARGS)
struct roffsu su;
char buf[24];
const struct roff_node *bl, *nn;
size_t ncols, dcol;
int i, offset, width;
size_t ncols; /* Number of columns in .Bl -column. */
size_t dcol; /* Column spacing in basic units. */
int i; /* Zero-based column index. */
int offset; /* Start of column in basic units. */
int width; /* Column width in basic units. */
enum mdoc_list type;
if (n->type == ROFFT_BLOCK) {
@@ -701,10 +708,9 @@ termp_it_pre(DECL_ARGS)
for (i = 0, nn = n->prev;
nn->prev && i < (int)ncols;
nn = nn->prev, i++) {
su.unit = SCALE_EN;
su.scale = term_strlen(p, bl->norm->Bl.cols[i]) /
term_strlen(p, "0");
offset += term_hen(p, &su) + dcol;
su.unit = SCALE_BU;
su.scale = term_strlen(p, bl->norm->Bl.cols[i]);
offset += term_hspan(p, &su) + dcol;
}
/*
@@ -720,10 +726,9 @@ termp_it_pre(DECL_ARGS)
* Use the declared column widths, extended as explained
* in the preceding paragraph.
*/
su.unit = SCALE_EN;
su.scale = term_strlen(p, bl->norm->Bl.cols[i]) /
term_strlen(p, "0");
width = term_hen(p, &su) + dcol;
su.unit = SCALE_BU;
su.scale = term_strlen(p, bl->norm->Bl.cols[i]);
width = term_hspan(p, &su) + dcol;
break;
default:
if (NULL == bl->norm->Bl.width)
@@ -1274,6 +1279,7 @@ termp_sh_pre(DECL_ARGS)
term_vspace(p);
break;
case ROFFT_HEAD:
p->fontibi = 1;
return termp_bold_pre(p, pair, meta, n);
case ROFFT_BODY:
p->tcol->offset = term_len(p, p->defindent);
@@ -1294,6 +1300,7 @@ termp_sh_post(DECL_ARGS)
{
switch (n->type) {
case ROFFT_HEAD:
p->fontibi = 0;
term_newln(p);
break;
case ROFFT_BODY:
@@ -1421,7 +1428,7 @@ termp_fa_pre(DECL_ARGS)
static int
termp_bd_pre(DECL_ARGS)
{
int offset;
int offset; /* In basic units. */
if (n->type == ROFFT_BLOCK) {
print_bvspace(p, n, n);
@@ -1509,7 +1516,8 @@ termp_ss_pre(DECL_ARGS)
term_vspace(p);
break;
case ROFFT_HEAD:
p->tcol->offset = term_len(p, (p->defindent+1)/2);
p->tcol->offset = term_len(p, p->defindent) / 2 + 1;
p->fontibi = 1;
return termp_bold_pre(p, pair, meta, n);
case ROFFT_BODY:
p->tcol->offset = term_len(p, p->defindent);
@@ -1526,8 +1534,16 @@ termp_ss_pre(DECL_ARGS)
static void
termp_ss_post(DECL_ARGS)
{
if (n->type == ROFFT_HEAD || n->type == ROFFT_BODY)
switch (n->type) {
case ROFFT_HEAD:
p->fontibi = 0;
/* FALLTHROUGH */
case ROFFT_BODY:
term_newln(p);
break;
default:
break;
}
}
static int
@@ -1888,9 +1904,7 @@ termp_lk_pre(DECL_ARGS)
}
/* Link target. */
term_fontpush(p, TERMFONT_BOLD);
term_word(p, link->string);
term_fontpop(p);
/* Trailing punctuation. */
while (punct != NULL) {
+4 -6
View File
@@ -1,4 +1,4 @@
/* $Id: mdoc_validate.c,v 1.393 2025/06/05 12:38:26 schwarze Exp $ */
/* $Id: mdoc_validate.c,v 1.396 2025/07/26 12:23:16 schwarze Exp $ */
/*
* Copyright (c) 2010-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -1714,7 +1714,7 @@ post_xx(POST_ARGS)
os = "OpenBSD";
break;
case MDOC_Ux:
os = "UNIX";
os = "Unix";
break;
default:
abort();
@@ -2777,7 +2777,7 @@ post_dd(POST_ARGS)
mandoc_msg(MANDOCERR_PROLOG_ORDER,
n->line, n->pos, "Dd after Os");
if (mdoc->quick && n != NULL)
if (mdoc->quick)
mdoc->meta.date = mandoc_strdup("");
else
mdoc->meta.date = mandoc_normdate(n->child, n);
@@ -2842,8 +2842,7 @@ post_dt(POST_ARGS)
if (nn == NULL) {
mandoc_msg(MANDOCERR_MSEC_MISSING, n->line, n->pos,
"Dt %s", mdoc->meta.title);
mdoc->meta.vol = mandoc_strdup("LOCAL");
return; /* msec and arch remain NULL. */
return; /* msec, vol, and arch remain NULL. */
}
mdoc->meta.msec = mandoc_strdup(nn->string);
@@ -2854,7 +2853,6 @@ post_dt(POST_ARGS)
if (cp == NULL) {
mandoc_msg(MANDOCERR_MSEC_BAD,
nn->line, nn->pos, "Dt ... %s", nn->string);
mdoc->meta.vol = mandoc_strdup(nn->string);
} else {
mdoc->meta.vol = mandoc_strdup(cp);
if (mdoc->filesec != '\0' &&
+42 -21
View File
@@ -1,8 +1,8 @@
/* $Id: out.c,v 1.86 2025/01/05 18:14:39 schwarze Exp $ */
/* $Id: out.c,v 1.87 2025/07/16 14:33:08 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2014, 2015, 2017, 2018, 2019, 2021
* Copyright (c) 2011, 2014, 2015, 2017, 2018, 2019, 2021, 2025
* Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -122,9 +122,23 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
const struct tbl_dat *dp;
struct roffcol *col;
struct tbl_colgroup *first_group, **gp, *g;
size_t *colwidth;
size_t ewidth, min1, min2, wanted, width, xwidth;
int done, icol, maxcol, necol, nxcol, quirkcol;
/* Widths in basic units. */
size_t *colwidth; /* Widths of all columns. */
size_t min1; /* Width of the narrowest column. */
size_t min2; /* Width of the second narrowest column. */
size_t wanted; /* For any of the narrowest columns. */
size_t xwidth; /* Total width of columns not to expand. */
size_t ewidth; /* Width of widest column to equalize. */
size_t width; /* Width of the data in basic units. */
size_t enw; /* Width of one EN unit. */
int icol; /* Column number, starting at zero. */
int maxcol; /* Number of last column. */
int necol; /* Number of columns to equalize. */
int nxcol; /* Number of columns to expand. */
int done; /* Boolean: this group is wide enough. */
int quirkcol;
/*
* Allocate the master column specifiers. These will hold the
@@ -139,6 +153,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
maxcol = -1;
first_group = NULL;
enw = (*tbl->len)(1, tbl->arg);
for (sp = sp_first; sp != NULL; sp = sp->next) {
if (sp->pos != TBL_SPAN_DATA)
continue;
@@ -175,8 +190,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
opts, dp,
dp->block == 0 ? 0 :
dp->layout->width ? dp->layout->width :
rmargin ? (rmargin + sp->opts->cols / 2)
/ (sp->opts->cols + 1) : 0);
rmargin ? (rmargin / enw + sp->opts->cols / 2) /
(sp->opts->cols + 1) * enw : 0);
if (dp->hspans == 0)
continue;
@@ -211,8 +226,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
maxcol = sp_first->opts->cols - 1;
for (icol = 0; icol <= maxcol; icol++) {
col = tbl->cols + icol;
if (col->width < 1)
col->width = 1;
if (col->width < enw)
col->width = enw;
/*
* Column spacings are needed for span width
@@ -234,7 +249,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
for (icol = g->startcol; icol <= g->endcol; icol++) {
width = tbl->cols[icol].width;
if (icol < g->endcol)
width += tbl->cols[icol].spacing;
width += (*tbl->len)(tbl->cols[icol].spacing,
tbl->arg);
if (g->wanted <= width) {
done = 1;
break;
@@ -372,9 +388,9 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
*/
if (nxcol && rmargin) {
xwidth += 3*maxcol +
xwidth += (*tbl->len)(3 * maxcol +
(opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX) ?
2 : !!opts->lvert + !!opts->rvert);
2 : !!opts->lvert + !!opts->rvert), tbl->arg);
if (rmargin <= offset + xwidth)
return;
xwidth = rmargin - offset - xwidth;
@@ -387,7 +403,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
*/
if (nxcol == 5) {
quirkcol = xwidth % nxcol + 2;
quirkcol = xwidth / enw % nxcol + 2;
if (quirkcol != 3 && quirkcol != 4)
quirkcol = -1;
} else
@@ -402,7 +418,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
col->width = (double)xwidth * ++necol / nxcol
- ewidth + 0.4995;
if (necol == quirkcol)
col->width--;
col->width -= enw;
ewidth += col->width;
}
}
@@ -444,9 +460,12 @@ tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
const char *str; /* Beginning of the first line. */
const char *beg; /* Beginning of the current line. */
char *end; /* End of the current line. */
size_t lsz; /* Length of the current line. */
size_t wsz; /* Length of the current word. */
size_t msz; /* Length of the longest line. */
/* Widths in basic units. */
size_t lsz; /* Of the current line. */
size_t wsz; /* Of the current word. */
size_t msz; /* Of the longest line. */
size_t enw; /* Of one EN unit. */
if (dp->string == NULL || *dp->string == '\0')
return 0;
@@ -460,8 +479,9 @@ tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
end++;
}
wsz = (*tbl->slen)(beg, tbl->arg);
if (mw && lsz && lsz + 1 + wsz <= mw)
lsz += 1 + wsz;
enw = (*tbl->len)(1, tbl->arg);
if (mw && lsz && lsz + enw + wsz <= mw)
lsz += enw + wsz;
else
lsz = wsz;
if (msz < lsz)
@@ -479,7 +499,8 @@ tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
const struct tbl_opts *opts, const struct tbl_dat *dp)
{
const char *cp, *lastdigit, *lastpoint;
size_t intsz, totsz;
size_t totsz; /* Total width of the number in basic units. */
size_t intsz; /* Width of the integer part in basic units. */
char buf[2];
if (dp->string == NULL || *dp->string == '\0')
+11 -13
View File
@@ -1,7 +1,7 @@
/* $Id: out.h,v 1.35 2022/09/11 09:13:48 schwarze Exp $ */
/* $Id: out.h,v 1.36 2025/07/16 14:33:08 schwarze Exp $ */
/*
* Copyright (c) 2011,2014,2017,2018,2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -33,11 +33,11 @@ enum roffscale {
};
struct roffcol {
size_t width; /* width of cell */
size_t nwidth; /* max. width of number in cell */
size_t decimal; /* decimal position in cell */
size_t spacing; /* spacing after the column */
int flags; /* layout flags, see tbl_cell */
size_t width; /* Width of cell [BU]. */
size_t nwidth; /* Maximum width of number [BU]. */
size_t decimal; /* Decimal position [BU]. */
size_t spacing; /* Spacing after the column [EN]. */
int flags; /* Layout flags, see tbl_cell. */
};
struct roffsu {
@@ -45,16 +45,14 @@ struct roffsu {
double scale;
};
typedef size_t (*tbl_sulen)(const struct roffsu *, void *);
typedef size_t (*tbl_strlen)(const char *, void *);
typedef size_t (*tbl_len)(size_t, void *);
struct rofftbl {
tbl_sulen sulen; /* calculate scaling unit length */
tbl_strlen slen; /* calculate string length */
tbl_len len; /* produce width of empty space */
struct roffcol *cols; /* master column specifiers */
void *arg; /* passed to sulen, slen, and len */
tbl_strlen slen; /* Calculate string length [BU]. */
tbl_len len; /* Produce width of empty space [BU]. */
struct roffcol *cols; /* Master column specifiers. */
void *arg; /* Passed to slen() and len(). */
};
+148 -47
View File
@@ -1,6 +1,6 @@
.\" $Id: roff.7,v 1.121 2023/10/23 20:25:02 schwarze Exp $
.\" $Id: roff.7,v 1.123 2025/08/04 23:12:08 schwarze Exp $
.\"
.\" Copyright (c) 2010-2019, 2022-2023 Ingo Schwarze <[email protected]>
.\" Copyright (c) 2010-2019,2022-2023,2025 Ingo Schwarze <[email protected]>
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <[email protected]>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: October 23 2023 $
.Dd $Mdocdate: August 4 2025 $
.Dt ROFF 7
.Os
.Sh NAME
@@ -79,8 +79,10 @@ They provide free-form text to be printed; the formatting of the text
depends on the respective processing context.
.Sh LANGUAGE SYNTAX
.Nm
documents may contain only graphable 7-bit ASCII characters, the space
character, and, in certain circumstances, the tab character.
documents are text files containing only printable
.Xr ascii 7
characters, the space character,
and, in certain circumstances, the tab character.
The backslash character
.Sq \e
indicates the start of an escape sequence, used for example for
@@ -180,7 +182,7 @@ Italic font.
Return to the previous font.
If a macro caused a font change since the last
.Ic \ef
eascape sequence or
escape sequence or
.Ic \&ft
request, this returns to the font before the last font change in
the macro rather than to the font before the last manual font change.
@@ -267,7 +269,7 @@ width of rendered
.Pq en
character
.It u
default horizontal span for the terminal
device-dependent basic units
.It M
mini-em (1/100 em)
.El
@@ -289,7 +291,7 @@ for vertical spaces and
for horizontal ones.
.Pp
Examples:
.Bl -tag -width ".Bl -tag -width 2i" -offset indent -compact
.Bl -tag -width "xBl -tag -width 2i" -offset indent -compact
.It Li \&.Bl -tag -width 2i
two-inch tagged list indentation in
.Xr mdoc 7
@@ -1319,10 +1321,16 @@ among others because it overrides the
.Xr mandoc 1
.Fl O Cm width
command line option.
.It Ic \&lnr Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar value Op Ar increment
.It Ic \&lnr Ar registername Xo
.Oo Cm + Ns | Ns Cm \- Oc Ns Ar value
.Op Ar increment
.Xc
Set local number register.
This is a Heirloom extension and currently unsupported.
.It Ic \&lnrf Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar value Op Ar increment
.It Ic \&lnrf Ar registername Xo
.Oo Cm + Ns | Ns Cm \- Oc Ns Ar value
.Op Ar increment
.Xc
Set local floating-point register.
This is a Heirloom extension and currently unsupported.
.It Ic \&lpfx Ar string
@@ -1398,10 +1406,13 @@ skipping the
.Ic \&nop
request and any space characters immediately following it.
This is mostly used to indent text lines inside macro definitions.
.It Ic \&nr Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar expression Op Ar stepsize
Define or change a register.
A register is an arbitrary string value that defines some sort of state,
which influences parsing and/or formatting.
.It Ic \&nr Ar registername Xo
.Oo Cm + Ns | Ns Cm \- Oc Ns Ar expression
.Op Ar stepsize
.Xc
Define or change the number register with the given
.Ar registername .
A register can store an integer number.
For the syntax of
.Ar expression ,
see
@@ -1410,6 +1421,9 @@ below.
If it is prefixed by a sign, the register will be
incremented or decremented instead of assigned to.
.Pp
Once set, the value of a number register can be interpolated using the
.Ic \en
escape sequence.
The
.Ar stepsize
is used by the
@@ -1418,29 +1432,13 @@ auto-increment feature.
It remains unchanged when omitted while changing an existing register,
and it defaults to 0 when defining a new register.
.Pp
The following
.Ar register
is handled specially:
.Bl -tag -width Ds
.It Cm nS
If set to a positive integer value, certain
.Xr mdoc 7
macros will behave in the same way as in the
.Em SYNOPSIS
section.
If set to 0, these macros will behave in the same way as outside the
.Em SYNOPSIS
section, even when called within the
.Em SYNOPSIS
section itself.
Note that starting a new
.Xr mdoc 7
section with the
.Ic \&Sh
macro will reset this register.
.El
Some number registers can be read to inspect parser state,
and some can be changed to influence formatting.
For details about individual registers, see the
.Sx NUMBER REGISTER REFERENCE
below.
.It Xo
.Ic \&nrf Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar expression
.Ic \&nrf Ar registername Oo Cm + Ns | Ns Cm \- Oc Ns Ar expression
.Op Ar increment
.Xc
Define or change a floating-point register.
@@ -1569,7 +1567,7 @@ requests is not supported, and diversions are not implemented at all.
Rename a number register.
Currently unsupported.
.It Ic \&rr Ar register
Remove a register.
Remove a number register.
.It Ic \&rs
End no-space mode.
Currently ignored.
@@ -2152,6 +2150,8 @@ on the current font.
.It Ic \en Ns Oo +|- Oc Ns Ic \&[ Ns Ar name Ns Ic \&]
Interpolate the number register
.Ar name .
If the register is not yet defined,
it is automatically initialised to zero before interpolation.
For short names, there are variants
.Ic \en Ns Ar c
and
@@ -2162,6 +2162,9 @@ the register is first incremented or decremented by the
that was specified in the relevant
.Ic \&nr
request, and the changed value is interpolated.
For the names of predefined registers, see the
.Sx NUMBER REGISTER REFERENCE
below.
.It Ic \eO Ns Ar digit , Ic \eO[5 Ns arguments Ns Ic \&]
Suppress output.
This is a groff extension and currently unsupported.
@@ -2250,6 +2253,83 @@ with zero width and height; ignored by
.It Ic \ez
Output the next character without advancing the cursor position.
.El
.Sh NUMBER REGISTER REFERENCE
In
.Xr mdoc 7
and
.Xr man 7
documents, using registers is discouraged.
For compatibility with legacy documents, the
.Xr mandoc 1
.Nm
parser recognises the following names of read-only registers:
.Bl -tag -width Ds
.It Cm .$
The number of arguments of the innermost user-defined macro
currently being called, or 0 by default.
The
.Ic shift
request decrements the value of this register.
.It Cm .A
Whether ASCII approximation mode is on;
.Xr mandoc 1
always returns 0, meaning off.
.It Cm .g
Whether the formatter claims groff compatibility;
.Xr mandoc 1
always returns 1, meaning yes.
.It Cm .H
The minimum horizontal movement in basic units;
.Xr mandoc 1
always returns 24, corresponding to one character position.
.It Cm .j
The current line adjustment mode;
.Xr mandoc 1
always returns 0, meaning flush left.
.It Cm .l
The line length in basic units;
.Xr mandoc 1
always returns 78 * 24, corresponding to 78 characters per line.
.It Cm \&.T
Whether an output device has been selected;
.Xr mandoc 1
always returns 1, meaning yes.
.It Cm .V
The minimum vertical movement in basic units;
.Xr mandoc 1
always returns 40, corresponding to one line height.
.El
.Pp
The
.Cm nS
register is handled specially.
If set to a positive integer value, certain
.Xr mdoc 7
macros behave in the same way as in the
.Em SYNOPSIS
section.
If set to 0, these macros behave in the same way as outside the
.Em SYNOPSIS
section, even when called within the
.Em SYNOPSIS
section itself.
Starting a new
.Xr mdoc 7
section with the
.Ic \&Sh
macro resets this register.
.Pp
Full
.Nm
implementations support large numbers of additional predefined registers.
While the
.Ic \&nr
request supports setting and the
.Ic \en
escape sequence supports inspecting arbitrary registers,
.Xr mandoc 1
only defines the few registers listed above by default.
All other registers are undefined by default and yield 0 when interpolated.
.Sh COMPATIBILITY
The
.Xr mandoc 1
@@ -2266,17 +2346,29 @@ never reads or writes external files except via
.Ic \&so
requests with safe relative paths.
.It
There is no automatic hyphenation, no adjustment to the right margin,
and very limited support for centering; the output is always set flush-left.
There is no automatic hyphenation and no support for the
.Ic \&ad
line adjustment request.
Except when the
.Ic \&ce
or
.Ic \&rj
requests or the
.Xr tbl 7
cell specifications
.Cm c ,
.Cm n ,
or
.Cm r
or the table option
.Cm center
are used, output is always set flush-left.
.It
Support for setting tabulator and leader characters is missing,
and support for manually changing indentation is limited.
.It
The
.Sq u
scaling unit is the default terminal unit.
In traditional troff systems, this unit changes depending on the
output media.
Support for setting tabulator and leader characters is missing, and the
.Ic \&in
indentation request is not supported in
.Xr mdoc 7
input files.
.It
Width measurements are implemented in a crude way
and often yield wrong results.
@@ -2336,6 +2428,15 @@ implementations.
.%D September 17, 2007
.%U http://heirloom.sourceforge.net/doctools/troff.pdf
.Re
.Rs
.%A James Clark
.%A Werner Lemberg
.%A G. Branden Robinson
.%I Free Software Foundation, Inc.
.%T The GNU Troff Manual
.%D 1999\(en2023
.%U https://www.gnu.org/software/groff/manual/
.Re
.Sh HISTORY
The RUNOFF typesetting system, whose input forms the basis for
.Nm ,
+21 -11
View File
@@ -1,6 +1,7 @@
/* $Id: roff_term.c,v 1.25 2023/04/28 19:11:04 schwarze Exp $ */
/* $Id: roff_term.c,v 1.27 2025/08/21 15:38:51 schwarze Exp $ */
/*
* Copyright (c) 2010,2014,2015,2017-2020 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2014, 2015, 2017-2021, 2025
* Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -159,8 +160,14 @@ static void
roff_term_pre_po(ROFF_TERM_ARGS)
{
struct roffsu su;
static int po, pouse, polast;
int ponew;
/* Page offsets in basic units. */
static int polast; /* Previously requested. */
static int po; /* Currently requested. */
static int pouse; /* Currently used. */
int pomin; /* Minimum to be used. */
int pomax; /* Maximum to be used. */
int ponew; /* Newly requested. */
/* Revert the currently active page offset. */
p->tcol->offset -= pouse;
@@ -168,7 +175,7 @@ roff_term_pre_po(ROFF_TERM_ARGS)
/* Determine the requested page offset. */
if (n->child != NULL &&
a2roffsu(n->child->string, &su, SCALE_EM) != NULL) {
ponew = term_hen(p, &su);
ponew = term_hspan(p, &su);
if (*n->child->string == '+' ||
*n->child->string == '-')
ponew += po;
@@ -180,8 +187,9 @@ roff_term_pre_po(ROFF_TERM_ARGS)
po = ponew;
/* Truncate to the range [-offset, 60], remember, and apply it. */
pouse = po >= 60 ? 60 :
po < -(int)p->tcol->offset ? -(int)p->tcol->offset : po;
pomin = -p->tcol->offset;
pomax = term_len(p, 60);
pouse = po > pomax ? pomax : po < pomin ? pomin : po;
p->tcol->offset += pouse;
}
@@ -219,9 +227,10 @@ static void
roff_term_pre_ti(ROFF_TERM_ARGS)
{
struct roffsu su;
const char *cp;
const size_t maxoff = 72;
int len, sign;
const char *cp; /* Request argument. */
size_t maxoff; /* Maximum indentation in basic units. */
int len; /* Request argument in basic units. */
int sign;
roff_term_pre_br(p, n);
@@ -239,7 +248,8 @@ roff_term_pre_ti(ROFF_TERM_ARGS)
if (a2roffsu(cp, &su, SCALE_EM) == NULL)
return;
len = term_hen(p, &su);
len = term_hspan(p, &su);
maxoff = term_len(p, 72);
switch (sign) {
case 1:
+8 -8
View File
@@ -1,7 +1,7 @@
/* $Id: tbl.h,v 1.3 2025/01/05 18:14:39 schwarze Exp $ */
/* $Id: tbl.h,v 1.4 2025/07/16 14:33:08 schwarze Exp $ */
/*
* Copyright (c) 2014-2018, 2021, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014,2015,2017,2018,2021 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,8 +27,8 @@ struct tbl_opts {
#define TBL_OPT_NOSPACE (1 << 6) /* Option "nospaces". */
#define TBL_OPT_NOWARN (1 << 7) /* Option "nowarn". */
int cols; /* Number of columns. */
int lvert; /* Width of left vertical line. */
int rvert; /* Width of right vertical line. */
int lvert; /* Width of left vertical line in EN. */
int rvert; /* Width of right vertical line in EN. */
char tab; /* Option "tab": cell separator. */
char decimal; /* Option "decimalpoint". */
};
@@ -51,9 +51,9 @@ enum tbl_cellt {
*/
struct tbl_cell {
struct tbl_cell *next; /* Layout cell to the right. */
size_t width; /* Minimum column width. */
size_t spacing; /* To the right of the column. */
int vert; /* Width of subsequent vertical line. */
size_t width; /* Minimum column width in basic units. */
size_t spacing; /* To the right of the column in EN. */
int vert; /* Width of subseq. vertical line in EN. */
int col; /* Column number, starting from 0. */
int flags;
#define TBL_CELL_TALIGN (1 << 2) /* t, T */
@@ -73,7 +73,7 @@ struct tbl_row {
struct tbl_row *next; /* Layout row below. */
struct tbl_cell *first; /* Leftmost layout cell. */
struct tbl_cell *last; /* Rightmost layout cell. */
int vert; /* Width of left vertical line. */
int vert; /* Width of left vertical line in EN. */
};
enum tbl_datt {
+1 -33
View File
@@ -1,4 +1,4 @@
/* $Id: tbl_html.c,v 1.41 2022/04/23 14:02:17 schwarze Exp $ */
/* $Id: tbl_html.c,v 1.42 2025/07/16 14:33:08 schwarze Exp $ */
/*
* Copyright (c) 2014, 2015, 2017, 2018, 2021, 2022
* Ingo Schwarze <schwarze@openbsd.org>
@@ -37,7 +37,6 @@
static void html_tblopen(struct html *, const struct tbl_span *);
static size_t html_tbl_len(size_t, void *);
static size_t html_tbl_strlen(const char *, void *);
static size_t html_tbl_sulen(const struct roffsu *, void *);
static size_t
@@ -52,36 +51,6 @@ html_tbl_strlen(const char *p, void *arg)
return strlen(p);
}
static size_t
html_tbl_sulen(const struct roffsu *su, void *arg)
{
if (su->scale < 0.0)
return 0;
switch (su->unit) {
case SCALE_FS: /* 2^16 basic units */
return su->scale * 65536.0 / 24.0;
case SCALE_IN: /* 10 characters per inch */
return su->scale * 10.0;
case SCALE_CM: /* 2.54 cm per inch */
return su->scale * 10.0 / 2.54;
case SCALE_PC: /* 6 pica per inch */
case SCALE_VS:
return su->scale * 10.0 / 6.0;
case SCALE_EN:
case SCALE_EM:
return su->scale;
case SCALE_PT: /* 12 points per pica */
return su->scale * 10.0 / 6.0 / 12.0;
case SCALE_BU: /* 24 basic units per character */
return su->scale / 24.0;
case SCALE_MM: /* 1/1000 inch */
return su->scale / 100.0;
default:
abort();
}
}
static void
html_tblopen(struct html *h, const struct tbl_span *sp)
{
@@ -89,7 +58,6 @@ html_tblopen(struct html *h, const struct tbl_span *sp)
if (h->tbl.cols == NULL) {
h->tbl.len = html_tbl_len;
h->tbl.slen = html_tbl_strlen;
h->tbl.sulen = html_tbl_sulen;
tblcalc(&h->tbl, sp, 0, 0);
}
assert(NULL == h->tblt);
+5 -5
View File
@@ -1,4 +1,4 @@
/* $Id: tbl_layout.c,v 1.51 2025/01/05 18:14:39 schwarze Exp $ */
/* $Id: tbl_layout.c,v 1.52 2025/07/16 14:33:08 schwarze Exp $ */
/*
* Copyright (c) 2012, 2014, 2015, 2017, 2020, 2021, 2025
* Ingo Schwarze <schwarze@openbsd.org>
@@ -66,8 +66,8 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
int ln, const char *p, int *pos)
{
char *endptr;
unsigned long spacing;
int isz;
unsigned long spacing; /* Column spacing in EN units. */
int isz; /* Width in basic units. */
enum mandoc_esc fontesc;
mod:
@@ -145,8 +145,7 @@ mod:
mandoc_msg(MANDOCERR_TBLLAYOUT_WIDTH,
ln, *pos, "%s", p + *pos);
else {
/* Convert from BU to EN and round. */
cp->width = (isz + 11) /24;
cp->width = isz;
(*pos)++;
}
} else {
@@ -155,6 +154,7 @@ mod:
cp->width *= 10;
cp->width += p[(*pos)++] - '0';
}
cp->width *= 24;
if (cp->width == 0)
mandoc_msg(MANDOCERR_TBLLAYOUT_WIDTH,
ln, *pos, "%s", p + *pos);
+165 -122
View File
@@ -1,6 +1,6 @@
/* $Id: tbl_term.c,v 1.79 2022/08/28 10:58:31 schwarze Exp $ */
/* $Id: tbl_term.c,v 1.81 2025/07/24 17:54:48 schwarze Exp $ */
/*
* Copyright (c) 2011-2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -39,23 +39,23 @@
static size_t term_tbl_len(size_t, void *);
static size_t term_tbl_strlen(const char *, void *);
static size_t term_tbl_sulen(const struct roffsu *, void *);
static void tbl_data(struct termp *, const struct tbl_opts *,
const struct tbl_cell *,
const struct tbl_dat *,
const struct roffcol *);
const struct roffcol *, size_t *);
static void tbl_direct_border(struct termp *, int, size_t);
static void tbl_fill_border(struct termp *, int, size_t);
static void tbl_fill_char(struct termp *, char, size_t);
static void tbl_fill_string(struct termp *, const char *, size_t);
static void tbl_fill_border(struct termp *, int, size_t *, size_t);
static void tbl_fill_char(struct termp *, char, size_t *, size_t);
static void tbl_fill_string(struct termp *, const char *,
size_t *, size_t);
static void tbl_hrule(struct termp *, const struct tbl_span *,
const struct tbl_span *, const struct tbl_span *,
int);
static void tbl_literal(struct termp *, const struct tbl_dat *,
const struct roffcol *);
const struct roffcol *, size_t *);
static void tbl_number(struct termp *, const struct tbl_opts *,
const struct tbl_dat *,
const struct roffcol *);
const struct roffcol *, size_t *);
static void tbl_word(struct termp *, const struct tbl_dat *);
@@ -139,15 +139,6 @@ static const int borders_ascii[81] = {
static const int *borders_locale;
static size_t
term_tbl_sulen(const struct roffsu *su, void *arg)
{
int i;
i = term_hen((const struct termp *)arg, su);
return i > 0 ? i : 0;
}
static size_t
term_tbl_strlen(const char *p, void *arg)
{
@@ -166,16 +157,29 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
{
const struct tbl_cell *cp, *cpn, *cpp, *cps;
const struct tbl_dat *dp;
static size_t offset;
size_t save_offset;
size_t coloff, tsz;
int hspans, ic, more;
int dvert, fc, horiz, lhori, rhori, uvert;
/* Positions and widths in basic units. */
static size_t offset; /* Of the table as a whole. */
size_t save_offset; /* Of the surrounding text. */
size_t coloff; /* Of this cell. */
size_t tsz; /* Total width of the table. */
size_t enw; /* Width of one EN unit. */
int ic; /* Column number. */
int hspans; /* Number of spans following this cell. */
int horiz; /* Boolean: this row only contains a line. */
int lhori; /* Number of horizontal lines pointing left. */
int rhori; /* Number of horizontal lines pointing right. */
int dvert; /* Number of vertical lines pointing down. */
int uvert; /* Number of vertical lines pointing up. */
int fc; /* Frame character index in borders_locale[]. */
int more; /* Boolean: there are more columns to print. */
/* Inhibit printing of spaces: we do padding ourselves. */
tp->flags |= TERMP_NOSPACE | TERMP_NONOSPACE;
save_offset = tp->tcol->offset;
enw = term_len(tp, 1);
/*
* The first time we're invoked for a given table block,
@@ -188,7 +192,6 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
tp->tbl.len = term_tbl_len;
tp->tbl.slen = term_tbl_strlen;
tp->tbl.sulen = term_tbl_sulen;
tp->tbl.arg = tp;
tblcalc(&tp->tbl, sp, tp->tcol->offset, tp->tcol->rmargin);
@@ -197,17 +200,36 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
offset = tp->tcol->offset;
if (sp->opts->opts & TBL_OPT_CENTRE) {
tsz = sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)
? 2 : !!sp->opts->lvert + !!sp->opts->rvert;
/*
* Vertical lines on the edges of the table make the
* table wider; take that into account for centering.
* The following assignment essentially says that a
* line on the right side occupies two columns (which
* matches reality) and a line on the left side three
* columns (which does not match reality; in fact,
* it only occupies two columns). But this is how
* groff does centering, so for compatibility, use
* the same numbers as groff.
*/
tsz = term_len(tp,
sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX) ?
5 : 3 * !!sp->opts->lvert + 2 * !!sp->opts->rvert);
/* Column widths and column spacing. */
for (ic = 0; ic + 1 < sp->opts->cols; ic++)
tsz += tp->tbl.cols[ic].width +
tp->tbl.cols[ic].spacing;
term_len(tp, tp->tbl.cols[ic].spacing);
if (sp->opts->cols)
tsz += tp->tbl.cols[sp->opts->cols - 1].width;
if (offset + tsz > tp->tcol->rmargin)
tsz -= 1;
tsz -= enw;
offset = offset + tp->tcol->rmargin > tsz ?
(offset + tp->tcol->rmargin - tsz) / 2 : 0;
((offset + tp->tcol->rmargin - tsz) / enw / 2) *
enw : 0;
tp->tcol->offset = offset;
}
@@ -239,7 +261,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
if (sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX) ||
sp->opts->lvert)
coloff++;
coloff += enw * 2;
tp->tcol->rmargin = coloff;
/* Set up the data columns. */
@@ -254,7 +276,8 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
coloff += tp->tbl.cols[ic].width;
tp->tcol->rmargin = coloff;
if (ic + 1 < sp->opts->cols)
coloff += tp->tbl.cols[ic].spacing;
coloff += term_len(tp,
tp->tbl.cols[ic].spacing);
if (hspans) {
hspans--;
continue;
@@ -269,7 +292,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
/* Set up a column for a right vertical frame. */
tp->tcol++;
tp->tcol->offset = coloff + 1;
tp->tcol->offset = coloff + enw;
tp->tcol->rmargin = tp->maxrmargin;
/* Spans may have reduced the number of columns. */
@@ -279,6 +302,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
/* Fill the buffers for all data columns. */
tp->tcol = tp->tcols;
coloff = tp->tcols[1].offset;
cp = cpn = sp->layout->first;
dp = sp->first;
hspans = 0;
@@ -294,7 +318,9 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
tp->tcol++;
tp->col = 0;
tp->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE);
tbl_data(tp, sp->opts, cp, dp, tp->tbl.cols + ic);
tbl_data(tp, sp->opts, cp, dp, tp->tbl.cols + ic,
&coloff);
coloff += term_len(tp, tp->tbl.cols[ic].spacing);
if (dp != NULL &&
(ic || sp->layout->first->pos != TBL_CELL_SPAN)) {
hspans = dp->hspans;
@@ -328,8 +354,8 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
fc = BUP * uvert + BDOWN * dvert + BRIGHT * rhori;
if (uvert > 0 || dvert > 0 || (horiz && sp->opts->lvert)) {
(*tp->advance)(tp, tp->tcols->offset);
tp->viscol = tp->tcol->offset;
tbl_direct_border(tp, fc, 1);
tbl_direct_border(tp, fc, enw);
tbl_direct_border(tp, BHORIZ * rhori, enw);
}
/* Print the data cells. */
@@ -348,6 +374,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
for (ic = 0; ic < sp->opts->cols; ic++) {
/*
* Handle horizontal alignment.
* Figure out whether to print a
* vertical line after this cell
* and advance to next layout cell.
@@ -362,6 +389,16 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
if (sp->pos == TBL_SPAN_DATA)
uvert = dvert = cps->vert;
switch (cp->pos) {
case TBL_CELL_CENTRE:
tp->flags |= TERMP_CENTER;
break;
case TBL_CELL_RIGHT:
tp->flags |= TERMP_RIGHT;
break;
case TBL_CELL_LONG:
if (hspans == 0)
tp->tcol->offset += enw;
break;
case TBL_CELL_HORIZ:
fc = BHORIZ;
break;
@@ -432,6 +469,9 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
tp->tcol++;
if (tp->tcol->col < tp->tcol->lastcol)
term_flushln(tp);
tp->flags &= ~(TERMP_CENTER | TERMP_RIGHT);
if (cp != NULL && cp->pos == TBL_CELL_LONG)
tp->tcol->offset -= enw;
if (tp->tcol->col < tp->tcol->lastcol)
more = 1;
@@ -451,15 +491,13 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
continue;
}
if (tp->viscol < tp->tcol->rmargin) {
(*tp->advance)(tp, tp->tcol->rmargin
- tp->viscol);
tp->viscol = tp->tcol->rmargin;
}
if (tp->viscol < tp->tcol->rmargin)
(*tp->advance)(tp,
tp->tcol->rmargin - tp->viscol);
while (tp->viscol < tp->tcol->rmargin +
tp->tbl.cols[ic].spacing / 2)
term_len(tp, tp->tbl.cols[ic].spacing / 2))
tbl_direct_border(tp,
BHORIZ * lhori, 1);
BHORIZ * lhori, enw);
if (tp->tcol + 1 == tp->tcols + tp->lasttcol)
continue;
@@ -479,7 +517,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
if (tp->tbl.cols[ic].spacing)
tbl_direct_border(tp,
BLEFT * lhori + BRIGHT * rhori +
BUP * uvert + BDOWN * dvert, 1);
BUP * uvert + BDOWN * dvert, enw);
if (tp->enc == TERMENC_UTF8)
uvert = dvert = 0;
@@ -489,7 +527,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
tbl_direct_border(tp,
BHORIZ * rhori +
BUP * (uvert > 1) +
BDOWN * (dvert > 1), 1);
BDOWN * (dvert > 1), enw);
}
}
@@ -528,15 +566,14 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
if (horiz == 0 && (IS_HORIZ(sp->layout->last) == 0 ||
sp->layout->last->col + 1 < sp->opts->cols)) {
tp->tcol++;
do {
if (tp->tcol->offset > tp->viscol)
tbl_direct_border(tp,
BHORIZ * lhori, 1);
} while (tp->viscol < tp->tcol->offset);
BHORIZ * lhori,
tp->tcol->offset - tp->viscol);
}
tbl_direct_border(tp, fc, 1);
tbl_direct_border(tp, fc, enw);
}
(*tp->endline)(tp);
tp->viscol = 0;
} while (more);
/*
@@ -575,6 +612,7 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
const struct tbl_cell *cpn; /* Layout cell below this line. */
const struct tbl_dat *dpn; /* Data cell below this line. */
const struct roffcol *col; /* Contains width and spacing. */
size_t enw; /* Width of one EN unit. */
int opts; /* For the table as a whole. */
int bw; /* Box line width. */
int hw; /* Horizontal line width. */
@@ -599,16 +637,19 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
/* Print the left end of the line. */
if (tp->viscol == 0) {
enw = term_len(tp, 1);
if (tp->viscol == 0)
(*tp->advance)(tp, tp->tcols->offset);
tp->viscol = tp->tcols->offset;
}
if (flags != 0)
if (flags != 0) {
tbl_direct_border(tp,
(spp == NULL ? 0 : BUP * bw) +
(spn == NULL ? 0 : BDOWN * bw) +
(spp == NULL || cpn == NULL ||
cpn->pos != TBL_CELL_DOWN ? BRIGHT * hw : 0), 1);
cpn->pos != TBL_CELL_DOWN ? BRIGHT * hw : 0), enw);
tbl_direct_border(tp,
(spp == NULL || cpn == NULL ||
cpn->pos != TBL_CELL_DOWN ? BHORIZ * hw : 0), enw);
}
col = tp->tbl.cols;
for (;;) {
@@ -625,7 +666,7 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
strcmp(dpn->string, "\\^") != 0))
? hw : 0;
tbl_direct_border(tp, BHORIZ * lw,
col->width + col->spacing / 2);
col->width + term_len(tp, col->spacing / 2));
/*
* Figure out whether a vertical line is crossing
@@ -678,7 +719,7 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
if (col->spacing)
tbl_direct_border(tp, BLEFT * lw +
BRIGHT * rw + BUP * uw + BDOWN * dw, 1);
BRIGHT * rw + BUP * uw + BDOWN * dw, enw);
/*
* In ASCII output, a crossing may print two characters.
@@ -688,13 +729,14 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
uw = dw = 0;
if (col->spacing > 2)
tbl_direct_border(tp,
BHORIZ * rw + BUP * uw + BDOWN * dw, 1);
BHORIZ * rw + BUP * uw + BDOWN * dw, enw);
/* Padding before the start of the next column. */
if (col->spacing > 4)
tbl_direct_border(tp,
BHORIZ * rw, (col->spacing - 3) / 2);
BHORIZ * rw,
term_len(tp, (col->spacing - 3) / 2));
}
/* Print the right end of the line. */
@@ -705,23 +747,22 @@ tbl_hrule(struct termp *tp, const struct tbl_span *spp,
(spn == NULL ? 0 : BDOWN * bw) +
(spp == NULL || spn == NULL ||
spn->layout->last->pos != TBL_CELL_DOWN ?
BLEFT * hw : 0), 1);
BLEFT * hw : 0), enw);
(*tp->endline)(tp);
tp->viscol = 0;
}
}
static void
tbl_data(struct termp *tp, const struct tbl_opts *opts,
const struct tbl_cell *cp, const struct tbl_dat *dp,
const struct roffcol *col)
const struct roffcol *col, size_t *coloff)
{
switch (cp->pos) {
case TBL_CELL_HORIZ:
tbl_fill_border(tp, BHORIZ, col->width);
tbl_fill_border(tp, BHORIZ, coloff, col->width);
return;
case TBL_CELL_DHORIZ:
tbl_fill_border(tp, BHORIZ * 2, col->width);
tbl_fill_border(tp, BHORIZ * 2, coloff, col->width);
return;
default:
break;
@@ -735,11 +776,11 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts,
return;
case TBL_DATA_HORIZ:
case TBL_DATA_NHORIZ:
tbl_fill_border(tp, BHORIZ, col->width);
tbl_fill_border(tp, BHORIZ, coloff, col->width);
return;
case TBL_DATA_NDHORIZ:
case TBL_DATA_DHORIZ:
tbl_fill_border(tp, BHORIZ * 2, col->width);
tbl_fill_border(tp, BHORIZ * 2, coloff, col->width);
return;
default:
break;
@@ -750,10 +791,10 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts,
case TBL_CELL_CENTRE:
case TBL_CELL_LEFT:
case TBL_CELL_RIGHT:
tbl_literal(tp, dp, col);
tbl_literal(tp, dp, col, coloff);
break;
case TBL_CELL_NUMBER:
tbl_number(tp, opts, dp, col);
tbl_number(tp, opts, dp, col, coloff);
break;
case TBL_CELL_DOWN:
case TBL_CELL_SPAN:
@@ -763,46 +804,72 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts,
}
}
/*
* Print multiple copies of the string cp to advance to
* len basic units from the left edge of the current column.
*/
static void
tbl_fill_string(struct termp *tp, const char *cp, size_t len)
tbl_fill_string(struct termp *tp, const char *cp, size_t *coloff, size_t len)
{
size_t i, sz;
size_t sz; /* Width of the string cp in basic units. */
size_t target; /* Distance from the left margin in basic units. */
if (len == 0)
return;
sz = term_strlen(tp, cp);
for (i = 0; i < len; i += sz)
target = tp->tcol->offset + len;
while (*coloff < target) {
term_word(tp, cp);
*coloff += sz;
}
}
/*
* Print multiple copies of the ASCII character c to advance to
* len basic units from the left edge of the current column.
*/
static void
tbl_fill_char(struct termp *tp, char c, size_t len)
tbl_fill_char(struct termp *tp, char c, size_t *coloff, size_t len)
{
char cp[2];
cp[0] = c;
cp[1] = '\0';
tbl_fill_string(tp, cp, len);
tbl_fill_string(tp, cp, coloff, len);
}
/*
* Print multiple copies of the border c to fill len basic units.
* Used for horizontal lines inside table cells.
*/
static void
tbl_fill_border(struct termp *tp, int c, size_t len)
tbl_fill_border(struct termp *tp, int c, size_t *coloff, size_t len)
{
char buf[12];
if ((c = borders_locale[c]) > 127) {
(void)snprintf(buf, sizeof(buf), "\\[u%04x]", c);
tbl_fill_string(tp, buf, len);
tbl_fill_string(tp, buf, coloff, len);
} else
tbl_fill_char(tp, c, len);
tbl_fill_char(tp, c, coloff, len);
}
/*
* The same, but bypassing term_flushln().
* Used for horizontal and vertical lines at the edges of table cells.
*/
static void
tbl_direct_border(struct termp *tp, int c, size_t len)
{
size_t i, sz;
size_t sz; /* Width of the character in basic units. */
size_t enw2; /* Width of half an EN in basic units. */
size_t target; /* Distance from the left margin in basic units. */
c = borders_locale[c];
sz = (*tp->width)(tp, c);
for (i = 0; i < len; i += sz) {
sz = (*tp->getwidth)(tp, c);
enw2 = (*tp->getwidth)(tp, ' ') / 2;
target = tp->viscol + len;
while (tp->viscol + enw2 < target) {
(*tp->letter)(tp, c);
tp->viscol += sz;
}
@@ -810,56 +877,36 @@ tbl_direct_border(struct termp *tp, int c, size_t len)
static void
tbl_literal(struct termp *tp, const struct tbl_dat *dp,
const struct roffcol *col)
const struct roffcol *col, size_t *coloff)
{
size_t len, padl, padr, width;
int ic, hspans;
size_t width; /* Of the cell including following spans [BU]. */
int ic; /* Column number of the cell. */
int hspans; /* Number of horizontal spans that follow. */
assert(dp->string);
len = term_strlen(tp, dp->string);
width = col->width;
ic = dp->layout->col;
hspans = dp->hspans;
while (hspans--) {
width += tp->tbl.cols[ic].spacing;
width += term_len(tp, tp->tbl.cols[ic].spacing);
ic++;
width += tp->tbl.cols[ic].width;
}
padr = width > len ? width - len : 0;
padl = 0;
switch (dp->layout->pos) {
case TBL_CELL_LONG:
padl = term_len(tp, 1);
padr = padr > padl ? padr - padl : 0;
break;
case TBL_CELL_CENTRE:
if (2 > padr)
break;
padl = padr / 2;
padr -= padl;
break;
case TBL_CELL_RIGHT:
padl = padr;
padr = 0;
break;
default:
break;
}
tbl_fill_char(tp, ASCII_NBRSP, padl);
tbl_word(tp, dp);
tbl_fill_char(tp, ASCII_NBRSP, padr);
*coloff += width;
}
static void
tbl_number(struct termp *tp, const struct tbl_opts *opts,
const struct tbl_dat *dp,
const struct roffcol *col)
const struct roffcol *col, size_t *coloff)
{
const char *cp, *lastdigit, *lastpoint;
size_t intsz, padl, totsz;
/* Widths in basic units. */
size_t pad; /* Padding before the number. */
size_t totsz; /* Of the number to be printed. */
size_t intsz; /* Of the integer part. */
char buf[2];
/*
@@ -883,7 +930,7 @@ tbl_number(struct termp *tp, const struct tbl_opts *opts,
/* Then measure both widths. */
padl = 0;
pad = 0;
totsz = term_strlen(tp, dp->string);
if (lastdigit != NULL) {
if (lastpoint == NULL)
@@ -901,23 +948,19 @@ tbl_number(struct termp *tp, const struct tbl_opts *opts,
*/
if (col->decimal > intsz && col->width > totsz) {
padl = col->decimal - intsz;
if (padl + totsz > col->width)
padl = col->width - totsz;
pad = col->decimal - intsz;
if (pad + totsz > col->width)
pad = col->width - totsz;
}
/* If it is not a number, simply center the string. */
} else if (col->width > totsz)
padl = (col->width - totsz) / 2;
pad = (col->width - totsz) / 2;
tbl_fill_char(tp, ASCII_NBRSP, padl);
tbl_fill_char(tp, ASCII_NBRSP, coloff, pad);
tbl_word(tp, dp);
/* Pad right to fill the column. */
if (col->width > padl + totsz)
tbl_fill_char(tp, ASCII_NBRSP, col->width - padl - totsz);
*coloff += col->width;
}
static void
+108 -93
View File
@@ -1,6 +1,6 @@
/* $Id: term.c,v 1.291 2023/04/28 19:11:04 schwarze Exp $ */
/* $Id: term.c,v 1.294 2025/08/01 14:59:39 schwarze Exp $ */
/*
* Copyright (c) 2010-2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -94,12 +94,15 @@ term_end(struct termp *p)
void
term_flushln(struct termp *p)
{
size_t vbl; /* Number of blanks to prepend to the output. */
/* Widths in basic units. */
size_t vbl; /* Whitespace to prepend to the output. */
size_t vbr; /* Actual visual position of the end of field. */
size_t vfield; /* Desired visual field width. */
size_t vtarget; /* Desired visual position of the right margin. */
size_t ic; /* Character position in the input buffer. */
size_t nbr; /* Number of characters to print in this field. */
/* Bytes. */
size_t ic; /* Byte index in the input buffer. */
size_t nbr; /* Number of bytes to print in this field. */
/*
* Normally, start writing at the left margin, but with the
@@ -108,8 +111,8 @@ term_flushln(struct termp *p)
vbl = (p->flags & TERMP_NOPAD) || p->tcol->offset < p->viscol ?
0 : p->tcol->offset - p->viscol;
if (p->minbl && vbl < p->minbl)
vbl = p->minbl;
if (p->minbl > 0 && vbl < term_len(p, p->minbl))
vbl = term_len(p, p->minbl);
if ((p->flags & TERMP_MULTICOL) == 0)
p->tcol->col = 0;
@@ -137,7 +140,7 @@ term_flushln(struct termp *p)
*/
term_fill(p, &nbr, &vbr,
p->flags & TERMP_BRNEVER ? SIZE_MAX : vtarget);
p->flags & TERMP_BRNEVER ? SIZE_MAX / 2 : vtarget);
if (nbr == 0)
break;
@@ -161,7 +164,7 @@ term_flushln(struct termp *p)
p->tcol->taboff += vbr;
else
p->tcol->taboff += vtarget;
p->tcol->taboff += (*p->width)(p, ' ');
p->tcol->taboff += term_len(p, 1);
/*
* If there is no text left in the field, exit the loop.
@@ -178,7 +181,7 @@ term_flushln(struct termp *p)
continue;
case ' ':
if (p->flags & TERMP_BRTRSP)
vbr += (*p->width)(p, ' ');
vbr += term_len(p, 1);
continue;
case '\n':
case ASCII_NBRZW:
@@ -245,13 +248,13 @@ term_flushln(struct termp *p)
if ((p->flags & TERMP_HANG) == 0 &&
((p->flags & TERMP_NOBREAK) == 0 ||
vbr + term_len(p, p->trailspace) > vfield))
vbr + term_len(p, p->trailspace) > vfield + term_len(p, 1) / 2))
endline(p);
}
/*
* Store the number of input characters to print in this field in *nbr
* and their total visual width to print in *vbr.
* Store the number of input bytes to print in this field in *nbr
* and their total visual width in basic units in *vbr.
* If there is only whitespace in the field, both remain zero.
* The desired visual width of the field is provided by vtarget.
* If the first word is longer, the field will be overrun.
@@ -259,28 +262,33 @@ term_flushln(struct termp *p)
static void
term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
{
size_t ic; /* Character position in the input buffer. */
/* Widths in basic units. */
size_t vis; /* Visual position of the current character. */
size_t vn; /* Visual position of the next character. */
size_t enw; /* Width of an EN unit. */
int taboff; /* Temporary offset for literal tabs. */
size_t ic; /* Byte index in the input buffer. */
int breakline; /* Break at the end of this word. */
int graph; /* Last character was non-blank. */
int taboff; /* Temporary offset for literal tabs. */
*nbr = *vbr = vis = 0;
breakline = graph = 0;
taboff = p->tcol->taboff;
enw = (*p->getwidth)(p, ' ');
vtarget += enw / 2;
for (ic = p->tcol->col; ic < p->tcol->lastcol; ic++) {
switch (p->tcol->buf[ic]) {
case '\b': /* Escape \o (overstrike) or backspace markup. */
assert(ic > 0);
vis -= (*p->width)(p, p->tcol->buf[ic - 1]);
vis -= (*p->getwidth)(p, p->tcol->buf[ic - 1]);
continue;
case ' ':
case ASCII_BREAK: /* Escape \: (breakpoint). */
vn = vis;
if (p->tcol->buf[ic] == ' ')
vn += (*p->width)(p, ' ');
vn += enw;
/* Can break at the end of a word. */
if (breakline || vn > vtarget)
break;
@@ -305,7 +313,7 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
* hyphen such that we get the correct width.
*/
p->tcol->buf[ic] = '-';
vis += (*p->width)(p, '-');
vis += (*p->getwidth)(p, '-');
if (vis > vtarget) {
ic++;
break;
@@ -315,7 +323,7 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
continue;
case ASCII_TABREF:
taboff = -vis - (*p->width)(p, ' ');
taboff = -vis - enw;
continue;
default:
@@ -334,7 +342,7 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
p->tcol->buf[ic] = ' ';
/* FALLTHROUGH */
default: /* Printable character. */
vis += (*p->width)(p, p->tcol->buf[ic]);
vis += (*p->getwidth)(p, p->tcol->buf[ic]);
break;
}
graph = 1;
@@ -359,18 +367,20 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
/*
* Print the contents of one field
* with an indentation of vbl visual columns,
* and an input string length of nbr characters.
* with an indentation of vbl basic units
* and an input string length of nbr bytes.
*/
static void
term_field(struct termp *p, size_t vbl, size_t nbr)
{
size_t ic; /* Character position in the input buffer. */
/* Widths in basic units. */
size_t vis; /* Visual position of the current character. */
size_t vt; /* Visual position including tab offset. */
size_t dv; /* Visual width of the current character. */
int taboff; /* Temporary offset for literal tabs. */
size_t ic; /* Byte position in the input buffer. */
vis = 0;
taboff = p->tcol->taboff;
for (ic = p->tcol->col; ic < nbr; ic++) {
@@ -386,7 +396,7 @@ term_field(struct termp *p, size_t vbl, size_t nbr)
case ASCII_NBRZW:
continue;
case ASCII_TABREF:
taboff = -vis - (*p->width)(p, ' ');
taboff = -vis - (*p->getwidth)(p, ' ');
continue;
case '\t':
case ' ':
@@ -398,7 +408,7 @@ term_field(struct termp *p, size_t vbl, size_t nbr)
vt = vis + taboff;
dv = term_tab_next(vt) - vt;
} else
dv = (*p->width)(p, ' ');
dv = (*p->getwidth)(p, ' ');
vbl += dv;
vis += dv;
continue;
@@ -413,7 +423,6 @@ term_field(struct termp *p, size_t vbl, size_t nbr)
if (vbl > 0) {
(*p->advance)(p, vbl);
p->viscol += vbl;
vbl = 0;
}
@@ -421,11 +430,11 @@ term_field(struct termp *p, size_t vbl, size_t nbr)
(*p->letter)(p, p->tcol->buf[ic]);
if (p->tcol->buf[ic] == '\b') {
dv = (*p->width)(p, p->tcol->buf[ic - 1]);
dv = (*p->getwidth)(p, p->tcol->buf[ic - 1]);
p->viscol -= dv;
vis -= dv;
} else {
dv = (*p->width)(p, p->tcol->buf[ic]);
dv = (*p->getwidth)(p, p->tcol->buf[ic]);
p->viscol += dv;
vis += dv;
}
@@ -433,6 +442,10 @@ term_field(struct termp *p, size_t vbl, size_t nbr)
p->tcol->col = nbr;
}
/*
* Print the margin character, if one is configured,
* and end the output line.
*/
static void
endline(struct termp *p)
{
@@ -441,14 +454,13 @@ endline(struct termp *p)
p->flags &= ~TERMP_ENDMC;
}
if (p->mc != NULL) {
if (p->viscol && p->maxrmargin >= p->viscol)
(*p->advance)(p, p->maxrmargin - p->viscol + 1);
if (p->viscol > 0 && p->viscol <= p->maxrmargin)
(*p->advance)(p,
p->maxrmargin - p->viscol + term_len(p, 1));
p->flags |= TERMP_NOBUF | TERMP_NOSPACE;
term_word(p, p->mc);
p->flags &= ~(TERMP_NOBUF | TERMP_NEWMC);
}
p->viscol = 0;
p->minbl = 0;
(*p->endline)(p);
}
@@ -477,8 +489,6 @@ term_vspace(struct termp *p)
{
term_newln(p);
p->viscol = 0;
p->minbl = 0;
if (0 < p->skipvsp)
p->skipvsp--;
else
@@ -496,34 +506,36 @@ term_fontlast(struct termp *p)
p->fontq[p->fonti] = f;
}
/* Set font, save current, discard previous; for \f, .ft, .B etc. */
/* Set font, save current, discard previous; for \f, .ft, and man(7). */
void
term_fontrepl(struct termp *p, enum termfont f)
{
p->fontl = p->fontq[p->fonti];
if (p->fontibi && f == TERMFONT_UNDER)
f = TERMFONT_BI;
p->fontq[p->fonti] = f;
}
/* Set font, save previous. */
/* Set font, save previous; for mdoc(7), eqn(7), and tbl(7). */
void
term_fontpush(struct termp *p, enum termfont f)
{
enum termfont fl;
p->fontl = p->fontq[p->fonti];
fl = p->fontq[p->fonti];
if (++p->fonti == p->fontsz) {
p->fontsz += 8;
p->fontq = mandoc_reallocarray(p->fontq,
p->fontsz, sizeof(*p->fontq));
}
p->fontq[p->fonti] = f;
p->fontq[p->fonti] = fl;
term_fontrepl(p, f);
}
/* Flush to make the saved pointer current again. */
void
term_fontpopq(struct termp *p, int i)
{
assert(i >= 0);
if (p->fonti > i)
p->fonti = i;
@@ -533,8 +545,7 @@ term_fontpopq(struct termp *p, int i)
void
term_fontpop(struct termp *p)
{
assert(p->fonti);
assert(p->fonti > 0);
p->fonti--;
}
@@ -548,9 +559,14 @@ term_word(struct termp *p, const char *word)
{
struct roffsu su;
const char nbrsp[2] = { ASCII_NBRSP, 0 };
const char *seq, *cp;
int sz, uc;
size_t csz, lsz, ssz;
const char *seq; /* Escape sequence argument. */
const char *cp; /* String to be printed. */
size_t csz; /* String length in basic units. */
size_t lsz; /* Line width in basic units. */
size_t ssz; /* Substring length in bytes. */
int sz; /* Argument length in bytes. */
int uc; /* Unicode codepoint number. */
int bu; /* Width in basic units. */
enum mandoc_esc esc;
if ((p->flags & TERMP_NOBUF) == 0) {
@@ -663,15 +679,15 @@ term_word(struct termp *p, const char *word)
}
if (*seq == '|') {
seq++;
uc = -p->col;
bu = -term_len(p, p->col);
} else
uc = 0;
bu = 0;
if (a2roffsu(seq, &su, SCALE_EM) == NULL)
continue;
uc += term_hen(p, &su);
if (uc >= 0) {
while (uc > 0) {
uc -= term_len(p, 1);
bu += term_hspan(p, &su);
if (bu >= 0) {
while (bu > 0) {
bu -= term_len(p, 1);
if (p->flags & TERMP_BACKBEFORE)
p->flags &= ~TERMP_BACKBEFORE;
else
@@ -681,17 +697,17 @@ term_word(struct termp *p, const char *word)
}
if (p->flags & TERMP_BACKBEFORE) {
p->flags &= ~TERMP_BACKBEFORE;
assert(p->col > 0);
assert(p->col > 1);
p->col--;
}
if (p->col >= (size_t)(-uc)) {
p->col += uc;
if (term_len(p, p->col) >= (size_t)(-bu)) {
p->col -= -bu / term_len(p, 1);
} else {
uc += p->col;
bu += term_len(p, p->col);
p->col = 0;
if (p->tcol->offset > (size_t)(-uc)) {
p->ti += uc;
p->tcol->offset += uc;
if (p->tcol->offset > (size_t)(-bu)) {
p->ti += bu;
p->tcol->offset += bu;
} else {
p->ti -= p->tcol->offset;
p->tcol->offset = 0;
@@ -701,13 +717,13 @@ term_word(struct termp *p, const char *word)
case ESCAPE_HLINE:
if ((cp = a2roffsu(seq, &su, SCALE_EM)) == NULL)
continue;
uc = term_hen(p, &su);
if (uc <= 0) {
bu = term_hspan(p, &su);
if (bu <= 0) {
if (p->tcol->rmargin <= p->tcol->offset)
continue;
lsz = p->tcol->rmargin - p->tcol->offset;
} else
lsz = uc;
lsz = bu;
if (*cp == seq[-1])
uc = -1;
else if (*cp == '\\') {
@@ -739,13 +755,16 @@ term_word(struct termp *p, const char *word)
csz = term_strlen(p, cp);
ssz = strlen(cp);
} else
csz = (*p->width)(p, uc);
while (lsz >= csz) {
csz = (*p->getwidth)(p, uc);
while (lsz > 0) {
if (p->enc == TERMENC_ASCII)
encode(p, cp, ssz);
else
encode1(p, uc);
lsz -= csz;
if (lsz > csz)
lsz -= csz;
else
lsz = 0;
}
continue;
case ESCAPE_SKIPCHAR:
@@ -954,28 +973,39 @@ term_setwidth(struct termp *p, const char *wstr)
size_t
term_len(const struct termp *p, size_t sz)
{
return (*p->width)(p, ' ') * sz;
return (*p->getwidth)(p, ' ') * sz;
}
static size_t
cond_width(const struct termp *p, int c, int *skip)
{
if (*skip) {
(*skip) = 0;
return 0;
} else
return (*p->width)(p, c);
return (*p->getwidth)(p, c);
}
size_t
term_strlen(const struct termp *p, const char *cp)
{
size_t sz, rsz, i;
int ssz, skip, uc;
const char *seq, *rhs;
const char *seq; /* Escape sequence argument. */
const char *rhs; /* String to be printed. */
/* Widths in basic units. */
size_t sz; /* Return value. */
size_t this_sz; /* Individual char for overstrike. */
size_t max_sz; /* Result of overstrike. */
/* Numbers of bytes. */
size_t rsz; /* Substring length in bytes. */
size_t i; /* Byte index in substring. */
int ssz; /* Argument length in bytes. */
int skip; /* Number of bytes to skip. */
int uc; /* Unicode codepoint number. */
enum mandoc_esc esc;
static const char rej[] = { '\\', ASCII_NBRSP, ASCII_NBRZW,
ASCII_BREAK, ASCII_HYPH, ASCII_TABREF, '\0' };
@@ -1039,18 +1069,18 @@ term_strlen(const struct termp *p, const char *cp)
skip = 1;
continue;
case ESCAPE_OVERSTRIKE:
rsz = 0;
max_sz = 0;
rhs = seq + ssz;
while (seq < rhs) {
if (*seq == '\\') {
mandoc_escape(&seq, NULL, NULL);
continue;
}
i = (*p->width)(p, *seq++);
if (rsz < i)
rsz = i;
this_sz = (*p->getwidth)(p, *seq++);
if (max_sz < this_sz)
max_sz = this_sz;
}
sz += rsz;
sz += max_sz;
continue;
default:
continue;
@@ -1085,7 +1115,7 @@ term_strlen(const struct termp *p, const char *cp)
*/
for (i = 0; i < rsz; i++)
sz += (*p->width)(p, *rhs++);
sz += (*p->getwidth)(p, *rhs++);
break;
case ASCII_NBRSP:
sz += cond_width(p, ' ', &skip);
@@ -1146,25 +1176,10 @@ term_vspan(const struct termp *p, const struct roffsu *su)
}
/*
* Convert a scaling width to basic units, rounding towards 0.
* Convert a scaling width to basic units.
*/
int
term_hspan(const struct termp *p, const struct roffsu *su)
{
return (*p->hspan)(p, su);
}
/*
* Convert a scaling width to basic units, rounding to closest.
*/
int
term_hen(const struct termp *p, const struct roffsu *su)
{
int bu;
if ((bu = (*p->hspan)(p, su)) >= 0)
return (bu + 11) / 24;
else
return -((-bu + 11) / 24);
}
+16 -22
View File
@@ -1,6 +1,7 @@
/* $Id: term.h,v 1.134 2022/08/16 17:45:55 schwarze Exp $ */
/* $Id: term.h,v 1.138 2025/07/27 15:27:28 schwarze Exp $ */
/*
* Copyright (c) 2011-2015,2017,2019,2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011-2015, 2017, 2019, 2021, 2022, 2025
* Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -44,19 +45,14 @@ struct termp;
typedef void (*term_margin)(struct termp *, const struct roff_meta *);
struct termp_tbl {
int width; /* width in fixed chars */
int decimal; /* decimal point position */
};
struct termp_col {
int *buf; /* Output buffer. */
size_t maxcols; /* Allocated bytes in buf. */
size_t lastcol; /* Last byte in buf. */
size_t col; /* Byte in buf to be written. */
size_t rmargin; /* Current right margin. */
size_t offset; /* Current left margin. */
size_t taboff; /* Offset for literal tabs. */
size_t rmargin; /* Current right margin [BU]. */
size_t offset; /* Current left margin [BU]. */
size_t taboff; /* Offset for literal tabs [BU]. */
};
struct termp {
@@ -66,17 +62,16 @@ struct termp {
size_t maxtcol; /* Allocated table columns. */
size_t lasttcol; /* Last column currently used. */
size_t line; /* Current output line number. */
size_t defindent; /* Default indent for text. */
size_t defrmargin; /* Right margin of the device. */
size_t lastrmargin; /* Right margin before the last ll. */
size_t maxrmargin; /* Max right margin. */
size_t defindent; /* Default indent for text [EN]. */
size_t defrmargin; /* Right margin of the device [BU]. */
size_t lastrmargin; /* Right margin before last ll [BU]. */
size_t maxrmargin; /* Maximum right margin [BU]. */
size_t col; /* Byte position in buf. */
size_t viscol; /* Chars on current line. */
size_t trailspace; /* See term_flushln(). */
size_t minbl; /* Minimum blanks before next field. */
size_t viscol; /* Width of the current line [BU]. */
size_t trailspace; /* Whitespace after field [EN]. */
size_t minbl; /* Whitespace before field [EN]. */
int synopsisonly; /* Print the synopsis only. */
int mdocstyle; /* Imitate mdoc(7) output. */
int ti; /* Temporary indent for one line. */
int ti; /* Temporary indent for line [BU]. */
int skipvsp; /* Vertical space to skip. */
int flags;
#define TERMP_SENTENCE (1 << 0) /* Space before a sentence. */
@@ -108,6 +103,7 @@ struct termp {
enum termfont *fontq; /* Symmetric fonts. */
int fontsz; /* Allocated size of font stack */
int fonti; /* Index of font stack. */
int fontibi; /* Map font I to BI. */
term_margin headf; /* invoked to print head */
term_margin footf; /* invoked to print foot */
void (*letter)(struct termp *, int);
@@ -116,7 +112,7 @@ struct termp {
void (*endline)(struct termp *);
void (*advance)(struct termp *, size_t);
void (*setwidth)(struct termp *, int, int);
size_t (*width)(const struct termp *, int);
size_t (*getwidth)(const struct termp *, int);
int (*hspan)(const struct termp *,
const struct roffsu *);
const void *argf; /* arg for headf/footf */
@@ -143,13 +139,11 @@ void term_end(struct termp *);
void term_setwidth(struct termp *, const char *);
int term_hspan(const struct termp *, const struct roffsu *);
int term_hen(const struct termp *, const struct roffsu *);
int term_vspan(const struct termp *, const struct roffsu *);
size_t term_strlen(const struct termp *, const char *);
size_t term_len(const struct termp *, size_t);
void term_tab_set(const struct termp *, const char *);
void term_tab_iset(size_t);
void term_tab_ref(struct termp *);
size_t term_tab_next(size_t);
void term_tab_free(void);
+51 -40
View File
@@ -1,7 +1,7 @@
/* $Id: term_ascii.c,v 1.69 2023/11/13 19:13:01 schwarze Exp $ */
/* $Id: term_ascii.c,v 1.71 2025/07/16 14:33:08 schwarze Exp $ */
/*
* Copyright (c) 2014,2015,2017-2020,2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014,2015,2017,2018,2020 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -43,7 +43,7 @@
static struct termp *ascii_init(enum termenc, const struct manoutput *);
static int ascii_hspan(const struct termp *,
const struct roffsu *);
static size_t ascii_width(const struct termp *, int);
static size_t ascii_getwidth(const struct termp *, int);
static void ascii_advance(struct termp *, size_t);
static void ascii_begin(struct termp *);
static void ascii_end(struct termp *);
@@ -55,7 +55,7 @@ static void ascii_setwidth(struct termp *, int, int);
static void locale_advance(struct termp *, size_t);
static void locale_endline(struct termp *);
static void locale_letter(struct termp *, int);
static size_t locale_width(const struct termp *, int);
static size_t locale_getwidth(const struct termp *, int);
#endif
@@ -73,7 +73,6 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
p->line = 1;
p->defindent = 5;
p->defrmargin = p->lastrmargin = 78;
p->fontq = mandoc_reallocarray(NULL,
(p->fontsz = 8), sizeof(*p->fontq));
p->fontq[0] = p->fontl = TERMFONT_NONE;
@@ -82,13 +81,12 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
p->end = ascii_end;
p->hspan = ascii_hspan;
p->type = TERMTYPE_CHAR;
p->enc = TERMENC_ASCII;
p->advance = ascii_advance;
p->endline = ascii_endline;
p->letter = ascii_letter;
p->setwidth = ascii_setwidth;
p->width = ascii_width;
p->getwidth = ascii_getwidth;
#if HAVE_WCHAR
if (enc != TERMENC_ASCII) {
@@ -118,17 +116,15 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
p->advance = locale_advance;
p->endline = locale_endline;
p->letter = locale_letter;
p->width = locale_width;
p->getwidth = locale_getwidth;
}
}
#endif
p->defrmargin = term_len(p, outopts->width ? outopts->width : 78);
p->lastrmargin = p->defrmargin;
if (outopts->mdoc)
p->mdocstyle = 1;
if (outopts->indent)
p->defindent = outopts->indent;
if (outopts->width)
p->defrmargin = outopts->width;
if (outopts->synopsisonly)
p->synopsisonly = 1;
@@ -140,29 +136,24 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
void *
ascii_alloc(const struct manoutput *outopts)
{
return ascii_init(TERMENC_ASCII, outopts);
}
void *
utf8_alloc(const struct manoutput *outopts)
{
return ascii_init(TERMENC_UTF8, outopts);
}
void *
locale_alloc(const struct manoutput *outopts)
{
return ascii_init(TERMENC_LOCALE, outopts);
}
static void
ascii_setwidth(struct termp *p, int iop, int width)
{
width /= 24;
p->tcol->rmargin = p->defrmargin;
if (iop > 0)
p->defrmargin += width;
@@ -172,8 +163,8 @@ ascii_setwidth(struct termp *p, int iop, int width)
p->defrmargin -= width;
else
p->defrmargin = 0;
if (p->defrmargin > 1000)
p->defrmargin = 1000;
if (p->defrmargin > term_len(p, 1000))
p->defrmargin = term_len(p, 1000);
p->lastrmargin = p->tcol->rmargin;
p->tcol->rmargin = p->maxrmargin = p->defrmargin;
}
@@ -182,67 +173,76 @@ void
terminal_sepline(void *arg)
{
struct termp *p;
size_t i;
size_t i; /* Printed width in basic units. */
size_t sz; /* Width of a dash in basic units. */
p = (struct termp *)arg;
(*p->endline)(p);
for (i = 0; i < p->defrmargin; i++)
sz = (*p->getwidth)(p, '-');
for (i = 0; i < p->defrmargin; i += sz)
(*p->letter)(p, '-');
(*p->endline)(p);
(*p->endline)(p);
}
static size_t
ascii_width(const struct termp *p, int c)
ascii_getwidth(const struct termp *p, int c)
{
return c != ASCII_BREAK && c != ASCII_NBRZW && c != ASCII_TABREF;
switch (c) {
case ASCII_BREAK:
case ASCII_NBRZW:
case ASCII_TABREF:
return 0;
default:
return 24;
}
}
void
ascii_free(void *arg)
{
term_free((struct termp *)arg);
}
static void
ascii_letter(struct termp *p, int c)
{
putchar(c);
}
static void
ascii_begin(struct termp *p)
{
(*p->headf)(p, p->argf);
}
static void
ascii_end(struct termp *p)
{
(*p->footf)(p, p->argf);
}
static void
ascii_endline(struct termp *p)
{
p->line++;
if ((int)p->tcol->offset > p->ti)
p->tcol->offset -= p->ti;
else
p->tcol->offset = 0;
p->ti = 0;
p->minbl = 0;
p->viscol = 0;
putchar('\n');
}
static void
ascii_advance(struct termp *p, size_t len)
{
size_t i;
size_t dst; /* Destination column in basic units. */
size_t sz; /* Width of a space in basic units. */
sz = (*p->getwidth)(p, ' ');
/*
* XXX We used to have "assert(len < UINT16_MAX)" here.
@@ -250,10 +250,14 @@ ascii_advance(struct termp *p, size_t len)
* can trigger that by merely providing large input.
* For now, simply truncate.
*/
if (len > 256)
len = 256;
for (i = 0; i < len; i++)
if (len > 256 * sz)
len = 256 * sz;
dst = p->viscol + len;
while (p->viscol + sz / 2 < dst) {
putchar(' ');
p->viscol += sz;
}
}
static int
@@ -372,7 +376,7 @@ ascii_uc2str(int uc)
#if HAVE_WCHAR
static size_t
locale_width(const struct termp *p, int c)
locale_getwidth(const struct termp *p, int c)
{
int rc;
@@ -381,13 +385,16 @@ locale_width(const struct termp *p, int c)
rc = wcwidth(c);
if (rc < 0)
rc = 0;
return rc;
return rc * 24;
}
static void
locale_advance(struct termp *p, size_t len)
{
size_t i;
size_t dst; /* Destination column in basic units. */
size_t sz; /* Width of a space in basic units. */
sz = (*p->getwidth)(p, ' ');
/*
* XXX We used to have "assert(len < UINT16_MAX)" here.
@@ -395,29 +402,33 @@ locale_advance(struct termp *p, size_t len)
* can trigger that by merely providing large input.
* For now, simply truncate.
*/
if (len > 256)
len = 256;
for (i = 0; i < len; i++)
if (len > 256 * sz)
len = 256 * sz;
dst = p->viscol + len;
while (p->viscol + sz / 2 < dst) {
putwchar(L' ');
p->viscol += sz;
}
}
static void
locale_endline(struct termp *p)
{
p->line++;
if ((int)p->tcol->offset > p->ti)
p->tcol->offset -= p->ti;
else
p->tcol->offset = 0;
p->ti = 0;
p->minbl = 0;
p->viscol = 0;
putwchar(L'\n');
}
static void
locale_letter(struct termp *p, int c)
{
putwchar(c);
}
#endif
+10 -8
View File
@@ -1,7 +1,7 @@
/* $Id: term_ps.c,v 1.92 2020/09/06 14:45:22 schwarze Exp $ */
/* $Id: term_ps.c,v 1.95 2025/09/26 12:17:12 schwarze Exp $ */
/*
* Copyright (c) 2014-2017, 2020, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014,2015,2016,2017,2020 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2017 Marc Espie <espie@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -95,7 +95,7 @@ struct termp_ps {
static int ps_hspan(const struct termp *,
const struct roffsu *);
static size_t ps_width(const struct termp *, int);
static size_t ps_getwidth(const struct termp *, int);
static void ps_advance(struct termp *, size_t);
static void ps_begin(struct termp *);
static void ps_closepage(struct termp *);
@@ -549,7 +549,7 @@ pspdf_alloc(const struct manoutput *outopts, enum termtype type)
p->hspan = ps_hspan;
p->letter = ps_letter;
p->setwidth = ps_setwidth;
p->width = ps_width;
p->getwidth = ps_getwidth;
/* Default to US letter (millimetres). */
@@ -1211,6 +1211,7 @@ ps_advance(struct termp *p, size_t len)
ps_plast(p);
ps_pclose(p);
p->ps->pscol += len;
p->viscol += len;
}
static void
@@ -1221,6 +1222,8 @@ ps_endline(struct termp *p)
ps_plast(p);
ps_pclose(p);
p->viscol = 0;
p->minbl = 0;
/*
* If we're in the margin, don't try to recalculate our current
@@ -1282,7 +1285,7 @@ ps_setfont(struct termp *p, enum termfont f)
}
static size_t
ps_width(const struct termp *p, int c)
ps_getwidth(const struct termp *p, int c)
{
if (c <= 32 || c - 32 >= MAXCHAR)
@@ -1311,7 +1314,7 @@ ps_hspan(const struct termp *p, const struct roffsu *su)
* scaling unit so that output is the same regardless
* the media.
*/
r = PNT2AFM(p, su->scale * 72.0 / 240.0);
r = PNT2AFM(p, su->scale * 72.0 / 10.0);
break;
case SCALE_CM:
r = PNT2AFM(p, su->scale * 72.0 / 2.54);
@@ -1344,8 +1347,7 @@ ps_hspan(const struct termp *p, const struct roffsu *su)
r = su->scale;
break;
}
return r * 24.0;
return r;
}
static void
+6 -21
View File
@@ -1,6 +1,6 @@
/* $Id: term_tab.c,v 1.7 2021/10/04 18:56:31 schwarze Exp $ */
/* $Id: term_tab.c,v 1.9 2025/07/16 14:33:08 schwarze Exp $ */
/*
* Copyright (c) 2017, 2021 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2017, 2021, 2025 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,7 +27,7 @@
#include "term.h"
struct tablist {
size_t *t; /* Allocated array of tab positions. */
size_t *t; /* Allocated array of tab positions [BU]. */
size_t s; /* Allocated number of positions. */
size_t n; /* Currently used number of positions. */
};
@@ -36,7 +36,7 @@ static struct {
struct tablist a; /* All tab positions for lookup. */
struct tablist p; /* Periodic tab positions to add. */
struct tablist *r; /* Tablist currently being recorded. */
size_t d; /* Default tab width in units of n. */
size_t d; /* Default tab width in basic units. */
} tabs;
@@ -55,7 +55,7 @@ term_tab_set(const struct termp *p, const char *arg)
tabs.r = &tabs.a;
if (tabs.d == 0) {
a2roffsu(".8i", &su, SCALE_IN);
tabs.d = term_hen(p, &su);
tabs.d = term_hspan(p, &su);
}
return;
}
@@ -84,28 +84,13 @@ term_tab_set(const struct termp *p, const char *arg)
/* Append the new position. */
pos = term_hen(p, &su);
pos = term_hspan(p, &su);
tl->t[tl->n] = pos;
if (add && tl->n)
tl->t[tl->n] += tl->t[tl->n - 1];
tl->n++;
}
/*
* Simplified version without a parser,
* never incremental, never periodic, for use by tbl(7).
*/
void
term_tab_iset(size_t inc)
{
if (tabs.a.n >= tabs.a.s) {
tabs.a.s += 8;
tabs.a.t = mandoc_reallocarray(tabs.a.t, tabs.a.s,
sizeof(*tabs.a.t));
}
tabs.a.t[tabs.a.n++] = inc;
}
size_t
term_tab_next(size_t prev)
{
@@ -0,0 +1,375 @@
/* $NetBSD$ */
/*-
* Copyright (c) 2025 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* iconv(3)
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: t_mbrtoc8.c,v 1.3 2024/08/20 17:43:09 riastradh Exp $");
#include <atf-c.h>
#include <errno.h>
#include <iconv.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "h_macros.h"
static const struct sample {
const char *src_codeset;
size_t nsrc;
const char *src;
const char *dst_codeset;
size_t ndst;
const char *dst;
size_t ninval;
size_t ninval_rev;
const char *xfail;
#define IRREVERSIBLE ((size_t)-1)
} samples[] = {
[0] = { "us-ascii", 6, "hello",
"us-ascii", 6, "hello",
0, 0, NULL },
/* LATIN SMALL LETTER E WITH ACUTE ACCENT */
[1] = { "iso-8859-1", 1, (const char[1]){0xe9},
"UTF-8", 2, (const char[2]){0xc3,0xa9},
0, 0, NULL },
/* LEFT CURLY BRACKET */
[2] = { "UTF-8", 2, (const char[2]){0x00,0x7b},
"ZW", 6, (const char[6]){0x00,0x7a,0x57,0x20,0x7b,0x0a},
0, 0, NULL },
/* LATIN SMALL LETTER O, TILDE */
[3] = { "UTF-8", 2, (const char[2]){0x4f,0x7e},
"VIQR", 3, (const char[3]){0x4f,0x5c,0x7e},
0, 0, NULL },
/* LEFT CURLY BRACKET (optionally encoded in UTF-7) */
[4] = { "UTF-7", 1, (const char[1]){0x7b},
"UTF-8", 1, (const char[1]){0x7b},
0, IRREVERSIBLE, NULL },
[5] = { "UTF-7", 4, "+AHs-",
"UTF-8", 1, (const char[1]){0x7b},
0, 0, NULL },
/* éclair */
[6] = { "UTF-7", 10, "+AOk-clair",
"UTF-8", 7, (const char[7]){
0xc3,0xa9,0x63,0x6c,0x61,0x69,0x72,
},
0, 0, NULL },
[7] = { "HZ", 55, /* RFC 1843, Sec. 4, Example 1 */
"The next sentence is in GB.~{<:Ky2;S{#,NpJ)l6HK!#~}Bye.",
"UTF-8", 61, (const char[61]) {
0x54,0x68,0x65,0x20, 0x6e,0x65,0x78,0x74,
0x20,0x73,0x65,0x6e, 0x74,0x65,0x6e,0x63,
0x65,0x20,0x69,0x73, 0x20,0x69,0x6e,0x20,
0x47,0x42,0x2e,0xe5, 0xb7,0xb1,0xe6,0x89,
0x80,0xe4,0xb8,0x8d, 0xe6,0xac,0xb2,0xef,
0xbc,0x8c,0xe5,0x8b, 0xbf,0xe6,0x96,0xbd,
0xe6,0x96,0xbc,0xe4, 0xba,0xba,0xe3,0x80,
0x82,0x42,0x79,0x65, 0x2e
},
0, 0, NULL },
/* Same as above but with HZ8 instead of HZ. */
[8] = { "HZ8", 55, (const char[55]) {
0x54,0x68,0x65,0x20,0x6e,0x65,0x78,0x74,
0x20,0x73,0x65,0x6e,0x74,0x65,0x6e,0x63,
0x65,0x20,0x69,0x73,0x20,0x69,0x6e,0x20,
0x47,0x42,0x2e,0x7e,0x7b,0xbc,0xba,0xcb,
0xf9,0xb2,0xbb,0xd3,0xfb,0xa3,0xac,0xce,
0xf0,0xca,0xa9,0xec,0xb6,0xc8,0xcb,0xa1,
0xa3,0x7e,0x7d,0x42,0x79,0x65,0x2e
},
"UTF-8", 61, (const char[61]) {
0x54,0x68,0x65,0x20, 0x6e,0x65,0x78,0x74,
0x20,0x73,0x65,0x6e, 0x74,0x65,0x6e,0x63,
0x65,0x20,0x69,0x73, 0x20,0x69,0x6e,0x20,
0x47,0x42,0x2e,0xe5, 0xb7,0xb1,0xe6,0x89,
0x80,0xe4,0xb8,0x8d, 0xe6,0xac,0xb2,0xef,
0xbc,0x8c,0xe5,0x8b, 0xbf,0xe6,0x96,0xbd,
0xe6,0x96,0xbc,0xe4, 0xba,0xba,0xe3,0x80,
0x82,0x42,0x79,0x65, 0x2e
},
0, 0, NULL },
/* 馬 from CNS 11643-1 */
[9] = { "UTF-8", 3, (const char[3]){0xe9,0xa6,0xac},
"ISO-2022-CN", 8,
(const char[8]){0x1b,0x24,0x29,0x47,0x0e,0x58,0x6b,0x0f},
0, 0, NULL },
/* 馬毦 shifting from CNS 11643-1 to CNS 11643-2 */
[10] = { "UTF-8", 6, (const char[6]){0xe9,0xa6,0xac,0xe6,0xaf,0xa6},
"ISO-2022-CN", 16,
(const char[16]){
/* ESC $ ) G (shift G1 to CNS 11643 plane 1) */
0x1b,0x24,0x29,0x47,
0x0e, /* GL is G1 from now on */
0x58,0x6b, /* 馬 */
/* ESC $ * H (shift G2 to CNS 11643 plane 2) */
0x1b,0x24,0x2a,0x48,
0x1b,0x4e, /* GL is G2 for next char */
0x30,0x21, /* 毦 */
0x0f, /* GL is G0 from now on */
},
0, 0, "PR lib/59019: various iconv issues ([case 10: ISO-2022-CN to UTF-8 14/6] iconv: Illegal byte sequence (85))" },
};
#ifdef MIN
#undef MIN
#endif
#define MIN(x, y) ((x) < (y) ? (x) : (y))
static void
test_sample_bounded(const char *title, const struct sample *S,
size_t nsrc, size_t ndst)
{
char inbuf[4096], inguard = arc4random();
char outbuf[4096], outguard = arc4random();
iconv_t C;
char *src0, *src, *dst0, *dst;
size_t srcleft0, srcleft, dstleft0, dstleft;
size_t ninval;
int error;
ATF_REQUIRE_MSG(S->nsrc < sizeof(inbuf) - 2, "[%s]", title);
ATF_REQUIRE_MSG(S->ndst < sizeof(outbuf) - 2, "[%s]", title);
memset(inbuf, inguard, sizeof(inbuf));
memset(outbuf, outguard, sizeof(outbuf));
src = src0 = inbuf + 1;
memcpy(src, S->src, nsrc);
dst = dst0 = outbuf + 1;
srcleft = srcleft0 = nsrc;
dstleft = dstleft0 = ndst;
C = iconv_open(S->dst_codeset, S->src_codeset);
if (C == (iconv_t)-1) {
error = errno;
atf_tc_fail_nonfatal("[%s] iconv_open: %s (%d)", title,
strerror(error), error);
return;
}
ninval = iconv(C, &src, &srcleft, &dst, &dstleft);
if (ninval == (size_t)-1) {
error = errno;
/*
* Incomplete input manifests as EINVAL -- ignore that,
* unless we're trying the full-size input.
*
* Truncated output manifests as E2BIG -- ignore that,
* unless we're trying the full-size output.
*/
if ((error != EINVAL || nsrc == S->nsrc) &&
(error != E2BIG || ndst == S->ndst)) {
atf_tc_fail_nonfatal("[%s] iconv: %s (%d)",
title, strerror(error), error);
goto next;
}
} else if (ninval != S->ninval) {
error = errno;
atf_tc_fail_nonfatal("[%s] iconv:"
" %zu invalid, expected %zu",
title, ninval, S->ninval);
}
ATF_CHECK_MSG(src0 <= src && src <= src0 + srcleft0, "[%s] iconv:"
" src went from %p to %p, expected [%p,%p]",
title, src0, src, src0, src0 + srcleft0);
ATF_CHECK_MSG(srcleft <= srcleft0, "[%s] iconv:"
" srcleft went from %zu to %zu",
title, srcleft0, srcleft);
ATF_CHECK_MSG(dst0 <= dst && dst <= dst0 + dstleft0, "[%s] iconv:"
" dst went from %p to %p, expected [%p,%p]",
title, dst0, dst, dst0, dst0 + dstleft0);
ATF_CHECK_MSG(dstleft <= dstleft0, "[%s] iconv:"
" dstleft went from %zu to %zu",
title, dstleft0, dstleft);
if (memcmp(dst0, S->dst, MIN(ndst, dstleft0 - dstleft)) != 0) {
size_t k;
atf_tc_fail_nonfatal("[%s] iconv: bad conv", title);
fprintf(stderr, "[%s] input: ", title);
for (k = 0; k < nsrc; k++)
fprintf(stderr, " %02x", (unsigned char)S->src[k]);
fprintf(stderr, "\n");
fprintf(stderr, "[%s] expected: ", title);
for (k = 0; k < ndst; k++)
fprintf(stderr, " %02x", (unsigned char)S->dst[k]);
fprintf(stderr, "\n");
fprintf(stderr, "[%s] got: ", title);
for (k = 0; k < ndst; k++)
fprintf(stderr, " %02x", (unsigned char)dst0[k]);
fprintf(stderr, "\n");
}
next: if (dst0[-1] != outguard) {
atf_tc_fail_nonfatal("[%s] iconv overran before buffer:"
" dst0[-1] = 0x%02x, expected 0x%02x",
title, dst0[-1], outguard);
}
if (dst0[ndst] != outguard) {
atf_tc_fail_nonfatal("[%s] iconv overran after buffer:"
" dst0[ndst=%zu] = 0x%02x, expected 0x%02x",
title, ndst, dst0[ndst], outguard);
}
if (dst[0] != outguard) {
atf_tc_fail_nonfatal("[%s] iconv overran past updated dst:"
" dst[0] = 0x%02x, expected 0x%02x",
title, dst[0], outguard);
}
if (iconv_close(C) == -1) {
error = errno;
atf_tc_fail_nonfatal("[%s] iconv_close: %s (%d)",
title, strerror(error), error);
}
}
static void
test_sample(const char *title, const struct sample *S)
{
char buf[128];
size_t nsrc, ndst;
fprintf(stderr, "test %s from %s to %s\n",
title, S->src_codeset, S->dst_codeset);
for (nsrc = 0; nsrc <= S->nsrc; nsrc++) {
snprintf(buf, sizeof(buf), "%s %zu/%zu", title, nsrc, S->ndst);
test_sample_bounded(buf, S, nsrc, S->ndst);
}
for (ndst = 0; ndst <= S->ndst; ndst++) {
snprintf(buf, sizeof(buf), "%s %zu/%zu", title, S->nsrc, ndst);
test_sample_bounded(buf, S, S->nsrc, ndst);
}
}
ATF_TC(iconv_samples);
ATF_TC_HEAD(iconv_samples, tc)
{
atf_tc_set_md_var(tc, "descr", "Test iconv on various fixed samples");
}
ATF_TC_BODY(iconv_samples, tc)
{
unsigned i;
for (i = 0; i < __arraycount(samples); i++) {
const struct sample *S = &samples[i];
struct sample reverse = {
.src_codeset = S->dst_codeset,
.dst_codeset = S->src_codeset,
.nsrc = S->ndst,
.src = S->dst,
.ndst = S->nsrc,
.dst = S->src,
.ninval = S->ninval_rev,
};
char buf[128];
if (S->xfail)
atf_tc_expect_fail("%s", S->xfail);
snprintf(buf, sizeof(buf), "case %u: %s to %s", i,
S->src_codeset, S->dst_codeset);
test_sample(buf, S);
if (S->ninval_rev != IRREVERSIBLE) {
snprintf(buf, sizeof(buf), "case %u: %s to %s", i,
S->dst_codeset, S->src_codeset);
test_sample(buf, &reverse);
}
if (S->xfail)
atf_tc_expect_pass();
}
}
ATF_TC(iconv_pr59019_hz8);
ATF_TC_HEAD(iconv_pr59019_hz8, tc)
{
atf_tc_set_md_var(tc, "descr", "Truncated HZ8 input from PR 59019");
}
ATF_TC_BODY(iconv_pr59019_hz8, tc)
{
const char title[] = "iconv_pr59019_hz8";
char in[4] = "\x7e\x7b\x7e\x7e"; /* ~{~~ */
char out[4096], guard = arc4random();
char *src0, *src, *dst0, *dst;
size_t srcleft0, srcleft, dstleft0, dstleft;
iconv_t C;
size_t ninval;
memset(out, guard, sizeof(out));
REQUIRE_LIBC((C = iconv_open(/*to*/"UTF-8", /*from*/"HZ8")),
(iconv_t)-1);
src = src0 = in;
srcleft = srcleft0 = sizeof(in);
dst = dst0 = out + 1;
dstleft = dstleft0 = sizeof(out) - 2;
ninval = iconv(C, &src, &srcleft, &dst, &dstleft);
/*
* XXX Not actually 100% sure this is the correct result -- I
* can't find a reference for the HZ8 encoding.
*/
ATF_CHECK_EQ_MSG(ninval, (size_t)-1, "[%s] iconv: ninval=%zu", title,
ninval);
ATF_CHECK_MSG(src0 <= src && src <= src0 + srcleft0, "[%s] iconv:"
" src went from %p to %p, expected [%p,%p)",
title, src0, src, src0, src0 + srcleft0);
ATF_CHECK_MSG(srcleft <= srcleft0, "[%s] iconv:"
" srcleft went from %zu to %zu",
title, srcleft0, srcleft);
ATF_CHECK_MSG(dst0 <= dst && dst <= dst0 + dstleft0, "[%s] iconv:"
" dst went from %p to %p, expected [%p,%p)",
title, dst0, dst, dst0, dst0 + dstleft0);
ATF_CHECK_MSG(dstleft <= dstleft0, "[%s] iconv:"
" dstleft went from %zu to %zu",
title, dstleft0, dstleft);
ATF_CHECK_EQ(dst0[-1], guard);
ATF_CHECK_EQ(dst0[dstleft0], guard);
RL(iconv_close(C));
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, iconv_pr59019_hz8);
ATF_TP_ADD_TC(tp, iconv_samples);
return atf_no_error();
}
+1 -1
View File
@@ -22,7 +22,7 @@ To email small changes, please run a POSIX shell command like
For more-elaborate or possibly controversial changes,
such as renaming, adding or removing zones, please read
“Theory and pragmatics of the tz code and data”
<https://www.iana.org/time-zones/repository/theory.html>.
<https://data.iana.org/time-zones/theory.html>
It is also good to browse the mailing list archives
<https://lists.iana.org/hyperkitty/list/[email protected]/>
for examples of patches that tend to work well.
+45 -67
View File
@@ -66,28 +66,6 @@ DATAFORM= main
LOCALTIME= Factory
# The POSIXRULES macro controls interpretation of POSIX-like TZ
# settings like TZ='EET-2EEST' that lack DST transition rules.
# If POSIXRULES is '-', no template is installed; this is the default.
# Any other value for POSIXRULES is obsolete and should not be relied on, as:
# * It does not work correctly in popular implementations such as GNU/Linux.
# * It does not work even in tzcode, except for historical timestamps
# that precede the last explicit transition in the POSIXRULES file.
# Hence it typically does not work for current and future timestamps.
# If, despite the above, you want a template for handling these settings,
# you can change the line below (after finding the timezone you want in the
# one of the $(TDATA) source files, or adding it to a source file).
# Alternatively, if you discover you've got the wrong timezone, you can just
# 'zic -p -' to remove it, or 'zic -p rightzone' to change it.
# Use the command
# make zonenames
# to get a list of the values you can use for POSIXRULES.
POSIXRULES= -
# Also see TZDEFRULESTRING below, which takes effect only
# if POSIXRULES is '-' or if the template file cannot be accessed.
# Installation locations.
#
@@ -136,7 +114,7 @@ ZDUMPDIR = $(BINDIR)
# The "zic" command goes in:
ZICDIR = $(TOPDIR)/$(USRDIR)/sbin
# Manual pages go in subdirectories of. . .
# Manual pages go in subdirectories of:
MANDIR = $(TOPDIR)/$(USRSHAREDIR)/man
# Library functions are put in an archive in LIBDIR.
@@ -167,10 +145,10 @@ TIME_T_ALTERNATIVES_TAIL = int_least32_t.ck uint_least32_t.ck \
# nonnegative TZ_CHANGE_INTERVAL also assumes this, so to be compatible with
# these, use "posix_only" or "posix_right". Use POSIX time on systems with
# leap smearing; this can work better than unsmeared "right" time with
# applications that are not leap second aware, and is closer to unsmeared
# applications that are not aware of leap seconds, and is closer to unsmeared
# "right" time than unsmeared POSIX time is (e.g., 0.5 vs 1.0 s max error).
REDO= posix_right
REDO= posix_only
# Whether to put an "Expires" line in the leapseconds file.
# Use EXPIRES_LINE=1 to put the line in, 0 to omit it.
@@ -194,9 +172,9 @@ EXPIRES_LINE= 0
TZDATA_TEXT= leapseconds tzdata.zi
# For backward-compatibility links for old zone names, use
# For backward-compatibility links and zones for old names, use
# BACKWARD= backward
# To omit these links, use
# To omit these links and zones, use
# BACKWARD=
BACKWARD= backward
@@ -284,7 +262,10 @@ LDLIBS=
# -DHAVE_STRDUP=0 if your system lacks the strdup function
# -DHAVE_STRNLEN=0 if your system lacks the strnlen function+
# -DHAVE_STRTOLL=0 if your system lacks the strtoll function+
# -DHAVE_STRUCT_STAT_ST_CTIM=0 if struct stat lacks a member st_ctim+
# -DHAVE_STRUCT_STAT_ST_CTIM=0 if struct stat lacks a status-change member
# of type struct timespec, so code should use st_ctime instead;
# but if the status-change member name is st_ctimespec,
# use -Dst_ctim=st_ctimespec instead (default is guessed)+
# -DHAVE_STRUCT_TIMESPEC=0 if your system lacks struct timespec+
# -DHAVE_SYMLINK=0 if your system lacks the symlink function
# -DHAVE_SYS_STAT_H=0 if <sys/stat.h> does not work*
@@ -314,21 +295,21 @@ LDLIBS=
# -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires;
# not needed by the main-program tz code, which is single-threaded.
# Append other compiler flags as needed, e.g., -pthread on GNU/Linux.
# The following options can also be used:
# With -DTHREAD_SAFE the following options can also be used:
# -DTHREAD_PREFER_SINGLE to prefer speed in single-threaded apps,
# at some cost in CPU time and energy in multi-threaded apps.
# The following options can also be used:
# With -DTHREAD_PREFER_SINGLE the following options can also be used:
# -DHAVE___ISTHREADED=1 if there is an extern int __isthreaded
# variable, 0 otherwise (default is guessed)
# -DHAVE_SYS_SINGLE_THREADED_H=0 if <sys/single_threaded.h> works,
# 0 otherwise (default is guessed)
# -DTHREAD_RWLOCK to use read-write locks intead of mutexes.
# This can improve paralellism and thus save real time
# -DTHREAD_RWLOCK to use read-write locks instead of mutexes.
# This can improve parallelism and thus save real time
# if many threads call tzcode functions simultaneously.
# It also costs CPU time and thus energy.
# -DTHREAD_TM_MULTI to have gmtime, localtime, and offtime
# return different struct tm * addresses in different threads.
# This supports unportable programs that call
# This supports nonportable programs that call
# gmtime/localtime/offtime when they should call
# gmtime_r/localtime_r/offtime_r to avoid races.
# Because the corresponding storage is freed on thread exit,
@@ -347,10 +328,13 @@ LDLIBS=
# -DTZ_DOMAIN=\"foo\" to use "foo" for gettext domain name; default is "tz"
# -DTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
# the default is system-supplied, typically "/usr/lib/locale"
# -DTZ_RUNTIME_LEAPS=0 to disable runtime support for leap seconds.
# This conforms to POSIX, shrinks tzcode's attack surface,
# and is more efficient. However, it fails to support Internet
# RFC 9636's leap seconds.
# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
# DST transitions for proleptic format TZ strings lacking them,
# in the usual case where POSIXRULES is '-'. If not specified,
# TZDEFRULESTRING defaults to US rules for future DST transitions.
# DST transitions for proleptic format TZ strings lacking them.
# If not specified, it defaults to US rules for future DST transitions.
# This mishandles some past timestamps, as US DST rules have changed.
# It also mishandles settings like TZ='EET-2EEST' for eastern Europe,
# as Europe and US DST rules differ.
@@ -393,19 +377,21 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 \
-Wdeclaration-after-statement -Wdouble-promotion \
-Wduplicated-branches -Wduplicated-cond -Wflex-array-member-not-at-end \
-Wformat=2 -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation \
-Wimplicit-fallthrough=5 -Winit-self -Wlogical-op \
-Wfree-labels -Wimplicit-fallthrough=5 -Winit-self \
-Wkeyword-macro -Wlogical-op \
-Wmissing-declarations -Wmissing-prototypes \
-Wmissing-variable-declarations -Wnested-externs \
-Wnull-dereference \
-Wold-style-definition -Woverlength-strings -Wpointer-arith \
-Wshadow -Wshift-overflow=2 -Wstrict-overflow \
-Wshadow -Wshift-overflow=2 \
-Wstrict-prototypes -Wstringop-overflow=4 \
-Wstringop-truncation -Wsuggest-attribute=cold \
-Wsuggest-attribute=cold \
-Wsuggest-attribute=const -Wsuggest-attribute=format \
-Wsuggest-attribute=malloc \
-Wsuggest-attribute=noreturn -Wsuggest-attribute=pure \
-Wtrampolines -Wundef -Wunused-macros -Wuse-after-free=3 \
-Wvariadic-macros -Wvla -Wwrite-strings \
-Wzero-as-null-pointer-constant \
-Wno-format-nonliteral -Wno-sign-compare -Wno-type-limits
#
# If your system has a "GMT offset" field in its "struct tm"s
@@ -548,7 +534,7 @@ ZIC_INSTALL= $(ZIC) -d '$(DESTDIR)$(TZDIR)'
# mawk 1.3.3 and Solaris 10 /usr/bin/awk do not work.
# Also, it is better (though not essential) if 'awk' supports UTF-8,
# and unfortunately mawk and busybox awk do not support UTF-8.
# Try AWK=gawk or AWK=nawk if your awk has the abovementioned problems.
# Try AWK=gawk or AWK=nawk if your awk has the problems mentioned above.
AWK= awk
# The full path name of a POSIX-compliant shell, preferably one that supports
@@ -588,7 +574,7 @@ SAFE_CHAR= '[]'$(SAFE_CHARSET)'-]'
# These non-alphabetic, non-ASCII printable characters are
# used in commentary or in generated *.txt files
# and are not likely to cause confusion.
UNUSUAL_OK_CHARSET= §«°±»½¾×–‘’“”•→−≤★⟨⟩⯪
UNUSUAL_OK_CHARSET= §«°±»½¾¿×–‘’“”•→−≤★⟨⟩⯪
# Put this in a bracket expression to match spaces.
s = [:space:]
@@ -723,7 +709,6 @@ install: all $(DATA) $(REDO) $(MANS)
'$(DESTDIR)$(MANDIR)/man3' '$(DESTDIR)$(MANDIR)/man5' \
'$(DESTDIR)$(MANDIR)/man8'
$(ZIC_INSTALL) -l $(LOCALTIME) \
-p $(POSIXRULES) \
-t '$(DESTDIR)$(TZDEFAULT)'
cp -f $(TABDATA) '$(DESTDIR)$(TZDIR)/.'
cp tzselect '$(DESTDIR)$(BINDIR)/.'
@@ -929,7 +914,7 @@ tzselect: tzselect.ksh version
check: check_mild back.ck now.ck
check_mild: check_web check_zishrink \
character-set.ck white-space.ck links.ck mainguard.ck \
name-lengths.ck slashed-abbrs.ck sorted.ck \
name-lengths.ck news.ck slashed-abbrs.ck sorted.ck \
tables.ck ziguard.ck tzs.ck
# True if UTF8_LOCALE does not work;
@@ -937,7 +922,7 @@ check_mild: check_web check_zishrink \
UTF8_LOCALE_MISSING = \
{ test ! '$(UTF8_LOCALE)' \
|| ! printf 'A\304\200B\n' \
| LC_ALL='$(UTF8_LOCALE)' grep -q '^A.B$$' >/dev/null 2>&1 \
| LC_ALL='$(UTF8_LOCALE)' grep -q '^A[[:alpha:]]B$$' >/dev/null 2>&1 \
|| { export LC_ALL='$(UTF8_LOCALE)'; false; }; }
character-set.ck: $(ENCHILADA)
@@ -1021,11 +1006,11 @@ now.ck: checknow.awk date tzdata.zi zdump zic zone1970.tab zonenow.tab
now=$(CHECK_NOW_TIMESTAMP) && \
future=$$(($(CHECK_NOW_FUTURE_SECS) + $$now)) && \
./zdump -i -t $$now,$$future \
$$(find "$$PWD/$@d"/????*/ -type f) \
$$(find "$$PWD/$@d"/????*/ -type f -o -type l) \
>$@d/zdump-now.tab && \
./zdump -i -t 0,$$future \
$$(find "$$PWD/$@d" -name Etc -prune \
-o -type f ! -name '*.tab' -print) \
-o \( -type f -o -type l \) ! -name '*.tab' -print) \
>$@d/zdump-1970.tab && \
$(AWK) \
-v now=$$now \
@@ -1033,7 +1018,12 @@ now.ck: checknow.awk date tzdata.zi zdump zic zone1970.tab zonenow.tab
-v zdump_table=$@d/zdump-now.tab \
-f checknow.awk zonenow.tab
$(AWK) \
'BEGIN {print "-\t-\tUTC"} /^Zone/ {print "-\t-\t" $$2}' \
'BEGIN { \
SysVzone["EST5EDT"] = 1; SysVzone["CST6CDT"] = 1; \
SysVzone["MST7MDT"] = 1; SysVzone["PST8PDT"] = 1; \
print "-\t-\tUTC" \
} \
$$1 == "Zone" && !SysVzone[$$2] {print "-\t-\t" $$2}' \
$(PRIMARY_YDATA) backward factory | \
$(AWK) \
-v zdump_table=$@d/zdump-1970.tab \
@@ -1099,6 +1089,12 @@ zishrink-posix.ck zishrink-right.ck: \
rm -fr $@d t-$@d shrunk-$@d
touch $@
# Check that NEWS has data release versions and dates in reverse order.
news.ck: NEWS
grep '^Release [0-9][0-9][0-9][0-9]' NEWS | LC_ALL=C sort -cru
sed -n '/ -0000$$/!s/^Release [^ ]*//p' NEWS|LC_ALL=C sort -cru
touch $@
clean_misc:
rm -fr *.ckd *.dir
rm -f *.ck *.core *.o *.out *.t core core.* \
@@ -1155,7 +1151,8 @@ SET_TIMESTAMP_N = sh -c '\
# If DEST depends on A B C ... in this Makefile, callers should use
# $(SET_TIMESTAMP_DEP) DEST A B C ..., for the benefit of any
# downstream 'make' that considers equal timestamps to be out of date.
# POSIX allows this 'make' behavior, and HP-UX 'make' does it.
# POSIX allows this 'make' behavior, although only HP-UX 'make'
# (which is no longer supported) did things that way.
# If all that matters is that the timestamp be reproducible
# and plausible, use $(SET_TIMESTAMP).
SET_TIMESTAMP = $(SET_TIMESTAMP_N) 0
@@ -1415,24 +1412,6 @@ $(ALL_ASC):
$(SET_TIMESTAMP) $(@:.t=) $(?:.t=)
touch $@
TYPECHECK_CFLAGS = $(CFLAGS) -DTYPECHECK -D__time_t_defined -D_TIME_T
typecheck: long-long.ck unsigned.ck
long-long.ck unsigned.ck: $(VERSION_DEPS)
rm -fr $@d
mkdir $@d
ln $(VERSION_DEPS) $@d
cd $@d && \
case $@ in \
long-long.*) i="long long";; \
unsigned.* ) i="unsigned" ;; \
esac && \
$(MAKE) \
CFLAGS="$(TYPECHECK_CFLAGS) \"-Dtime_t=$$i\"" \
TOPDIR="$$PWD" \
install
$@d/zdump -i -c 1970,1971 Europe/Rome
touch $@
zonenames: tzdata.zi
@$(AWK) '/^Z/ { print $$2 } /^L/ { print $$3 }' tzdata.zi
@@ -1458,6 +1437,5 @@ zic.o: private.h tzdir.h tzfile.h version.h
.PHONY: traditional_signatures traditional_signatures_version
.PHONY: traditional_tarballs traditional_tarballs_version
.PHONY: tailored_tarballs tailored_tarballs_version
.PHONY: typecheck
.PHONY: zonenames zones
.PHONY: $(ZDS)
+353 -5
View File
@@ -1,5 +1,351 @@
News for the tz database
Release 2026e - 2026-09-29 17:14:38 -0700
Briefly:
Manitoba moves to permanent -05 on 2026-10-31.
Changes to future timestamps
Manitoba’s 2026-03-08 spring forward was its last foreseeable clock
change, as it moved to permanent -05 thereafter. Model this with
its traditional abbreviation EST. Although the change to
permanent -05 legally takes place on 2026-10-31, temporarily model
the change to occur on 2026-11-01 at 02:00 for the same reason as
other recent temporary hacks. (Caution: see “NOTE FOR 2026b
TEMPORARY HACK FOR CLDR AND CANADA” below.)
As the change affects both America/Winnipeg and its backward
compatibility link, the obsolescent setting TZ="Canada/Central"
will now use the abbreviation EST for affected timestamps,
akin to TZ="Canada/Pacific" behavior introduced in 2026b.
Another TZDB release may be needed soon if any of the portions of
northwestern Ontario historically aligned with America/Winnipeg do
not follow. For now, given the short leadtime with Manitoba’s
announcement, assume that they will, to avoid creating new zones
that may not be needed if no divergence occurs.
Changes to past timestamps
In 1925 Ireland fell back on 09-20 not 10-04 (thanks to Stan Ulbrych).
Changes to commentary
Discussion on timekeeping practices in northwestern Ontario has been
expanded in light of Manitoba’s recent announcement. It is not yet
known whether or to what extent these areas may adapt their own
timekeeping practices in response.
Release 2026d - 2026-09-11 15:21:07 -0700
Briefly:
Canada’s Northwest Territories moved to permanent -06 on 2026-08-21.
Obsolescent settings like TZ="EST5EDT" now conform better to POSIX.
Fix security, performance and porting bugs in zic and localtime.
Changes to future timestamps
Canada’s Northwest Territories will not fall back on 2026-11-01
and will stay on -06 year-round, matching Alberta’s recent change.
Model this with its traditional abbreviation CST. Although the
change to permanent -06 legally took place on 2026-08-21,
temporarily model the change to occur on 2026-11-01 at 02:00
for the same reason as other recent temporary hacks. (Caution:
see “NOTE FOR 2026b TEMPORARY HACK FOR CLDR AND CANADA” below.)
This affects only America/Inuvik as the rest of the territory is
covered by America/Edmonton, for which the equivalent change was
released in 2026c.
Changes to past timestamps
Colombia’s 1992-05-02 spring forward was at 00:00, not 24:00.
Iran’s 1979-05-26 spring forward was at 00:00, not 24:00.
(Thanks to N.F. Hase.)
The backward-compatibility names EST5EDT, CST6CDT, MST7MDT, and
PST8PDT now conform better to POSIX. For example, EST5EDT now
always uses the abbreviation "EST" for standard time (now always 5
hours behind UT) and "EDT" for daylight saving time, whereas it
formerly had different UT offsets before standard time was
introduced and sometimes used abbreviations like "LMT", "EWT" and
"EPT", all contrary to POSIX. Also, though not required by POSIX
these names now use US federal rules rather than rules of places
like New York, reverting to 2024a behavior. This change affects
only timestamps before 1966-10-30 at 01:00 standard time.
Other data changes
The temporary hacks used for North American timekeeping changes
now work around a libstdc++ std::chrono bug in GCC 14.1-14.4,
15.1-15.2, and 16.1; see GCC bug 124851. This data change does
not affect TZif files or timestamps. The change does not work
around the related but less serious GCC bugs 116110 and 124513.
These GCC bugs are all fixed in GCC 16.2.
Changes to code
zic now rejects Link targets that would have invalid names, and
more efficiently processes Expires, Leap and Rule lines with years
far in the past or future. (Thanks to Darren Carreras.)
zic now ports to systems that report lack of link support via
EINVAL, ENOSYS or EPERM errno values. (Thanks to Tom Lane.)
When tzset and related functions encounter a TZif file that is too
large for them, they now consistently fail instead of sometimes
silently ignoring excess parts of the file.
localtime-related functions no longer mishandle extreme timestamps
when given TZif files holding some unlikely timezone histories.
(Problem reported by David Sarkisyan.)
localtime-related functions no longer check the values of TZif
files’ standard/wall and UT/local indicators, which these
functions have not used since 2026a’s removal of the old
posixrules feature.
tzcode has been ported to Haiku.
localtime.c now works again by default on AIX and DragonFly BSD.
zic now rejects ‘:’ and ‘\’ in Zone and Link names when running on
Microsoft Windows. (Problem reported by David Diaz.)
Changes to documentation
URLs for release tarballs in tz-link.html have been updated to
reflect their new canonical URLs on data.iana.org.
Release 2026c - 2026-07-08 10:23:58 -0700
Briefly:
Alberta moved to permanent -06 on 2026-06-18.
Morocco moves to permanent +00 on 2026-09-20.
More integer overflow bugs have been fixed in zic.
Changes to future timestamps
Alberta’s 2026-03-08 spring forward was its last foreseeable clock
change, as it moved to permanent -06 thereafter. (Thanks to Roozbeh
Pournader and others.) Model this with its traditional abbreviation
CST. Although the change to permanent -06 legally took place on
2026-06-18, temporarily model the change to occur on 2026-11-01 at
02:00 instead, for the same reason we introduced a similarly
temporary hack for British Columbia in 2026b. (Caution: see
“NOTE FOR 2026b TEMPORARY HACK FOR CLDR AND CANADA” below.)
As the change affects both America/Edmonton and its backward
compatibility link, the obsolescent setting TZ="Canada/Mountain"
will now use the abbreviation CST for affected timestamps,
akin to TZ="Canada/Pacific" behavior introduced in 2026b.
Although another TZDB release will likely be needed soon because
Northwest Territories will likely follow Alberta, the legal
formalities have not yet taken place.
Morocco plans to move back to permanent UTC, without daylight
saving time transitions, on 2026-09-20 at 02:00. This also
affects Western Sahara.
Changes to code
zic no longer overflows integers when processing outlandish input
like ‘Zone Ouch 0 - LMT 9223372036854775807’, ‘Zone Ouch 0
2562047788015215 LMT’, ‘Zone Ouch -2562047788015215:30:08 - LMT’,
and ‘Zone Ouch -2562047788015215:30:08 - %%z’. This avoids
undefined behavior in C. (Problems reported by Naveed Khan.)
On platforms that have EFTYPE, tzalloc now fails with errno set to
EFTYPE, not EINVAL, if it detects that the TZif file has an
invalid format or is not a regular file. Formerly it did this
only on NetBSD, and only when the file was not a regular file.
Unprivileged programs no longer require TZif files to be regular
files or reject relative names containing ".." components. This
reverts to the more-permissive 2025b behavior, as the stricter
behavior did not catch on in FreeBSD.
zic now reports any failure to remove a temporary file when
cleaning up after a previous failure. (Problem reported by Tom
Lane.)
Changes to commentary
Northwest Territories is expected to move to permanent -06 prior to
2026-11-01 02:00, when clocks would otherwise fall back. (Thanks to
Tim Parenti and James Bellaire.) Model this with its traditional
abbreviation CST. Unfortunately the change is not yet official, so
it is currently present only as comments that can be uncommented as
needed.
Changes to build procedure
The undocumented ‘typecheck’ Makefile check rule has been removed.
It stopped working in 2025a and evidently nobody noticed.
The rule was superseded by ‘check_time_t_alternatives’ in 2013d.
Release 2026b - 2026-04-22 23:06:43 -0700
Briefly:
British Columbia moved to permanent -07 on 2026-03-09.
zic no longer mishandles a last transition to a new time type.
Some more overflow bugs have been fixed in zic.
Changes to future timestamps
British Columbia’s 2026-03-08 spring forward was its last
foreseeable clock change, as it moved to permanent -07 thereafter.
(Thanks to Arthur David Olson.) Although the change to permanent
-07 legally took place on 2026-03-09, temporarily model the change
to occur on 2026-11-01 at 02:00 instead. This works around a
limitation in CLDR 48.1 (2026-01-08). This temporary hack is
planned to be removed after CLDR is fixed.
To match longstanding practice for -07 standard time in North
America, such as for America/Dawson, America/Dawson_Creek,
America/Fort_Nelson and America/Whitehorse, affected BC
timestamps use the abbreviation MST. As the change affects both
America/Vancouver and its backward compatibility link, the
obsolescent setting TZ="Canada/Pacific" will now use the
abbreviation MST. Future TZDB releases may change the
abbreviation if something else becomes popular across areas
observing -07, and may change it to "-07" if no alphabetic
consensus emerges.
Changes to code
zic no longer mishandles a last transition to a new time type.
NOTE FOR 2026b TEMPORARY HACK FOR CLDR AND CANADA:
This zic fix is needed for the temporary hack (mentioned above)
that works around the Canadian timekeeping bug in Unicode CLDR.
Without the fix, the temporary hack causes zic versions 2023d
through 2026a, in their default mode that generates slim output,
to generate a TZif file that violates Internet RFC 9636 §3.3.
The buggy file in turn causes some TZif readers, including tzcode
itself, to ignore America/Vancouver’s 2026-11-01 02:00 transition
from PDT (tm_isdst=1) to MST (tm_isdst=0). Although the buggy
file does not cause any known TZif reader to mishandle UT offsets,
caution is advised when using zic 2023d through 2026a to compile
data from more-recent tz releases. To work around this problem
when using these older zic versions, use ‘zic -b fat’.
zic no longer overflows a buffer when generating a TZ string like
"PST-167:59:58PDT-167:59:59,M11.5.6/-167:59:59,M12.5.6/-167:59:59",
which can occur with adversarial input. (Thanks to Naveed Khan.)
zic no longer generates a longer TZif file than necessary when
an earlier time zone abbreviation is a suffix of a later one.
As a nice side effect, zic no longer overflows a buffer when given
a long series of abbreviations, each a suffix of the next.
(Buffer overflow reported by Arthur Chan.)
zic no longer overflows an int when processing input like ‘Zone
Ouch 2147483648:00:00 - LMT’. The int overflow can lead to buffer
overflow in adversarial cases. (Thanks to Naveed Khan.)
zic now checks for signals more often.
Release 2026a - 2026-03-01 22:59:49 -0800
Briefly:
Moldova has used EU transition times since 2022.
The “right” TZif files are no longer installed by default.
-DTZ_RUNTIME_LEAPS=0 disables runtime support for leap seconds.
TZif files are no longer limited to 50 bytes of abbreviations.
zic is no longer limited to 50 leap seconds.
Several integer overflow bugs have been fixed.
Changes to past and future timestamps
Since 2022 Moldova has observed EU transition times, that is, it
has sprung forward at 03:00, not 02:00, and has fallen back at
04:00, not 03:00. (Thanks to Heitor David Pinto.)
Changes to data
Remove Europe/Chisinau from zonenow.tab, as it now agrees with
Europe/Athens for future timestamps.
Changes to build procedure
The Makefile no longer by default installs an alternate set
of TZif files for system clocks that count leap seconds.
Install with ‘make REDO=posix_right’ to get the old default,
which is rarely used in major downstream distributions.
If your system clock counts leap seconds (contrary to POSIX),
it is better to install with ‘make REDO=right_only’.
This change does not affect the leapseconds file, which is still
installed as before.
The Makefile’s POSIXRULES option, which was declared obsolete in
release 2019b, has been removed. The Makefile’s build procedure
thus no longer optionally installs the obsolete posixrules file.
Changes to code
Compiling with the new option -DTZ_RUNTIME_LEAPS=0 disables
runtime support for leap seconds. Although this conforms to
POSIX, shrinks tzcode’s attack surface, and is more efficient,
it fails to support Internet RFC 9636’s leap seconds.
zic now can generate, and localtime.c can now use, TZif files that
hold up to 256 bytes of abbreviations, counting trailing NULs.
The previous limit was 50 bytes, and some tzdata TZif files were
already consuming 40 bytes. zic -v warns if it generates a file
that exceeds the old 50-byte limit.
zic -L can now generate TZif files with more than 50 leap seconds.
This helps test TZif readers not limited to 50 leap seconds, as
tzcode’s localtime.c is; it has little immediate need for
practical timekeeping as there have been only 27 leap seconds and
possibly there will be no more, due to planned changes to UTC.
zic -v warns if its output exceeds the old 50-second limit.
localtime.c no longer accesses the posixrules file generated by
zic -p. Hence for obsolete and nonconforming settings like
TZ="AST4ADT" it now typically falls back on US DST rules, rather
than attempting to override this fallback with the contents of the
posixrules file. This removes library support that was declared
obsolete in release 2019b, and fixes some undefined behavior.
(Undefined behavior reported by Naveed Khan.)
The posix2time, posix2time_z, time2posix, and time2posix_z
functions now set errno=EOVERFLOW and return ((time_t) -1) if the
result is not representable. Formerly they had undefined behavior
that could in practice result in crashing, looping indefinitely,
or returning an incorrect result. As before, these functions are
defined only when localtime.c is compiled with the -DSTD_INSPIRED
option.
Some other undefined behavior, triggered by TZif files containing
outlandish but conforming UT offsets or leap second corrections,
has also been fixed. (Some of these bugs reported by Naveed Khan.)
localtime.c no longer rejects TZif files that exactly fit in its
internal structures, fixing off-by-one typos introduced in 2014g.
zic no longer generates a no-op transition when
simultaneous Rule and Zone changes cancel each other out.
This occurs in tzdata only in Asia/Tbilisi on 1997-03-30.
(Thanks to Renchunhui for a test case showing the bug.)
zic no longer assumes you can fflush a read-only stream.
(Problem reported by Christos Zoulas.)
zic no longer generates UT offsets equal to -2**31 and localtime.c
no longer accepts them, as they can cause trouble in both
localtime.c and its callers. RFC 9636 prohibits such offsets.
zic -p now warns that the -p option is obsolete and likely
ineffective.
Release 2025c - 2025-12-10 14:42:37 -0800
Briefly:
@@ -69,6 +415,8 @@ Release 2025c - 2025-12-10 14:42:37 -0800
The new CFLAGS options -DHAVE_STRUCT_STAT_ST_CTIM=0 and
-DHAVE_STRUCT_TIMESPEC=0 port to non-POSIX.1-2008 platforms
that lack st_ctim and struct timespec, respectively.
On these platforms, the code falls back on st_ctime to
implement -DTZ_CHANGE_INTERVAL=N.
tzset etc. now treat ' ' like '_' in time zone abbreviations,
just as they treat other invalid bytes. This continues the
@@ -87,9 +435,9 @@ Release 2025c - 2025-12-10 14:42:37 -0800
rarely changing and many threads call tzcode simultaneously.
It costs more CPU time and energy.
The new CFLAGS option -TTHREAD_TM_MULTI causes localtime to return
The new CFLAGS option -DTHREAD_TM_MULTI causes localtime to return
a pointer to thread-specific memory, as FreeBSD does, instead of
to the same memory in all threads. This supports unportable
to the same memory in all threads. This supports nonportable
programs that incorrectly use localtime instead of localtime_r.
This option affects gmtime and offtime similarly to localtime.
Because the corresponding storage is freed on thread exit, this
@@ -417,7 +765,7 @@ Release 2024a - 2024-02-01 09:28:56 -0800
The leap-seconds.list file is now copied from the IERS instead of
from its downstream counterpart at NIST, as the IERS version is
now in the public domain too and tends to be more up-to-date.
(Thanks to Martin Burnicki for liaisoning with the IERS.)
(Thanks to Martin Burnicki for liaising with the IERS.)
Changes to documentation
@@ -1575,7 +1923,7 @@ Release 2020a - 2020-04-23 16:03:47 -0700
zic -L now supports an Expires line in the leapseconds file, and
truncates the TZif output accordingly. This propagates leap
second expiration information into the TZif file, and avoids the
abovementioned localtime.c bug as well as similar bugs present in
localtime.c bug mentioned above, as well as similar bugs present in
many client implementations. If no Expires line is present, zic
-L instead truncates the TZif output based on the #expires comment
present in leapseconds files distributed by tzdb 2018f and later;
@@ -6532,7 +6880,7 @@ few (e.g., code2012c-data2012d) have tarballs with mixed version
numbers. Recent releases also come in an experimental format
consisting of a single tarball tzdb-R.tar.lz with extra data.
Release timestamps are taken from the release's commit (for newer,
A release’s timestamp is taken from the release’s commit (for newer,
Git-based releases), from the newest file in the tarball (for older
releases, where this info is available) or from the email announcing
the release (if all else fails; these are marked with a time zone
+1 -1
View File
@@ -10,7 +10,7 @@ locations around the globe. It is updated periodically to reflect
changes made by political bodies to time zone boundaries, UTC offsets,
and daylight-saving rules.
See <https://www.iana.org/time-zones/repository/tz-link.html> or the
See <https://data.iana.org/time-zones/tz-link.html> or the
file tz-link.html for how to acquire the code and data.
Once acquired, read the leading comments in the file ‘Makefile’
+32 -159
View File
@@ -597,6 +597,24 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis
# Morocco
# See Africa/Ceuta for Spanish Morocco.
# From Paul Eggert (2026-06-26):
# In “Morocco’s GMT+1, a century of shifting time and a debate far from over”
# https://en.yabiladi.com/articles/details/191310/morocco-s-gmt1-century-shifting-time
# (2026-03-30), Yabiladi’s Latifa Babas reports the following:
# * A 1913-10-26 royal dahir established GMT as legal time in Morocco.
# * A 1918-05-10 dahir instituted DST on 1918-05-16 at 00:00.
# * A September 1939 dahir restarted DST on 1939-09-12.
# * A February 1940 dahir restarted DST as early as 1940-02-25.
# * Standard time resumed in September 1946.
# * A June 1950 decree restarted DST, which ran until as late as October.
# * Royal decree 455-67 (1967-06-02) restarted DST on June 3 at noon.
# * After 1967 Morocco used DST “during several summers, particularly
# throughout the 1970s and 1980s.”
# Babas consulted official records that disagree with and are surely
# more correct than our pre-2008 timestamp data, which came from the
# unreliable Shanks & Pottenger. Unfortunately, Babas did not provide
# enough detail to correct our data.
# From Alex Krivenyshev (2008-05-09):
# Here is an article that Morocco plan to introduce Daylight Saving Time between
# 1 June, 2008 and 27 September, 2008.
@@ -850,33 +868,16 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis
# The return to legal GMT time will take place this Sunday, March 19 at 3 a.m.
# ... the return to GMT+1 will be made on Sunday April 23, 2023 at 2 a.m.
# https://www.mmsp.gov.ma/fr/actualites/passage-à-l%E2%80%99heure-gmt-à-partir-du-dimanche-19-mars-2023
#
# From Paul Eggert (2023-03-14):
# For now, guess that in the future Morocco will fall back at 03:00
# the last Sunday before Ramadan, and spring forward at 02:00 the
# first Sunday after one day after Ramadan. To implement this,
# transition dates and times for 2019 through 2087 were determined by
# running the following program under GNU Emacs 28.2. (This algorithm
# also produces the correct transition dates for 2016 through 2018,
# though the times differ due to Morocco's time zone change in 2018.)
# (let ((islamic-year 1440))
# (require 'cal-islam)
# (while (< islamic-year 1511)
# (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year)))
# (b (+ 1 (calendar-islamic-to-absolute (list 10 1 islamic-year))))
# (sunday 0))
# (while (/= sunday (mod (setq a (1- a)) 7)))
# (while (/= sunday (mod b 7))
# (setq b (1+ b)))
# (setq a (calendar-gregorian-from-absolute a))
# (setq b (calendar-gregorian-from-absolute b))
# (insert
# (format
# (concat "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 3:00\t-1:00\t-\n"
# "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 2:00\t0\t-\n")
# (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a))
# (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
# (setq islamic-year (+ 1 islamic-year))))
# From Paul Eggert (2026-06-25):
# https://www.moroccoworldnews.com/2026/06/325034/confirmed-morocco-to-restore-gmt-on-september-20-ending-eight-year-gmt1-saga/
# Today the Moroccan government adopted Decree No. 2.26.530, which abrogates
# the 2018 decree that put it at +01 with daylight saving during Ramadan.
# The plan is to go back to +00 without DST on 2026-09-20 at 02:00.
# From Anass Taghjichte (2026-07-03):
# https://www.sgg.gov.ma/BO/AR/3111/2026/BO_7521_Ar.pdf
# From Afaf EL MAAYATI (2026-07-06):
# https://www.mapexpress.ma/actualite/activite-gouvernementale/conseil-gouvernement-approuve-projet-decret-relatif-au-retour-lheure-legale/
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Morocco 1939 only - Sep 12 0:00 1:00 -
@@ -936,143 +937,14 @@ Rule Morocco 2025 only - Feb 23 3:00 -1:00 -
Rule Morocco 2025 only - Apr 6 2:00 0 -
Rule Morocco 2026 only - Feb 15 3:00 -1:00 -
Rule Morocco 2026 only - Mar 22 2:00 0 -
Rule Morocco 2027 only - Feb 7 3:00 -1:00 -
Rule Morocco 2027 only - Mar 14 2:00 0 -
Rule Morocco 2028 only - Jan 23 3:00 -1:00 -
Rule Morocco 2028 only - Mar 5 2:00 0 -
Rule Morocco 2029 only - Jan 14 3:00 -1:00 -
Rule Morocco 2029 only - Feb 18 2:00 0 -
Rule Morocco 2029 only - Dec 30 3:00 -1:00 -
Rule Morocco 2030 only - Feb 10 2:00 0 -
Rule Morocco 2030 only - Dec 22 3:00 -1:00 -
Rule Morocco 2031 only - Jan 26 2:00 0 -
Rule Morocco 2031 only - Dec 14 3:00 -1:00 -
Rule Morocco 2032 only - Jan 18 2:00 0 -
Rule Morocco 2032 only - Nov 28 3:00 -1:00 -
Rule Morocco 2033 only - Jan 9 2:00 0 -
Rule Morocco 2033 only - Nov 20 3:00 -1:00 -
Rule Morocco 2033 only - Dec 25 2:00 0 -
Rule Morocco 2034 only - Nov 5 3:00 -1:00 -
Rule Morocco 2034 only - Dec 17 2:00 0 -
Rule Morocco 2035 only - Oct 28 3:00 -1:00 -
Rule Morocco 2035 only - Dec 9 2:00 0 -
Rule Morocco 2036 only - Oct 19 3:00 -1:00 -
Rule Morocco 2036 only - Nov 23 2:00 0 -
Rule Morocco 2037 only - Oct 4 3:00 -1:00 -
Rule Morocco 2037 only - Nov 15 2:00 0 -
Rule Morocco 2038 only - Sep 26 3:00 -1:00 -
Rule Morocco 2038 only - Oct 31 2:00 0 -
Rule Morocco 2039 only - Sep 18 3:00 -1:00 -
Rule Morocco 2039 only - Oct 23 2:00 0 -
Rule Morocco 2040 only - Sep 2 3:00 -1:00 -
Rule Morocco 2040 only - Oct 14 2:00 0 -
Rule Morocco 2041 only - Aug 25 3:00 -1:00 -
Rule Morocco 2041 only - Sep 29 2:00 0 -
Rule Morocco 2042 only - Aug 10 3:00 -1:00 -
Rule Morocco 2042 only - Sep 21 2:00 0 -
Rule Morocco 2043 only - Aug 2 3:00 -1:00 -
Rule Morocco 2043 only - Sep 13 2:00 0 -
Rule Morocco 2044 only - Jul 24 3:00 -1:00 -
Rule Morocco 2044 only - Aug 28 2:00 0 -
Rule Morocco 2045 only - Jul 9 3:00 -1:00 -
Rule Morocco 2045 only - Aug 20 2:00 0 -
Rule Morocco 2046 only - Jul 1 3:00 -1:00 -
Rule Morocco 2046 only - Aug 5 2:00 0 -
Rule Morocco 2047 only - Jun 23 3:00 -1:00 -
Rule Morocco 2047 only - Jul 28 2:00 0 -
Rule Morocco 2048 only - Jun 7 3:00 -1:00 -
Rule Morocco 2048 only - Jul 19 2:00 0 -
Rule Morocco 2049 only - May 30 3:00 -1:00 -
Rule Morocco 2049 only - Jul 4 2:00 0 -
Rule Morocco 2050 only - May 15 3:00 -1:00 -
Rule Morocco 2050 only - Jun 26 2:00 0 -
Rule Morocco 2051 only - May 7 3:00 -1:00 -
Rule Morocco 2051 only - Jun 18 2:00 0 -
Rule Morocco 2052 only - Apr 28 3:00 -1:00 -
Rule Morocco 2052 only - Jun 2 2:00 0 -
Rule Morocco 2053 only - Apr 13 3:00 -1:00 -
Rule Morocco 2053 only - May 25 2:00 0 -
Rule Morocco 2054 only - Apr 5 3:00 -1:00 -
Rule Morocco 2054 only - May 10 2:00 0 -
Rule Morocco 2055 only - Mar 28 3:00 -1:00 -
Rule Morocco 2055 only - May 2 2:00 0 -
Rule Morocco 2056 only - Mar 12 3:00 -1:00 -
Rule Morocco 2056 only - Apr 23 2:00 0 -
Rule Morocco 2057 only - Mar 4 3:00 -1:00 -
Rule Morocco 2057 only - Apr 8 2:00 0 -
Rule Morocco 2058 only - Feb 17 3:00 -1:00 -
Rule Morocco 2058 only - Mar 31 2:00 0 -
Rule Morocco 2059 only - Feb 9 3:00 -1:00 -
Rule Morocco 2059 only - Mar 23 2:00 0 -
Rule Morocco 2060 only - Feb 1 3:00 -1:00 -
Rule Morocco 2060 only - Mar 7 2:00 0 -
Rule Morocco 2061 only - Jan 16 3:00 -1:00 -
Rule Morocco 2061 only - Feb 27 2:00 0 -
Rule Morocco 2062 only - Jan 8 3:00 -1:00 -
Rule Morocco 2062 only - Feb 12 2:00 0 -
Rule Morocco 2062 only - Dec 31 3:00 -1:00 -
Rule Morocco 2063 only - Feb 4 2:00 0 -
Rule Morocco 2063 only - Dec 16 3:00 -1:00 -
Rule Morocco 2064 only - Jan 27 2:00 0 -
Rule Morocco 2064 only - Dec 7 3:00 -1:00 -
Rule Morocco 2065 only - Jan 11 2:00 0 -
Rule Morocco 2065 only - Nov 22 3:00 -1:00 -
Rule Morocco 2066 only - Jan 3 2:00 0 -
Rule Morocco 2066 only - Nov 14 3:00 -1:00 -
Rule Morocco 2066 only - Dec 26 2:00 0 -
Rule Morocco 2067 only - Nov 6 3:00 -1:00 -
Rule Morocco 2067 only - Dec 11 2:00 0 -
Rule Morocco 2068 only - Oct 21 3:00 -1:00 -
Rule Morocco 2068 only - Dec 2 2:00 0 -
Rule Morocco 2069 only - Oct 13 3:00 -1:00 -
Rule Morocco 2069 only - Nov 17 2:00 0 -
Rule Morocco 2070 only - Oct 5 3:00 -1:00 -
Rule Morocco 2070 only - Nov 9 2:00 0 -
Rule Morocco 2071 only - Sep 20 3:00 -1:00 -
Rule Morocco 2071 only - Nov 1 2:00 0 -
Rule Morocco 2072 only - Sep 11 3:00 -1:00 -
Rule Morocco 2072 only - Oct 16 2:00 0 -
Rule Morocco 2073 only - Aug 27 3:00 -1:00 -
Rule Morocco 2073 only - Oct 8 2:00 0 -
Rule Morocco 2074 only - Aug 19 3:00 -1:00 -
Rule Morocco 2074 only - Sep 30 2:00 0 -
Rule Morocco 2075 only - Aug 11 3:00 -1:00 -
Rule Morocco 2075 only - Sep 15 2:00 0 -
Rule Morocco 2076 only - Jul 26 3:00 -1:00 -
Rule Morocco 2076 only - Sep 6 2:00 0 -
Rule Morocco 2077 only - Jul 18 3:00 -1:00 -
Rule Morocco 2077 only - Aug 22 2:00 0 -
Rule Morocco 2078 only - Jul 10 3:00 -1:00 -
Rule Morocco 2078 only - Aug 14 2:00 0 -
Rule Morocco 2079 only - Jun 25 3:00 -1:00 -
Rule Morocco 2079 only - Aug 6 2:00 0 -
Rule Morocco 2080 only - Jun 16 3:00 -1:00 -
Rule Morocco 2080 only - Jul 21 2:00 0 -
Rule Morocco 2081 only - Jun 1 3:00 -1:00 -
Rule Morocco 2081 only - Jul 13 2:00 0 -
Rule Morocco 2082 only - May 24 3:00 -1:00 -
Rule Morocco 2082 only - Jun 28 2:00 0 -
Rule Morocco 2083 only - May 16 3:00 -1:00 -
Rule Morocco 2083 only - Jun 20 2:00 0 -
Rule Morocco 2084 only - Apr 30 3:00 -1:00 -
Rule Morocco 2084 only - Jun 11 2:00 0 -
Rule Morocco 2085 only - Apr 22 3:00 -1:00 -
Rule Morocco 2085 only - May 27 2:00 0 -
Rule Morocco 2086 only - Apr 14 3:00 -1:00 -
Rule Morocco 2086 only - May 19 2:00 0 -
Rule Morocco 2087 only - Mar 30 3:00 -1:00 -
Rule Morocco 2087 only - May 11 2:00 0 -
# For dates after the somewhat-arbitrary cutoff of 2087, assume that
# Morocco will no longer observe DST. At some point this table will
# need to be extended, though quite possibly Morocco will change the
# rules first.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
0:00 Morocco %z 1984 Mar 16
1:00 - %z 1986
0:00 Morocco %z 2018 Oct 28 3:00
1:00 Morocco %z
1:00 Morocco %z 2026 Sep 20 2:00
0:00 - %z
# Western Sahara
#
@@ -1088,7 +960,8 @@ Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
Zone Africa/El_Aaiun -0:52:48 - LMT 1934 Jan # El Aaiún
-1:00 - %z 1976 Apr 14
0:00 Morocco %z 2018 Oct 28 3:00
1:00 Morocco %z
1:00 Morocco %z 2026 Sep 20 2:00
0:00 - %z
# Botswana
# Burundi
+18 -6
View File
@@ -1544,9 +1544,21 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov
# leap year calculation involved. There has never been any serious
# plan to change that law....
#
# From Paul Eggert (2022-06-30):
# Go with Pournader for 1935 through spring 1979, and for timestamps
# after August 1991; go with with Shanks & Pottenger for other timestamps.
# From N.F. Hase (2026-07-26):
# Ettela'at (Tehran daily) printed a daily panel headed "taqvim-e
# Ettela'at / sa'at-ha-ye shar'i", attributed to Dr. Riyazi Kermani.
# Each panel gives today's maghrib followed by fajr, sunrise, solar noon
# and maghrib for the next day, together with the Iranian, Hijri and
# Gregorian dates.... 26 May 1979 (5 Khordād 1358)
# https://commons.wikimedia.org/wiki/File:Ettelaat13580305.pdf
# ... That also matches Movahedi's wording, that the government
# returned to DST on 26 May, and the note in the 2022 thread that the
# change was announced one day in advance on 25 May.
#
# From Paul Eggert (2026-07-27):
# Go with Pournader for 1935 through spring 1979 (with the last
# transition clarified by Hase), and for timestamps after August 1991;
# go with Shanks & Pottenger for other timestamps.
# Go with Santoni's citation of the UIT for fall 1977, as 20 October 1977
# is 28 Mehr 1356, consistent with the "Mehr" in Pournader's source.
# Assume that the UIT's "1930" is UTC, i.e., 24:00 local time.
@@ -1591,13 +1603,13 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov
#
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# Work around a bug in zic 2022a and earlier.
Rule Iran 1910 only - Jan 1 00:00 0 -
Rule Iran 1910 only - Jan 1 0:00 0 -
#
Rule Iran 1977 only - Mar 21 23:00 1:00 -
Rule Iran 1977 only - Oct 20 24:00 0 -
Rule Iran 1978 only - Mar 24 24:00 1:00 -
Rule Iran 1978 only - Aug 5 01:00 0 -
Rule Iran 1979 only - May 26 24:00 1:00 -
Rule Iran 1978 only - Aug 5 1:00 0 -
Rule Iran 1979 only - May 26 0:00 1:00 -
Rule Iran 1979 only - Sep 18 24:00 0 -
Rule Iran 1980 only - Mar 20 24:00 1:00 -
Rule Iran 1980 only - Sep 22 24:00 0 -
+1 -1
View File
@@ -1721,7 +1721,7 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila
# to Japanese rule was right before 1970, ... per the current tz database
# rule, the information doesn't warrant creation of a new timezone for Bonin
# Islands itself and is thus as an anecdotal note for interest purpose only.
# ... [The abovementioned link] described some special timekeeping phenomenon
# ... [The link mentioned above] described some special timekeeping phenomenon
# regarding Marcus island, another remote island currently owned by Japanese
# in the same administrative unit as Bonin Islands. Many reports claim that
# the American coastal guard on the American quarter of the island use its own
+49 -5
View File
@@ -15,7 +15,8 @@
# typically use this file for backward compatibility.
# This file is divided into sections, one for each major reason for a
# backward compatibility link. Each section is sorted by link name.
# backward compatibility link or zone. Each section of links is
# sorted by name.
# A "#= TARGET1" comment labels each link inserted only because some
# .zi parsers (including tzcode through 2022e) mishandle links to links.
@@ -46,7 +47,6 @@ Link America/Noronha Brazil/DeNoronha
Link America/Sao_Paulo Brazil/East
Link America/Manaus Brazil/West
Link Europe/Brussels CET
Link America/Chicago CST6CDT
Link America/Halifax Canada/Atlantic
Link America/Winnipeg Canada/Central
# This line is commented out, as the name exceeded the 14-character limit
@@ -63,7 +63,6 @@ Link Pacific/Easter Chile/EasterIsland
Link America/Havana Cuba
Link Europe/Athens EET
Link America/Panama EST
Link America/New_York EST5EDT
Link Africa/Cairo Egypt
Link Europe/Dublin Eire
# Vanguard section, for most .zi parsers.
@@ -104,7 +103,6 @@ Link Pacific/Kwajalein Kwajalein
Link Africa/Tripoli Libya
Link Europe/Brussels MET
Link America/Phoenix MST
Link America/Denver MST7MDT
Link America/Tijuana Mexico/BajaNorte
Link America/Mazatlan Mexico/BajaSur
Link America/Mexico_City Mexico/General
@@ -326,6 +324,52 @@ Link Europe/Kyiv Europe/Kiev
# However, for various reasons many users expect to find it under Europe.
Link Asia/Nicosia Europe/Nicosia
Link Pacific/Honolulu HST
Link America/Los_Angeles PST8PDT
Link Pacific/Guadalcanal Pacific/Ponape #= Pacific/Pohnpei
Link Pacific/Port_Moresby Pacific/Truk #= Pacific/Chuuk
# The backward-compatibility zones PST8PDT, MST7MDT, CST6CDT, and EST5EDT
# Near-copy of US rules in the northamerica file,
# so that this file can be compiled separately.
# To conform to POSIX, this copy uses D instead of W for War and P for Peace.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule USback 1918 1919 - Mar lastSun 2:00 1:00 D
Rule USback 1918 1919 - Oct lastSun 2:00 0 S
Rule USback 1942 only - Feb 9 2:00 1:00 D # War
Rule USback 1945 only - Aug 14 23:00u 1:00 D # Peace
Rule USback 1945 only - Sep 30 2:00 0 S
Rule USback 1967 2006 - Oct lastSun 2:00 0 S
Rule USback 1967 1973 - Apr lastSun 2:00 1:00 D
Rule USback 1974 only - Jan 6 2:00 1:00 D
Rule USback 1975 only - Feb lastSun 2:00 1:00 D
Rule USback 1976 1986 - Apr lastSun 2:00 1:00 D
Rule USback 1987 2006 - Apr Sun>=1 2:00 1:00 D
Rule USback 2007 max - Mar Sun>=8 2:00 1:00 D
Rule USback 2007 max - Nov Sun>=1 2:00 0 S
# From Arthur David Olson (2005-12-19):
# We generate the files specified below to guard against old files with
# obsolete information being left in the time zone binary directory.
# We limit the list to names that have appeared in previous versions of
# this time zone package.
# We do these as separate Zones rather than as Links to avoid problems if
# a particular place changes whether it observes DST.
#
# From Paul Eggert (2026-07-24):
# These zones are for backward compatibility with Unix System V (1983).
# They are ahistorical, in that they pretend standard time extends
# backward indefinitely into the past.
# They use USback (not US) rules so that they conform to POSIX instead
# of using abbreviations like EWT for Eastern War Time during World War II.
# The zones are here, not in the northamerica file, to lessen
# confusion downstream by making it clear that the zones are present
# only for backward compatibility.
# New software should use settings like TZ='America/New_York' instead
# of these backwards-compatibility zones.
#
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone PST8PDT -8:00 USback P%sT
Zone MST7MDT -7:00 USback M%sT
Zone CST6CDT -6:00 USback C%sT
Zone EST5EDT -5:00 USback E%sT
+7 -11
View File
@@ -465,7 +465,7 @@ Zone America/Aruba -4:40:24 - LMT 1912 Feb 12 # Oranjestad
#
# From Paul Eggert (2000-10-02):
# Matthews and Vincent (1998) write that Atikokan, Pickle Lake, and
# New Osnaburgh observe CST all year, that Big Trout Lake observes
# New Osnaburgh observe [EST] all year, that Big Trout Lake observes
# CST/CDT, and that Upsala and Shebandowan observe EST/EDT, all in
# violation of the official Ontario rules.
#
@@ -927,9 +927,10 @@ Zone America/Tortola -4:18:28 - LMT 1911 Jul # Road Town
-4:00 - AST
# Yellowknife, Northwest Territories
Zone America/Yellowknife 0 - -00 1935 # Yellowknife founded?
-7:00 NT_YK M%sT 1980
-7:00 Canada M%sT
# Commented out as too wrong to be useful.
#Zone America/Yellowknife 0 - -00 1935 # Yellowknife founded?
# -7:00 NT_YK M%sT 1980
# -7:00 Canada M%sT
# Dumont d'Urville, Île des Pétrels, -6640+14001, since 1956-11
# <https://en.wikipedia.org/wiki/Dumont_d'Urville_Station> (2005-12-05)
@@ -1757,13 +1758,12 @@ Zone Pacific/Majuro 11:24:48 - LMT 1901
# Midway
#
# From Mark Brader (2005-01-23):
# [Fallacies and Fantasies of Air Transport History, by R.E.G. Davies,
# published 1994 by Paladwr Press, McLean, VA, USA; ISBN 0-9626483-5-3]
# [<https://www.timetableimages.com/ttimages/pa/pa36/pa36.pdf>]
# reproduced a Pan American Airways timetable from 1936, for their weekly
# "Orient Express" flights between San Francisco and Manila, and connecting
# flights to Chicago and the US East Coast. As it uses some time zone
# designations that I've never seen before:....
# Fri. 6:30A Lv. HONOLOLU (Pearl Harbor), H.I. H.L.T. Ar. 5:30P Sun.
# Fri. 6:30A Lv. HONOLULU (Pearl Harbor), H.I. . H.L.T. Ar. 5:30P Sun.
# " 3:00P Ar. MIDWAY ISLAND . . . . . . . . . M.L.T. Lv. 6:00A "
#
Zone Pacific/Midway -11:49:28 - LMT 1901
@@ -1837,12 +1837,8 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone HST -10:00 - HST
Zone PST8PDT -8:00 US P%sT
Zone MST -7:00 - MST
Zone MST7MDT -7:00 US M%sT
Zone CST6CDT -6:00 US C%sT
Zone EST -5:00 - EST
Zone EST5EDT -5:00 US E%sT
Zone WET 0:00 EU WE%sT
Zone CET 1:00 C-Eur CE%sT
Zone MET 1:00 C-Eur ME%sT
+2 -1
View File
@@ -20,7 +20,8 @@
# which load the "UTC" file to handle seconds properly.
Zone Etc/UTC 0 - UTC
# Functions like gmtime load the "GMT" file to handle leap seconds properly.
# If leap second support is enabled, functions like gmtime
# load the "GMT" file to handle leap seconds properly.
# Vanguard section, which works with most .zi parsers.
#Zone GMT 0 - GMT
# Rearguard section, for TZUpdater 2.3.2 and earlier.
+108 -17
View File
@@ -230,7 +230,7 @@
# https://www.polyomino.org.uk/british-time/bbc-19410418.png
# https://www.polyomino.org.uk/british-time/ho-19410421.png
# From Sir Alexander Maxwell in the above-mentioned letter (1941-04-21):
# From Sir Alexander Maxwell (1941-04-21) in the letter mentioned above:
# [N]o official designation has as far as I know been adopted for the time
# which is to be introduced in May....
# I cannot think of anything better than "Double British Summer Time"
@@ -378,13 +378,33 @@
# as a negative daylight saving time in winter. So, in this database
# IST stands for Irish Summer Time for timestamps before 1968, and for
# Irish Standard Time after that. See:
# http://www.irishstatutebook.ie/eli/1971/act/17/enacted/en/print
# https://www.irishstatutebook.ie/eli/1971/act/17/enacted/en/print
# Michael Deckers (2017-06-01) gave the following URLs for Ireland's
# Summer Time Act, 1925 and Summer Time Orders, 1926 and 1947:
# http://www.irishstatutebook.ie/eli/1925/act/8/enacted/en/print
# http://www.irishstatutebook.ie/eli/1926/sro/919/made/en/print
# http://www.irishstatutebook.ie/eli/1947/sro/71/made/en/print
# https://www.irishstatutebook.ie/eli/1925/act/8/enacted/en/print
# https://www.irishstatutebook.ie/eli/1926/sro/919/made/en/print
# https://www.irishstatutebook.ie/eli/1947/sro/71/made/en/print
# From Stan Ulbrych (2026-09-12):
# Ireland's Summer Time Act, 1925 (No. 8 of 1925, see above)
# ended summer time at 02:00 GMT on the day after the third Saturday in
# September, that is, 1925-09-20. The UK's Summer Time Act, 1925, however,
# moved the UK's end date to the day after the first Saturday in October with
# immediate effect, but it did not apply to the Irish Free State.
# Ireland matched the October date only from 1926, via the Summer Time Order,
# 1926, whose recital replaces the period fixed by section 2 of the 1925 Act
# and mentions no earlier order. Moving approval of that order in the
# Dáil on 1926-03-24, Minister Kevin O'Higgins said:
#
# Deputies will remember that last year there was a discrepancy of a
# fortnight between the termination of Summer Time in the Saorstát and
# in Great Britain and Northern Ireland. As a result of that, serious
# inconvenience was caused to railway companies, and there was a certain
# amount of dislocation of postal services in the country.
#
# (See: https://www.oireachtas.ie/en/debates/debate/dail/1926-03-24/18/)
# So Dublin fell back on 1925-09-20, two weeks before London.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# Summer Time Act, 1916
@@ -537,6 +557,8 @@ Zone Europe/Dublin -0:25:21 - LMT 1880 Aug 2
-0:25:21 - DMT 1916 May 21 2:00s
-0:25:21 1:00 IST 1916 Oct 1 2:00s
0:00 GB-Eire %s 1921 Dec 6 # independence
0:00 GB-Eire GMT/IST 1925 Sep Sun>=16 2:00s
0:00 - GMT 1926
0:00 GB-Eire GMT/IST 1940 Feb 25 2:00s
0:00 1:00 IST 1946 Oct 6 2:00s
0:00 - GMT 1947 Mar 16 2:00s
@@ -1041,9 +1063,19 @@ Zone Atlantic/Faroe -0:27:04 - LMT 1908 Jan 11 # Tórshavn
# Greenland
#
# From Paul Eggert (2004-10-31):
# From Paul Eggert (2026-01-22):
# During World War II, Greenland was effectively independent of Denmark and
# observed daylight saving time. TIME, volume 37, page 23 (1941-04-21)
# <https://time.com/archive/6770243/war-peace-greenlands-icy-mountains/> says,
# "Penfield and West made their way to the U.S.'s most northerly consulate.
# They were astonished to find that Greenlanders, with almost 24 hours of
# sunlight a day during the summer, have daylight saving time."
# As the details are unknown they are omitted from the data for now.
#
# During World War II, Germany maintained secret manned weather stations in
# East Greenland and Franz Josef Land, but we don't know their time zones.
# Also, they're likely out of scope for the database
# as we lack resources to track every bit of military activity.
# My source for this is Wilhelm Dege's book mentioned under Svalbard.
#
# From Paul Eggert (2017-12-10):
@@ -1957,7 +1989,6 @@ Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 # Valletta
# From Stepan Golosunov (2016-03-07):
# the act of the government of the Republic of Moldova Nr. 132 from 1990-05-04
# http://lex.justice.md/viewdoc.php?action=view&view=doc&id=298782&lang=2
# ... says that since 1990-05-06 on the territory of the Moldavian SSR
# time would be calculated as the standard time of the second time belt
# plus one hour of the "summer" time. To implement that clocks would be
@@ -2006,15 +2037,67 @@ Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 # Valletta
# From Roman Tudos (2015-07-02):
# http://lex.justice.md/index.php?action=view&view=doc&lang=1&id=355077
# From Paul Eggert (2015-07-01):
# The abovementioned official link to IGO1445-868/2014 states that
# The above-mentioned official link to IGO1445-868/2014 states that
# 2014-10-26's fallback transition occurred at 03:00 local time. Also,
# https://www.trm.md/en/social/la-30-martie-vom-trece-la-ora-de-vara
# says the 2014-03-30 spring-forward transition was at 02:00 local time.
# Guess that since 1997 Moldova has switched one hour before the EU.
# From Heitor David Pinto (2026-02-22):
# Soviet Moldovan resolution 132 of 1990 defined the summer time period from
# the last Sunday in March at 2:00 to the last Sunday in September at 3:00,
# matching the dates used in most of Europe at the time:
# https://web.archive.org/web/20211107050832/http://lex.justice.md/viewdoc.php?action=view&view=doc&id=298782&lang=1
#
# It seems that in 1996 Moldova changed the end date to October like most of
# Europe, but kept the transitions at 2:00 and 3:00 rather than 1:00 UTC,
# which would have been locally 3:00 and 4:00....
#
# The notices in the Moldovan government website and broadcaster showed the
# transitions at 2:00 and 3:00 until 2021:
# 2015 https://old.gov.md/en/node/7304
# 2016 https://old.gov.md/en/node/12587
# 2017 https://old.gov.md/en/node/20654
# 2017 https://old.gov.md/en/content/moldova-upholds-winter-time-night-28-29-october
# 2018 https://old.gov.md/en/content/moldova-switch-summer-time
# 2018 https://old.gov.md/en/content/cabinet-ministers-informs-about-switch-winter-time-28-october
# 2019 https://old.gov.md/en/content/moldova-switch-summer-time-31-march
# 2019 https://old.gov.md/en/node/31122
# 2020 https://old.gov.md/en/node/32771
# 2020 https://old.gov.md/en/node/34497
# 2021 https://trm.md/ro/social/moldova-trece-in-aceasta-noapte-la-ora-de-vara
# 2021 https://trm.md/en/social/republica-moldova-trece-la-ora-de-iarna1
#
# However, since 2022, the notices showed the transitions at 3:00 and 4:00,
# matching the EU rule at 1:00 UTC:
# 2022 https://trm.md/en/social/in-acest-weekend-republica-moldova-trece-la-ora-de-vara
# 2022 https://old.gov.md/en/content/moldova-switch-winter-time
# 2023 https://moldova1.md/p/6587/ora-de-vara-2023-cum-schimbam-acele-ceasornicelor-si-cand-trecem-la-ora-de-vara
# 2023 https://old.gov.md/en/node/46662
# 2024 https://moldova1.md/p/26535/republica-moldova-trece-la-ora-de-vara-in-acest-weekend
# 2024 https://moldova1.md/p/37768/republica-moldova-trece-in-aceasta-noapte-la-ora-de-iarna
# 2025 https://moldova1.md/p/46349/republica-moldova-trece-la-ora-de-vara-pe-30-martie-cum-ne-afecteaza-si-ce-recomanda-medicii
# 2025 https://moldova1.md/p/60469/republica-moldova-trece-la-ora-de-iarna-ceasurile-se-dau-inapoi-cu-o-ora
#
# It seems that the changes to the end date and transition times were just
# done in practice without formally changing the resolution. In late 2025, the
# government said that the Soviet resolution was still in force, and proposed
# a new resolution to replace it and formally establish the EU rule:
# ... based on the notices, it seems that in practice Moldova already
# uses the EU rule since 2022. This was also the year when Moldova applied to
# join the EU.
#
# From Robert Bastian (2026-02-26):
# This has been approved and published in the government gazette:
# https://monitorul.gov.md/ro/monitorul/view/pdf/3234/part/2#page=27
#
# From Paul Eggert (2026-02-24):
# Also see Svetlana Rudenko, "Moldova abandons the 'Soviet era'", Logos Press,
# 2026-02-21 <https://logos-pres.md/en/news/moldova-abandons-the-soviet-era/>.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Moldova 1997 max - Mar lastSun 2:00 1:00 S
Rule Moldova 1997 max - Oct lastSun 3:00 0 -
Rule Moldova 1997 2021 - Mar lastSun 2:00 1:00 S
Rule Moldova 1997 2021 - Oct lastSun 3:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Chisinau 1:55:20 - LMT 1880
@@ -2027,7 +2110,8 @@ Zone Europe/Chisinau 1:55:20 - LMT 1880
2:00 Russia EE%sT 1992
2:00 E-Eur EE%sT 1997
# See Romania commentary for the guessed 1997 transition to EU rules.
2:00 Moldova EE%sT
2:00 Moldova EE%sT 2022
2:00 EU EE%sT
# Poland
@@ -2318,10 +2402,17 @@ Zone Europe/Lisbon -0:36:45 - LMT 1884
# https://oal.ul.pt/hora-legal/legislacao/
# working backward through references of revocation and abrogation to
# Decreto-Lei 47233 of 1966-10-01, the last time DST was abolished across the
# mainland and its adjacent islands. Because of that reference, it is
# therefore assumed that DST rules in the islands prior to 1966 were like that
# of the mainland, though most legislation of the time didn't explicitly
# specify DST practices for the islands.
# mainland and its adjacent islands.
#
# From Tim Parenti (2026-05-26):
# Observance of DST on the Azores and Madeira was explicitly covered by
# mainland legislation in:
# - Portaria 11767 of 1947-03-28 for 1947,
# - Portaria 12286 of 1948-02-19 for 1948, and
# - Decreto-Lei 37048 of 1948-09-07 through its revocation in 1966.
# (See mainland commentary, above.) However, most legislation prior to 1947
# didn't explicitly call out these "adjacent islands", so we assume that DST
# rules on the islands prior to 1947 were also like that of the mainland.
Zone Atlantic/Azores -1:42:40 - LMT 1884 # Ponta Delgada
-1:54:32 - HMT 1912 Jan 1 2:00u # Horta MT
# Vanguard section, for zic and other parsers that support %z.
@@ -2413,7 +2504,7 @@ Zone Atlantic/Madeira -1:07:36 - LMT 1884 # Funchal
# Nine O'clock <http://www.nineoclock.ro/POL/1778pol.html>
# (1998-10-23) reports that the switch occurred at
# 04:00 local time in fall 1998. For lack of better info,
# assume that Romania and Moldova switched to EU rules in 1997,
# assume that Romania switched to EU rules in 1997,
# the same year as Bulgaria.
#
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
@@ -2554,7 +2645,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
# http://astro.uni-altai.ru/~orion/blog/2011/11/novyie-granitsyi-chasovyih-poyasov-v-sssr/
#
# From Paul Eggert (2018-07-16):
# Perhaps someone could translate the above-mentioned link and use it
# Perhaps someone could translate the link mentioned above, and use it
# to correct our data for the ex-Soviet Union. It cites the following:
# «Поясное время и новые границы часовых поясов» / сост. П.Н. Долгов,
# отв. ред. Г.Д. Бурдун - М: Комитет стандартов, мер и измерительных
+4 -4
View File
@@ -60,15 +60,15 @@
#
# The following line shows the last update of this file in NTP timestamp:
#
#$ 3960835200
#$ 3992312697
#
# 2) Expiration date of the file given on a semi-annual basis: last June or last December
#
# File expires on 28 June 2026
# File expires on 28 June 2027
#
# Expire date in NTP timestamp:
#
#@ 3991593600
#@ 4023129600
#
#
# LIST OF LEAP SECONDS
@@ -117,4 +117,4 @@
# please see the readme file in the 'source' directory :
# https://hpiers.obspm.fr/iers/bul/bulc/ntp/sources/README
#
#h 49db2447 571e5e1b 2f002a53 9c8da8e4 39b8e49e
#h a9bad145 84c31c70 758402aa b37bfd54 5923836a
+4 -4
View File
@@ -70,7 +70,7 @@ Leap 2016 Dec 31 23:59:60 + S
# Any additional leap seconds will come after this.
# This Expires line is commented out for now,
# so that pre-2020a zic implementations do not reject this file.
#Expires 2026 Jun 28 00:00:00
#Expires 2027 Jun 28 00:00:00
# Here are POSIX timestamps for the data in this file.
# "#updated" gives the last time the leap seconds data changed
@@ -79,8 +79,8 @@ Leap 2016 Dec 31 23:59:60 + S
# "#expires" gives the first time this file might be wrong;
# if this file was derived from the IERS leap-seconds.list,
# this is typically a bit less than one year after "updated".
#updated 1751846400 (2025-07-07 00:00:00 UTC)
#expires 1782604800 (2026-06-28 00:00:00 UTC)
#updated 1783323897 (2026-07-06 07:44:57 UTC)
#expires 1814140800 (2027-06-28 00:00:00 UTC)
# Updated through IERS Bulletin C (https://hpiers.obspm.fr/iers/bul/bulc/bulletinc.dat)
# File expires on 28 June 2026
# File expires on 28 June 2027
+281 -22
View File
@@ -96,7 +96,7 @@
# was the first nationwide legal time standard, and apparently
# time was just called "Standard Time" or "Daylight Saving Time".
# From Paul Eggert (2019-06-04):
# From Paul Eggert (2019-06-04) and Tim Parenti (2026-07-21):
# Here is the legal basis for the US federal rules.
# * Public Law 65-106 (1918-03-19) implemented standard and daylight saving
# time for the first time across the US, springing forward on March's last
@@ -111,10 +111,15 @@
# * Public Law 89-387 (1966-04-13) reinstituted a national standard for DST,
# from April's last Sunday to October's last Sunday, effective 1967.
# https://www.govinfo.gov/content/pkg/STATUTE-80/pdf/STATUTE-80-Pg107.pdf
# * Public Law 93-182 (1973-12-15) moved the 1974 spring-forward to 01-06.
# * Public Law 93-182 (1973-12-15) applied DST year-round as an emergency
# measure. It took effect on the fourth Sunday after its enactment,
# effectively moving the 1974 spring-forward to 01-06.
# https://www.govinfo.gov/content/pkg/STATUTE-87/pdf/STATUTE-87-Pg707.pdf
# * Public Law 93-434 (1974-10-05) moved the 1975 spring-forward to
# February's last Sunday.
# It was meant to last for 16 months or two winters (through 1975-04-27);
# however...
# * Public Law 93-434 (1974-10-05) created an exemption for much of the second
# winter, restoring standard time from the usual date of 1974-10-27 while
# moving the 1975 spring-forward up to February's last Sunday.
# https://www.govinfo.gov/content/pkg/STATUTE-88/pdf/STATUTE-88-Pg1209.pdf
# * Public Law 99-359 (1986-07-08) moved the spring-forward to April's first
# Sunday.
@@ -575,8 +580,12 @@ Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u
# Russian time, and it is more accurate to model this than to ignore it.
# The database format requires an exact transition time; use the Russian
# salute as a somewhat-arbitrary time for the formal transfer of control for
# all of Alaska. Sitka's UTC offset is -9:01:13; adjust its 15:30 to the
# local times of other Alaskan locations so that they change simultaneously.
# all of Alaska.
#
# From Tim Parenti (2026-08-26):
# Sitka's UT offset changed from +14:58:47 to -9:01:13, so effectuate this
# change at 15:30:00 +14:58:47, or 1867-10-19 00:31:13 UT in the Alaskan
# locations below.
# From Paul Eggert (2014-07-18):
# One opinion of the early 1980s turmoil in Alaska over time zones and
@@ -656,7 +665,7 @@ Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u
# and are west of 169.5° W.
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 15:33:32
Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 0:31:13u
-8:57:41 - LMT 1900 Aug 20 12:00
-8:00 - PST 1942
-8:00 US P%sT 1946
@@ -666,7 +675,7 @@ Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 15:33:32
-8:00 US P%sT 1983 Oct 30 2:00
-9:00 US Y%sT 1983 Nov 30
-9:00 US AK%sT
Zone America/Sitka 14:58:47 - LMT 1867 Oct 19 15:30
Zone America/Sitka 14:58:47 - LMT 1867 Oct 19 0:31:13u
-9:01:13 - LMT 1900 Aug 20 12:00
-8:00 - PST 1942
-8:00 US P%sT 1946
@@ -674,7 +683,7 @@ Zone America/Sitka 14:58:47 - LMT 1867 Oct 19 15:30
-8:00 US P%sT 1983 Oct 30 2:00
-9:00 US Y%sT 1983 Nov 30
-9:00 US AK%sT
Zone America/Metlakatla 15:13:42 - LMT 1867 Oct 19 15:44:55
Zone America/Metlakatla 15:13:42 - LMT 1867 Oct 19 0:31:13u
-8:46:18 - LMT 1900 Aug 20 12:00
-8:00 - PST 1942
-8:00 US P%sT 1946
@@ -684,14 +693,14 @@ Zone America/Metlakatla 15:13:42 - LMT 1867 Oct 19 15:44:55
-9:00 US AK%sT 2018 Nov 4 2:00
-8:00 - PST 2019 Jan 20 2:00
-9:00 US AK%sT
Zone America/Yakutat 14:41:05 - LMT 1867 Oct 19 15:12:18
Zone America/Yakutat 14:41:05 - LMT 1867 Oct 19 0:31:13u
-9:18:55 - LMT 1900 Aug 20 12:00
-9:00 - YST 1942
-9:00 US Y%sT 1946
-9:00 - YST 1969
-9:00 US Y%sT 1983 Nov 30
-9:00 US AK%sT
Zone America/Anchorage 14:00:24 - LMT 1867 Oct 19 14:31:37
Zone America/Anchorage 14:00:24 - LMT 1867 Oct 19 0:31:13u
-9:59:36 - LMT 1900 Aug 20 12:00
-10:00 - AST 1942
-10:00 US A%sT 1967 Apr
@@ -699,7 +708,7 @@ Zone America/Anchorage 14:00:24 - LMT 1867 Oct 19 14:31:37
-10:00 US AH%sT 1983 Oct 30 2:00
-9:00 US Y%sT 1983 Nov 30
-9:00 US AK%sT
Zone America/Nome 12:58:22 - LMT 1867 Oct 19 13:29:35
Zone America/Nome 12:58:22 - LMT 1867 Oct 19 0:31:13u
-11:01:38 - LMT 1900 Aug 20 12:00
-11:00 - NST 1942
-11:00 US N%sT 1946
@@ -708,7 +717,7 @@ Zone America/Nome 12:58:22 - LMT 1867 Oct 19 13:29:35
-11:00 US B%sT 1983 Oct 30 2:00
-9:00 US Y%sT 1983 Nov 30
-9:00 US AK%sT
Zone America/Adak 12:13:22 - LMT 1867 Oct 19 12:44:35
Zone America/Adak 12:13:22 - LMT 1867 Oct 19 0:31:13u
-11:46:38 - LMT 1900 Aug 20 12:00
-11:00 - NST 1942
-11:00 US N%sT 1946
@@ -1737,11 +1746,56 @@ Zone America/Toronto -5:17:32 - LMT 1895
-5:00 Canada E%sT 1946
-5:00 Toronto E%sT 1974
-5:00 Canada E%sT
# For Atikokan see America/Panama.
# From Tim Parenti (2026-09-21), per Paul Eggert (2000-10-02, 2006-07-17):
# In the northwest of the province, most portions of Kenora, Rainy River, and
# Thunder Bay Districts lying broadly west of 90°W longitude have historically
# been aligned with neighboring Manitoba and use America/Winnipeg, in
# accordance with section 2(2) of Ontario's Time Act, RSO 1990 chapter T.9:
# https://www.ontario.ca/laws/statute/90t09
# With Manitoba now opting to stay on -05 year-round, if any of these areas do
# not follow, it would require a new zone; however, given the short leadtime
# ahead of a potential divergence on 2026-11-01 and in the interest of not
# creating zones that may not be needed, assume for the time being that they
# will.
#
# In practice, there are several exceptions to the 90°W dividing line set by
# the province, all of which technically contravene the official Ontario rules:
# - An area around Big Trout Lake in Kenora District observes Central Time
# (-06/-05) despite extending east of 90°W.
# - An area around Upsala in the southwest of Thunder Bay District observes
# Eastern Time (-05/-04) like America/Toronto despite extending west of
# 90°W.
# - Atikokan in the east of Rainy River District has observed year-round -05
# (EST) since at least 1952; this matches America/Panama since our 1970
# cutoff.
# - Pickle Lake and the Mishkeegogamang First Nation (formerly New Osnaburgh)
# in Kenora District have also observed year-round -05 (EST) since at least
# 1998, though it is less clear how far back that arrangement goes; assume
# the area is covered in the same way as Atikokan.
# See the 'backzone' file for further commentary.
# At time of writing, it is not yet known to what extent Manitoba's 2026-09-17
# announcement may spur further adaptations in northwestern Ontario; see
# Manitoba, below.
# Manitoba
# From Paul Eggert (2026-05-08):
# For 1916 timestamps America/Winnipeg covers only a small region. See:
# Cassidy C. Winnipeg’s 110-year history with daylight time.
# Winnipeg Free Press. 2026-05-06.
# https://www.winnipegfreepress.com/our-communities/correspondents/2026/05/06/winnipegs-110-year-history-with-daylight-time
# Of the 1916 experiment, Cassidy writes: “As rural areas and nearby
# urban centres such as Selkirk and Brandon did not adopt DST, the
# City of Winnipeg essentially had its own time zone.” Cassidy also
# writes that province-wide DST came into effect on 1963-05-12.
#
# Shanks & Pottenger write that Winnipeg did not observe DST in 1964 and 1965.
# Although dubious in the light of Cassidy’s article, we lack a better source.
# Perhaps S&P’s data are for the train stations, not for the city?
# Also, S&P say Manitoba switched at 02:00 (not 02:00s) starting in 1966.
# Since 02:00s is clearly correct for 1967 on, assume 02:00s in 1966 too.
# From Rob Douglas (2006-04-06):
# the old Manitoba Time Act - as amended by Bill 2, assented to
# March 27, 1987 ... said ...
@@ -1756,10 +1810,39 @@ Zone America/Toronto -5:17:32 - LMT 1895
# the 1987 version would apply - the changeover was at 2:00 Central
# Standard Time (i.e. not until 3:00 Central Daylight Time).
# From Paul Eggert (2006-04-10):
# Shanks & Pottenger say Manitoba switched at 02:00 (not 02:00s)
# starting 1966. Since 02:00s is clearly correct for 1967 on, assume
# it was also 02:00s in 1966.
# From Tim Parenti (2026-09-29):
# As much of western Canada began announcing year-round DST in early 2026,
# Manitoba Premier Wab Kinew publicly mused on forming a "Prairie time zone" by
# joining Saskatchewan and Alberta on year-round -06, while committing to
# conducting a public engagement survey on the matter. The results, however,
# showed that while "[a] total of 92 per cent of Manitobans surveyed wanted to
# see an end to seasonal time changes", "[a] majority of Manitobans (58 per
# cent) preferred to stay on permanent DST, while 34 per cent voted to
# eliminate the time change but stay on standard time."
#
# The survey results were published on Thursday 2026-09-17 alongside a policy
# announcement adopting permanent DST, or year-round -05, just over 6 weeks
# before clocks would otherwise fall back on 2026-11-01.
# https://news.gov.mb.ca/news/?item=75397
# https://www.cbc.ca/news/canada/manitoba/daylight-time-manitoba-9.7347844
#
# While other potential options would have required further legislation, the
# Official Time Amendment Act (Bill 2 of the 42nd Legislature's 5th Session),
# assented to 2023-05-30, provides for year-round -05 upon proclamation.
# https://web2.gov.mb.ca/laws/statutes/2023/pdf/c00423.pdf
# Order in Council 221/2026, issued 2026-09-23, directed the proclamation
# bringing the Act into force on 2026-10-31, 26 hours before clocks would
# otherwise fall back.
# https://oic.gov.mb.ca/OICDocs/2026/09/Municipal%20and%20Northern%20Relations.260923.%20Official%20Time%20Amendment%20Act.2212026.pdf
# https://web2.gov.mb.ca/laws/statutes/proclamations/2023c4(2026-10-31).pdf
#
# The Act further allows for the Lieutenant Governor in Council to, on
# recommendation of the relevant minister, "make regulations varying the
# reckoning" of official time in Manitoba, provided the minister has "due
# regard for the applicable time zone in neighbouring jurisdictions."
#
# Use a temporary hack like Alberta’s to work around potential CLDR
# limitations.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Winn 1916 only - Apr 23 0:00 1:00 D
@@ -1789,7 +1872,11 @@ Rule Winn 1987 2005 - Apr Sun>=1 2:00s 1:00 D
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Winnipeg -6:28:36 - LMT 1887 Jul 16
-6:00 Winn C%sT 2006
-6:00 Canada C%sT
-6:00 Canada C%sT 2026 Oct 31
# Temporary hack; see above.
-6:00 Canada CDT 2026 Nov 1 2:00
# End of temporary hack.
-5:00 - EST
# Saskatchewan
@@ -1852,6 +1939,28 @@ Zone America/Winnipeg -6:28:36 - LMT 1887 Jul 16
# long and rather painful to read.
# http://www.qp.gov.sk.ca/documents/English/Statutes/Statutes/T14.pdf
# From Heitor David Pinto (2026-05-14):
# In Saskatchewan, a bill was passed to replace the Time Act. It sets UTC-6 all
# year in the whole province, including Lloydminster, but allows the government
# to issue regulations specifying a different time in localities that request
# so:
# https://docs.legassembly.sk.ca/legdocs/Bills/30L2S/Bill30-58.pdf
# The bill ... received royal assent today.
# From Tim Parenti (2026-05-14):
# In light of Alberta joining Saskatchewan on year-round -06, this simplifies
# the prior Act's framework for the many local exceptions to year-round -06 in
# border areas, by extending province-wide the notion of "time option areas"
# which can be prescribed by regulation "if it is in the provincial interest"
# for those areas to observe either "UTC-5, UTC-6 or UTC-7 for all or part of
# the year" on at least 30 days' notice.
# The new Act comes into force by order of the Lieutenant Governor in Council.
# From Tim Parenti (2026-09-21):
# With Manitoba now adopting year-round -05, the area around Creighton will
# likely wish to follow. As the area doesn't have a special charter like
# Lloydminster, the existing de facto arrangement technically violates
# provincial law already, but once the new Act takes effect it will better
# allow for continued alignment with Manitoba, per the above.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Regina 1918 only - Apr 14 2:00 1:00 D
Rule Regina 1918 only - Oct 27 2:00 0 S
@@ -1902,6 +2011,49 @@ Zone America/Swift_Current -7:11:20 - LMT 1905 Sep
# Boyer JP. Forcing Choice: The Risky Reward of Referendums. Dundum. 2017.
# ISBN 978-1459739123.
# From Roozbeh Pournader (2026-04-20):
# https://calgaryherald.com/opinion/columnists/bell-alberta-daylight-time-year-round-premier-danielle-smith
#
# From Tim Parenti (2026-04-23):
# Section 3 of Bill 31, the Red Tape Reduction Statutes Amendment Act, 2026
# https://docs.assembly.ab.ca/LADDAR_files/docs/bills/bill/legislature_31/session_2/20251023_bill-031.pdf
# would repeal the Daylight Saving Time Act in the Revised Statutes of Alberta
# 2000 Chapter D-5:
# https://web.archive.org/web/20240128134751/https://kings-printer.alberta.ca/documents/Acts/D05.pdf
# ...and substitutes a new chapter with language that closely parallels the
# original. The new title is the Official Time Act and will be numbered
# Chapter O-5.7. The Act establishes a standard time of UTC−6 without
# replacing the language previously used to effectuate DST.
#
# From Tim Parenti (2026-06-19):
# After receiving Royal Assent on 2026-05-14, Order in Council 204/2026 was
# issued on 2026-06-18 proclaiming the relevant section of the bill in force on
# the same date. Order in Council 206/2026, issued the same day, uses the
# regulatory authority within the Act to prescribe the official term "Alberta
# Time"; we use the traditional abbreviation CST for consistency.
# https://kings-printer.alberta.ca/Documents/Orders/Orders_in_Council/2026/2026_204.pdf
# https://kings-printer.alberta.ca/Documents/Orders/Orders_in_Council/2026/2026_206.pdf
#
# Since wall clock times do not diverge from past practice until 2026-11-01,
# use that transition date for now to work around potential CLDR limitations in
# the meantime; see British Columbia, below.
#
# From Paul Eggert (2026-07-02):
# The temporary hack for Alberta is needed for CLDR 48.2 (2026-03-17)
# and earlier, not the CLDR 48.1-and-earlier which drives BC’s temporary hack.
# Only a few platforms track minor CLDR releases, though, so the two
# temporary hacks have roughly the same effect in practice.
#
# The term “Alberta Time” is legally prescribed from yesterday until
# 2031-06-30, when the regulation in OiC 206/2026 expires to ensure that the
# term is reviewed by then for relevancy and need. This plan for possible
# obsolescence affects neither timekeeping nor TZDB’s data, which do
# not contain the string “Alberta Time”.
#
# From Tim Parenti (2026-07-21):
# The new Official Time Act is now in the Revised Statutes as Chapter O-5.7:
# https://kings-printer.alberta.ca/documents/Acts/O05p7.pdf
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Edm 1918 1919 - Apr Sun>=8 2:00 1:00 D
Rule Edm 1918 only - Oct 27 2:00 0 S
@@ -1919,7 +2071,11 @@ Rule Edm 1972 2006 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Edmonton -7:33:52 - LMT 1906 Sep
-7:00 Edm M%sT 1987
-7:00 Canada M%sT
-7:00 Canada M%sT 2026 Jun 18
# Temporary hack; see above.
-7:00 Canada MDT 2026 Nov 1 2:00
# End of temporary hack.
-6:00 - CST
# British Columbia
@@ -1957,6 +2113,82 @@ Zone America/Edmonton -7:33:52 - LMT 1906 Sep
# https://searcharchives.vancouver.ca/daylight-saving-1918-starts-again-july-7-1941-start-d-s-sept-27-end-of-d-s-1941
# We have no further details, so omit them for now.
# From Arthur David Olson (2026-03-02):
# B. C. Gov News: “Adopting permanent daylight saving time: ‘Spring forward’
# on March 8 will be the last time change, ending twice-yearly clock changes.”
# https://news.gov.bc.ca/releases/2026AG0013-000209
#
# From Paul Eggert (2026-09-23):
# The law says that 21 hours after the usual 2026-03-08 02:00 switch from
# PST to PDT, the next day inaugurated the new standard time Pacific Time,
# i.e., just one clock change but two name changes separated by 21 hours.
# PT, the obvious abbreviation for Pacific Time, is one letter too short
# to conform to TZDB’s (and POSIX’s) [-+[:alnum:]]{3,6} requirements.
# For now, do this:
# 1. As a temporary hack, pretend that the BC law takes effect
# not on 2026-03-09 at 00:00, but on 2026-11-01 at 02:00.
# This pretense works around a limitation in CLDR 48.1 (2026-01-08),
# which would otherwise say the interval uses “Pacific Standard Time”.
# (Below, this temporary hack is marked “Temporary hack; see above.”)
# Strictly speaking this hack is incorrect since the interval uses
# standard time, but it does have the right UT offset and it
# works around the CLDR limitation. We should be able to remove
# the temporary hack by November when there would be little point
# to keeping it anyway.
# 2. After the BC law takes effect, model the time as MST sans DST.
# We can change this later if another conforming non-numeric abbreviation
# for Pacific Time becomes more popular. Possibilities include:
# MST - the most compatible with existing software and practice,
# and already used in parts of BC and in Yukon
# PDT - almost as software-friendly, but confusing because it implies
# it is DST and is paired with PST, whereas PT is standard time
# -07 - accurate and clear in itself, but makes BC look odd vs neighbors
# PCT - as I understand it, inspired by the phrase “Pacific Coast Time”
# though legally it’s “Pacific Time”; suggested by the BC government
# <https://news.gov.bc.ca/releases/2026CITZ0009-001073>
# From Tim Parenti (2026-08-21):
# In the southeast of the province, the Regional District of East Kootenay
# (RDEK), Columbia Shuswap Regional District’s Electoral Area A (Rural Golden),
# and the Town of Golden have all historically been aligned with neighboring
# Alberta and use America/Edmonton.
#
# Shortly after the BC provincial government announced its adoption of
# year-round -07, the RDEK Board of Directors on 2026-03-13 initially voted
# narrowly, 8–7, that it would fall back one last time to rejoin the rest of BC
# on -07 from November 2026. However, citing the rushed decision and lack of
# feedback from residents, Mayor Steve Fairbairn of Elkford used his power to
# ask the question be called a second time, remarking, “Pardon the pun, but
# this is not a time-sensitive issue,” and the initial decision was rescinded
# by the RDEK Board at its 2026-04-10 meeting.
# https://www.cbc.ca/news/canada/british-columbia/what-time-is-it-in-the-east-kootenay-debate-9.7132624
# In the ensuing months, after Alberta announced and implemented its similar
# shift to “permanent DST” (see above), RDEK coordinated a public survey across
# all of the relevant BC communities. The survey found 89% of respondents in
# favor of ending seasonal time changes, with 66% of that group preferring to
# remain aligned with Alberta time on year-round -06 instead of the rest of BC.
# In line with those results, the RDEK Board adopted year-round -06 at its
# 2026-08-14 meeting.
# https://www.cbc.ca/news/canada/british-columbia/east-kootenay-stops-changing-clocks-9.7308201
#
# From Tim Parenti (2026-09-24):
# Echoing RDEK’s earlier false step, the Town of Golden initially opted for
# year-round -07 by a 4–2 Council vote on 2026-09-01. This was met with
# significant pushback from residents preferring to maintain the existing
# alignment with RDEK and Alberta, with a formal petition swiftly gathering
# 2,395 signatures in two weeks from the town of 3,986 and some smaller
# neighboring communities. In response, Council unanimously rescinded the
# resolution at the following meeting on 2026-09-22, and unanimously replaced
# it with year-round -06 to keep the regional alignment.
# Acknowledging that “its initial move was driven in part by concerns about
# dark winter mornings and pedestrian safety for children travelling to
# school”, the new resolution directs town staff to partner on safety supports
# and commits to reviewing the decision and its impacts in October 2027.
# https://www.ctvnews.ca/calgary/article/golden-bc-council-reverses-course-on-time-zone-opts-for-mountain-daylight-time/
# At time of writing, the surrounding CSRD Area A is yet to formalize its own
# decision following a 2026-09-10 deferral “to gather and assess further
# information”, but is expected to follow.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Vanc 1918 only - Apr 14 2:00 1:00 D
Rule Vanc 1918 only - Oct 27 2:00 0 S
@@ -1970,7 +2202,11 @@ Rule Vanc 1962 2006 - Oct lastSun 2:00 0 S
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Vancouver -8:12:28 - LMT 1884
-8:00 Vanc P%sT 1987
-8:00 Canada P%sT
-8:00 Canada P%sT 2026 Mar 9
# Temporary hack; see above.
-8:00 Canada PDT 2026 Nov 1 2:00
# End of temporary hack.
-7:00 - MST
Zone America/Dawson_Creek -8:00:56 - LMT 1884
-8:00 Canada P%sT 1947
-8:00 Vanc P%sT 1972 Aug 30 2:00
@@ -2296,6 +2532,25 @@ Zone America/Fort_Nelson -8:10:47 - LMT 1884
# about 1970, and uses PST for standard time in Yukon since then. Consistent
# with that, use MST for -07, the new standard time in Yukon effective Nov. 1.
# From Tim Parenti (2026-04-21):
# "[Northwest Territories] Premier R.J. Simpson announced Monday that the
# territory will move to end seasonal time changes and will adopt a year-round
# time standard instead. ... Simpson has previously said the territory wouldn't
# end seasonal time changes until Alberta does."
# https://www.cbc.ca/news/canada/north/nwt-ends-daylight-saving-9.7170964
#
# From Tim Parenti (2026-07-24):
# Now that Alberta has adopted year-round -06, NWT plans to follow through with
# the same. Bill 13 of the 19th Assembly's 2nd Session, assented to
# 2021-03-31, provides the NWT Commissioner in Executive Council with authority
# to fix a year-round standard time:
# https://www.ntlegislativeassembly.ca/sites/default/files/legacy/bill_13_-_reprint_-_interpretation_a.pdf
#
# From Paul Eggert (2026-08-21):
# The regulations were registered 2026-08-18 and came into force today:
# https://www.justice.gov.nt.ca/en/files/legislation/interpretation/interpretation.r2.pdf
# Use a temporary hack like Alberta’s.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule NT_YK 1918 only - Apr 14 2:00 1:00 D
Rule NT_YK 1918 only - Oct 27 2:00 0 S
@@ -2337,7 +2592,11 @@ Zone America/Cambridge_Bay 0 - -00 1920 # trading post est.?
Zone America/Inuvik 0 - -00 1953 # Inuvik founded
-8:00 NT_YK P%sT 1979 Apr lastSun 2:00
-7:00 NT_YK M%sT 1980
-7:00 Canada M%sT
-7:00 Canada M%sT 2026 Aug 21
# Temporary hack; see above.
-7:00 Canada MDT 2026 Nov 1 2:00
# End of temporary hack.
-6:00 - CST
Zone America/Whitehorse -9:00:12 - LMT 1900 Aug 20
-9:00 NT_YK Y%sT 1965
-9:00 Yukon Y%sT 1966 Feb 27 0:00
+16 -13
View File
@@ -1330,20 +1330,9 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# promulgated 2022-07-14 and published 2022-08-13:
# https://www.diariooficial.interior.gob.cl/publicaciones/2022/08/13/43327/01/2172567.pdf
# https://www.bcn.cl/leychile/navegar?idNorma=1179983
#
# From Paul Eggert (2022-08-17):
# Although the presidential decree stops at fall 2026, assume that
# similar DST rules will continue thereafter.
# From Paul Eggert (2025-01-15):
# Diario Regional Aysén's Sebastián Martel reports that 94% of Aysén
# citizens polled in November favored changing the rules from
# -04/-03-with-DST to -03 all year...
# https://www.diarioregionalaysen.cl/noticia/actualidad/2024/12/presentan-decision-que-gano-la-votacion-sobre-el-cambio-del-huso-horario-en-aysen
#
# From Yonathan Dossow (2025-03-20):
# [T]oday we have more confirmation of the change. [Aysén] region will keep
# UTC-3 all year...
# [Aysén] region will keep UTC-3 all year...
# https://www.cnnchile.com/pais/region-de-aysen-mantendra-horario-de-verano-todo-el-ano_20250320/
# https://www.latercera.com/nacional/noticia/tras-consulta-ciudadana-region-de-aysen-mantendra-el-horario-de-verano-durante-todo-el-ano/
# https://x.com/min_interior/status/1902692504270672098
@@ -1355,6 +1344,14 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# https://www.bcn.cl/leychile/Navegar?idNorma=1211955
# Model this as a change to standard offset effective 2025-03-20.
# From Paul Eggert (2026-08-11):
# Chile’s timekeeping regime is renewed by Decreto 98 of 2026 of the
# Ministry of the Interior, Undersecretariat of the Interior,
# promulgated 2026-06-30 and published 2026-07-02:
# https://www.bcn.cl/leychile/navegar?idNorma=1225724
# Although this decree stops at fall 2029, assume that
# similar DST rules will continue thereafter.
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Chile 1927 1931 - Sep 1 0:00 1:00 -
Rule Chile 1928 1932 - Apr 1 0:00 0 -
@@ -1472,13 +1469,19 @@ Zone Antarctica/Palmer 0 - -00 1965
# Milne gives 4:56:16.4 for Bogotá time in 1899. He writes,
# "A variation of fifteen minutes in the public clocks of Bogota is not rare."
# From Paul Eggert (2026-07-17):
# The 1992 spring forward was May 2 at 00:00. See:
# Jiménez FA. La noche en que Colombia perdió una hora para encarar el apagón,
# ¿se repetirá la historia en 2026? El Colombiano. 2026-06-21.
# https://www.elcolombiano.com/negocios/colombia-perdio-una-hora-para-evitar-apagon-horario-gaviria-LF37983109
# From Alois Treindl (2022-11-10):
# End of time change in Colombia 1993 ... should be 6 February 24h ...
# DECRETO 267 DE 1993
# https://www.suin-juriscol.gov.co/viewDocument.asp?ruta=Decretos/1061335
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule CO 1992 only - May 3 0:00 1:00 -
Rule CO 1992 only - May 2 0:00 1:00 -
Rule CO 1993 only - Feb 6 24:00 0 -
# Zone NAME STDOFF RULES FORMAT [UNTIL]
#STDOFF -4:56:16.4
+51 -48
View File
@@ -3,14 +3,17 @@
<head>
<title>Theory and pragmatics of the tz code and data</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
pre {margin-left: 2em; white-space: pre-wrap;}
dd {margin-left: 1.3rem;}
pre {margin-left: 1.3rem; overflow: auto;}
ul {padding-left: 1.3rem;}
</style>
</head>
<body>
<main>
<h1>Theory and pragmatics of the <code><abbr>tz</abbr></code> code and data</h1>
<h3>Outline</h3>
<nav>
<ul>
<li><a href="#scope">Scope of the <code><abbr>tz</abbr></code>
@@ -24,10 +27,10 @@
<li><a href="#leapsec">Leap seconds</a></li>
<li><a href="#calendar">Calendrical issues</a></li>
<li><a href="#planets">Time and time zones off earth</a></li>
<li><a href="#see-also">See also</a></li>
</ul>
</nav>
<section>
<h2 id="scope">Scope of the <code><abbr>tz</abbr></code> database</h2>
<p>
The <a
@@ -63,7 +66,7 @@ time (<abbr>DST</abbr>),
and <code>America/Phoenix</code> which does not observe <abbr>DST</abbr>.
Applications that also deal with past timestamps in the mountain time
zone can choose from over a dozen timezones, such as
<code>America/Boise</code>, <code>America/Edmonton</code>, and
<code>America/Boise</code> and
<code>America/Hermosillo</code>, each of which currently uses mountain
time but differs from other timezones for some timestamps after 1970.
</p>
@@ -110,9 +113,6 @@ It does not always make sense to talk about a timezone’s
“base offset”, which is not necessarily a single number.
</p>
</section>
<section>
<h2 id="naming">Timezone identifiers</h2>
<p>
Each timezone has a name that uniquely identifies the timezone.
@@ -343,8 +343,7 @@ These legacy names are mostly defined in the file
"<code>etcetera</code>".
Also, the file "<code>backward</code>" defines the legacy names
<code>Etc/GMT0</code>, <code>Etc/GMT-0</code>, <code>Etc/GMT+0</code>,
<code>GMT0</code>, <code>GMT-0</code> and <code>GMT+0</code>,
and the file "<code>northamerica</code>" defines the legacy names
<code>GMT0</code>, <code>GMT-0</code>, <code>GMT+0</code>,
<code>EST5EDT</code>, <code>CST6CDT</code>,
<code>MST7MDT</code>, and <code>PST8PDT</code>.
</li>
@@ -385,11 +384,11 @@ and <code>zone.tab</code>.
<p>
The database defines each timezone name to be a zone, or a link to a zone.
The source file <code>backward</code> defines links for backward
compatibility; it does not define zones.
The source file <code>backward</code> defines links
and a few zones for backward compatibility.
Although <code>backward</code> was originally designed to be optional,
nowadays distributions typically use it
and no great weight should be attached to whether a link
and no great weight should be attached to whether a link or zone
is defined in <code>backward</code> or in some other file.
The source file <code>etcetera</code> defines names that may be useful
on platforms that do not support proleptic <code>TZ</code> strings
@@ -402,9 +401,7 @@ second information on platforms that support leap seconds.
Another <code>etcetera</code> name, <code>GMT</code>,
is used by older code releases.
</p>
</section>
<section>
<h2 id="abbreviations">Time zone abbreviations</h2>
<p>
When this package is installed, it generates time zone abbreviations
@@ -590,10 +587,10 @@ in decreasing order of importance:
locations while uninhabited.
The leading "<code>-</code>" is a flag that the <abbr>UT</abbr> offset is in
some sense undefined; this notation is derived
from <a href="https://www.rfc-editor.org/rfc/rfc3339">Internet
from <a href="https://www.rfc-editor.org/info/rfc3339/">Internet
<abbr title="Request For Comments">RFC</abbr> 3339</a>.
(The abbreviation Z that
<a href="https://www.rfc-editor.org/rfc/rfc9557">Internet
<a href="https://www.rfc-editor.org/info/rfc9557/">Internet
<abbr>RFC</abbr> 9557</a> uses for this concept
would violate the POSIX requirement
of at least three characters in an abbreviation.)
@@ -608,9 +605,7 @@ Israel.
To avoid ambiguity, use numeric <abbr>UT</abbr> offsets like
<code>-</code>0600 instead of time zone abbreviations like CST.
</p>
</section>
<section>
<h2 id="accuracy">Accuracy of the <code><abbr>tz</abbr></code> database</h2>
<p>
The <code><abbr>tz</abbr></code> database is not authoritative, and it
@@ -630,7 +625,7 @@ Errors in the <code><abbr>tz</abbr></code> database arise from many sources:
timestamps, and current predictions
will be incorrect after future governments change the rules.
For example, if today someone schedules a meeting for 13:00 next
October 1, Casablanca time, and tomorrow Morocco changes its
October 1, Dublin time, and tomorrow Ireland changes its
daylight saving rules, software can mess up after the rule change
if it blithely relies on conversions made before the change.
</li>
@@ -648,14 +643,14 @@ Errors in the <code><abbr>tz</abbr></code> database arise from many sources:
should be observed.
In her 2015 book
<cite><a
href="https://www.hup.harvard.edu/catalog.php?isbn=9780674286146">The
href="https://www.hup.harvard.edu/books/9780674286146">The
Global Transformation of Time, 1870–1950</a></cite>,
Vanessa Ogle writes
“Outside of Europe and North America there was no system of time
zones at all, often not even a stable landscape of mean times,
prior to the middle decades of the twentieth century”.
See: Timothy Shenk, <a
href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanessa-ogle">Booked:
href="https://dissentmagazine.org/online_articles/booked-a-global-history-of-time-vanessa-ogle/">Booked:
A Global History of Time</a>. <cite>Dissent</cite> 2015-12-17.
</li>
<li>
@@ -789,7 +784,7 @@ href="https://www.dissentmagazine.org/blog/booked-a-global-history-of-time-vanes
calendar with 24-hour days. These divergences range from
relatively minor, such as Japanese bars giving times like 24:30 for the
wee hours of the morning, to more-significant differences such as <a
href="https://theworld.org/stories/2015-01-30/if-you-have-meeting-ethiopia-you-better-double-check-time">the
href="https://theworld.org/stories/2015/01/30/ethiopian-time">the
east African practice of starting the day at dawn</a>, renumbering
the Western 06:00 to be 12:00. These practices are largely outside
the scope of the <code><abbr>tz</abbr></code> code and data, which
@@ -874,9 +869,7 @@ merely because two locations
differ in <abbr>LMT</abbr> or transitioned to standard time at
different dates.
</p>
</section>
<section>
<h2 id="functions">Time and date functions</h2>
<p>
The <code><abbr>tz</abbr></code> code contains time and date functions
@@ -936,7 +929,7 @@ with problems that were fixed in later POSIX editions.
has a format that is hard to describe and is error-prone in practice.
Also, proleptic <code>TZ</code> strings cannot deal with daylight
saving time rules not based on the Gregorian calendar (as in
Morocco), or with situations where more than two time zone
Palestine), or with situations where more than two time zone
abbreviations or <abbr>UT</abbr> offsets are used in an area.
</p>
@@ -1126,7 +1119,7 @@ However POSIX.1-2024, like earlier POSIX editions, has some limitations:
the name of a file from which time-related information is read.
The file’s format is <dfn><abbr>TZif</abbr></dfn>,
a timezone information format that contains binary data; see
<a href="https://www.rfc-editor.org/rfc/9636">Internet
<a href="https://www.rfc-editor.org/info/rfc9636/">Internet
<abbr>RFC</abbr> 9636</a>.
The daylight saving time rules to be used for a
particular timezone are encoded in the
@@ -1210,8 +1203,8 @@ The vestigial <abbr>API</abbr>s are:
</li>
<li>
The <code>tm_isdst</code> member is almost never needed and most of
its uses should be discouraged in favor of the abovementioned
<abbr>API</abbr>s.
its uses should be discouraged in favor of the
<abbr>API</abbr>s mentioned above.
It was intended as an index into the <code>tzname</code> variable,
but as mentioned previously that usage is obsolete.
Although it can still be used in arguments to
@@ -1282,9 +1275,7 @@ The vestigial <abbr>API</abbr>s are:
much the better.
</li>
</ul>
</section>
<section>
<h2 id="stability">Interface stability</h2>
<p>
The <code><abbr>tz</abbr></code> code and data supply the following interfaces:
@@ -1351,9 +1342,7 @@ than Bangkok by putting <samp>Asia/Bangkok</samp> in the event’s record,
the application should be robust in the presence of timezone splits
between now and the future time.
</p>
</section>
<section>
<h2 id="leapsec">Leap seconds</h2>
<p>
Leap seconds were introduced in 1972 to accommodate the
@@ -1428,9 +1417,7 @@ Alternatively, you can install just one set of <abbr>TZif</abbr> files
in the first place; see the <code>REDO</code> variable in this package’s
<a href="https://en.wikipedia.org/wiki/Makefile">makefile</a>.
</p>
</section>
<section>
<h2 id="calendar">Calendrical issues</h2>
<p>
Calendrical issues are a bit out of scope for a time zone database,
@@ -1438,28 +1425,36 @@ but they indicate the sort of problems that we would run into if we
extended the time zone database further into the past.
An excellent resource in this area is Edward M. Reingold
and Nachum Dershowitz, <cite><a
href="https://www.cambridge.org/fr/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition">Calendrical
href="https://www.cambridge.org/fr/universitypress/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition">Calendrical
Calculations: The Ultimate Edition</a></cite>, Cambridge University Press (2018).
Other information and sources are given in the file "<code>calendars</code>"
in the <code><abbr>tz</abbr></code> distribution.
They sometimes disagree.
</p>
</section>
<section>
<h2 id="planets">Time and time zones off Earth</h2>
<p>
The European Space Agency is <a
href="https://www.esa.int/Applications/Navigation/Telling_time_on_the_Moon">considering</a>
the establishment of a reference timescale for the Moon, which has
Efforts are underway to establish a reference timescale for the Moon, which has
days roughly equivalent to 29.5 Earth days, and where relativistic
effects cause clocks to tick slightly faster than on Earth.
Also, <abbr title="National Aeronautics and Space Administration">NASA</abbr>
has been <a
href="https://www.whitehouse.gov/wp-content/uploads/2024/04/Celestial-Time-Standardization-Policy.pdf">ordered</a>
The European Space Agency <a
href="https://www.esa.int/Applications/Satellite_navigation/Telling_time_on_the_Moon">began
considering</a> the problem in 2023, and in 2024
<abbr title="National Aeronautics and Space Administration">NASA</abbr>
was <a
href="https://bidenwhitehouse.archives.gov/wp-content/uploads/2024/04/Celestial-Time-Standardization-Policy.pdf">ordered</a>
to consider the establishment of Coordinated Lunar Time (<abbr>LTC</abbr>).
It is not yet known whether the US and European efforts will result in
multiple timescales on the Moon.
In 2025 a team at China’s
<a href="https://en.wikipedia.org/wiki/Purple_Mountain_Observatory">Purple
Mountain Observatory</a> published
<a href="https://doi.org/10.1051/0004-6361/202557345">Lunar Time Ephemeris
440</a>, the first formal proposal for a standard
for Temps Coordonné Lunaire (<abbr>TCL</abbr>).
A <a href="https://www.bipm.org/documents/20126/284836054/CGPM-2026-Draft-Resolutions.pdf">draft
resolution of the 13–15 October 2026 General Conference on Weights
and Measures</a> recommends that the <a href="https://www.bipm.org/en/">Bureau
International des Poids et Mesures</a> collaborate with space agencies
and other organizations on this matter.
</p>
<p>
@@ -1556,7 +1551,7 @@ Sources for time on other planets:
Michael Allison and Robert Schmunk,
“<a href="https://www.giss.nasa.gov/tools/mars24/help/notes.html">Technical
Notes on Mars Solar Time as Adopted by the Mars24 Sunclock</a>”
(2020-03-08).
(2023-05-15).
</li>
<li>
Zara Mirmalek,
@@ -1576,12 +1571,20 @@ Sources for time on other planets:
</li>
<li>
Matt Williams,
“<a href="https://www.universetoday.com/37481/days-of-the-planets/">How
“<a href="https://www.universetoday.com/articles/days-of-the-planets">How
long is a day on the other planets of the solar system?</a>”
(2016-01-20).
</li>
</ul>
</section>
</main>
<aside>
<h2 id="see-also">See also</h2>
<ul>
<li><a href="tz-link.html">Time zone and daylight saving time data</a></li>
<li><a href="tz-art.html">Time and the arts</a></li>
</ul>
</aside>
<footer>
<hr>
+1 -1
View File
@@ -1 +1 @@
2025c
2026e
+4 -4
View File
@@ -184,7 +184,7 @@ DATAFORM != "main" {
dstoff = get_minutes(rules)
} else {
# The DST offset is normally an hour, but there are special cases.
if (rules == "Morocco" && NF == 3) {
if (rules == "Morocco" && $4 == 2026) {
dstoff = -60
} else if (rules == "NBorneo") {
dstoff = 20
@@ -286,13 +286,13 @@ DATAFORM != "main" {
}
}
}
if ($1 ~ /^[+0-9-]/ && NF == 3) {
if ($1 ~ /^[+0-9-]/ && $4 == 2026) {
if (DATAFORM == "rearguard") {
sub(/1:00\tMorocco/, "0:00\tMorocco")
sub(/\t\+01\/\+00$/, "\t+00/+01")
sub(/\t\+01\/\+00/, "\t+00/+01")
} else {
sub(/0:00\tMorocco/, "1:00\tMorocco")
sub(/\t\+00\/+01$/, "\t+01/+00")
sub(/\t\+00\/+01/, "\t+01/+00")
}
}
}
+4 -4
View File
@@ -116,20 +116,20 @@ CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore)
CA +4339-07923 America/Toronto Eastern - ON & QC (most areas)
CA +6344-06828 America/Iqaluit Eastern - NU (most areas)
CA +484531-0913718 America/Atikokan EST - ON (Atikokan), NU (Coral H)
CA +4953-09709 America/Winnipeg Central - ON (west), Manitoba
CA +4953-09709 America/Winnipeg EST - Manitoba, ON (northwest)
CA +744144-0944945 America/Resolute Central - NU (Resolute)
CA +624900-0920459 America/Rankin_Inlet Central - NU (central)
CA +5024-10439 America/Regina CST - SK (most areas)
CA +5017-10750 America/Swift_Current CST - SK (midwest)
CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W)
CA +5333-11328 America/Edmonton CST - AB, BC(E), NT(E), SK(W)
CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
CA +682059-1334300 America/Inuvik Mountain - NT (west)
CA +682059-1334300 America/Inuvik CST - NT (west)
CA +4916-12307 America/Vancouver MST - BC (most areas)
CA +4906-11631 America/Creston MST - BC (Creston)
CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
CA +6043-13503 America/Whitehorse MST - Yukon (east)
CA +6404-13925 America/Dawson MST - Yukon (west)
CA +4916-12307 America/Vancouver Pacific - BC (most areas)
CC -1210+09655 Indian/Cocos
CD -0418+01518 Africa/Kinshasa Dem. Rep. of Congo (west)
CD -1140+02728 Africa/Lubumbashi Dem. Rep. of Congo (east)
+4 -4
View File
@@ -108,19 +108,19 @@ CA +4606-06447 America/Moncton Atlantic - New Brunswick
CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas)
CA,BS +4339-07923 America/Toronto Eastern - ON & QC (most areas)
CA +6344-06828 America/Iqaluit Eastern - NU (most areas)
CA +4953-09709 America/Winnipeg Central - ON (west), Manitoba
CA +4953-09709 America/Winnipeg EST - Manitoba, ON (northwest)
CA +744144-0944945 America/Resolute Central - NU (Resolute)
CA +624900-0920459 America/Rankin_Inlet Central - NU (central)
CA +5024-10439 America/Regina CST - SK (most areas)
CA +5017-10750 America/Swift_Current CST - SK (midwest)
CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W)
CA +5333-11328 America/Edmonton CST - AB, BC(E), NT(E), SK(W)
CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
CA +682059-1334300 America/Inuvik Mountain - NT (west)
CA +682059-1334300 America/Inuvik CST - NT (west)
CA +4916-12307 America/Vancouver MST - BC (most areas)
CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
CA +6043-13503 America/Whitehorse MST - Yukon (east)
CA +6404-13925 America/Dawson MST - Yukon (west)
CA +4916-12307 America/Vancouver Pacific - BC (most areas)
CH,DE,LI +4723+00832 Europe/Zurich Büsingen
CI,BF,GH,GM,GN,IS,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan
CK -2114-15946 Pacific/Rarotonga
+12 -6
View File
@@ -56,13 +56,19 @@ XX +611305-1495401 America/Anchorage most of Alaska (AKST/AKDT)
XX -2504-13005 Pacific/Pitcairn Pitcairn
#
# -08/-07 - PST/PDT (North America DST)
XX +340308-1181434 America/Los_Angeles Pacific (PST/PDT) - US & Canada; Mexico near US border
XX +340308-1181434 America/Los_Angeles Pacific (PST/PDT) - US; Mexico near US border
#
# -08/-07 - PST/PDT (North America DST) until 2026-11-01 02:00; then MST
XX +4916-12307 America/Vancouver Mountain Standard (MST) - British Columbia (most areas)
#
# -07 - MST
XX +332654-1120424 America/Phoenix Mountain Standard (MST) - Arizona; western Mexico; Yukon
#
# -07/-06 - MST/MDT (North America DST)
XX +394421-1045903 America/Denver Mountain (MST/MDT) - US & Canada; Mexico near US border
XX +394421-1045903 America/Denver Mountain (MST/MDT) - US; Mexico near US border; western Nunavut
#
# -07/-06 - MST/MDT (North America DST) until 2026-11-01 02:00; then CST
XX +5333-11328 America/Edmonton Central Standard (CST) - Alberta, NWT, and some neighbors
#
# -06
XX -0054-08936 Pacific/Galapagos Galápagos
@@ -74,7 +80,10 @@ XX +1924-09909 America/Mexico_City Central Standard (CST) - Saskatchewan; centra
XX -2709-10926 Pacific/Easter Easter Island
#
# -06/-05 - CST/CDT (North America DST)
XX +415100-0873900 America/Chicago Central (CST/CDT) - US & Canada; Mexico near US border
XX +415100-0873900 America/Chicago Central (CST/CDT) - US; Mexico near US border; central Nunavut
#
# -06/-05 - CST/CDT (North America DST) until 2026-11-01 02:00; then EST
XX +4953-09709 America/Winnipeg Eastern Standard (EST) - Manitoba, northwestern Ontario
#
# -05
XX -1203-07703 America/Lima eastern South America
@@ -166,9 +175,6 @@ XX +3003+03115 Africa/Cairo Egypt
# +02/+03 - EET/EEST (Lebanon DST)
XX +3353+03530 Asia/Beirut Lebanon
#
# +02/+03 - EET/EEST (Moldova DST)
XX +4700+02850 Europe/Chisinau Moldova
#
# +02/+03 - EET/EEST (Palestine DST)
XX +3130+03428 Asia/Gaza Palestine
#
+1 -1
View File
@@ -361,7 +361,7 @@ dnscrypt_server_uncurve(struct dnsc_env* env,
len -= DNSCRYPT_QUERY_HEADER_SIZE;
while (*sldns_buffer_at(buffer, --len) == 0)
while (len>0 && *sldns_buffer_at(buffer, --len) == 0)
;
if (*sldns_buffer_at(buffer, len) != 0x80) {
+7 -1
View File
@@ -725,7 +725,13 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
rrset->rrset_all_next = NULL;
return 1;
}
mark_additional_rrset(pkt, msg, rrset);
/* Only mark glue as allowed for type NS in the authority
* section. Other RR types do not get glue for them, it
* is allowed from the answer section, but not authority
* so that a message can not have address records cached
* as a side effect to the query. */
if(rrset->type==LDNS_RR_TYPE_NS)
mark_additional_rrset(pkt, msg, rrset);
prev = rrset;
rrset = rrset->rrset_all_next;
}
+7 -1
View File
@@ -675,10 +675,16 @@ struct dns_msg*
dns_msg_deepcopy_region(struct dns_msg* origin, struct regional* region)
{
size_t i;
struct ub_packed_rrset_key** saved_rrsets;
struct dns_msg* res = NULL;
size_t rep_alloc_size = sizeof(struct reply_info)
- sizeof(struct rrset_ref); /* this is the size of res->rep
allocated in gen_dns_msg() */
res = gen_dns_msg(region, &origin->qinfo, origin->rep->rrset_count);
if(!res) return NULL;
*res->rep = *origin->rep;
saved_rrsets = res->rep->rrsets; /* save rrsets alloc by gen_dns_msg */
memcpy(res->rep, origin->rep, rep_alloc_size);
res->rep->rrsets = saved_rrsets;
if(origin->rep->reason_bogus_str) {
res->rep->reason_bogus_str = regional_strdup(region,
origin->rep->reason_bogus_str);
+10
View File
@@ -149,6 +149,16 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
if(equal && cached->ttl >= timenow &&
cached->security == sec_status_bogus)
return 0;
/* ghost-domain: never let an NS overwrite extend lifetime
* past the entry it replaces, regardless of trust. */
if(ns && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
newd->ttl > cached->ttl) {
size_t i;
newd->ttl = cached->ttl;
for(i=0; i<(newd->count+newd->rrsig_count); i++)
if(newd->rr_ttl[i] > newd->ttl)
newd->rr_ttl[i] = newd->ttl;
}
return 1;
}
/* o item in cache has expired */
+10 -4
View File
@@ -296,12 +296,14 @@ int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf)
if(mesh->num_reply_states < mesh->max_reply_states)
return 1;
/* try to kick out a jostle-list item */
if(m && m->reply_list && m->list_select == mesh_jostle_list) {
if(m && m->list_select == mesh_jostle_list) {
/* how old is it? */
struct timeval age;
timeval_subtract(&age, mesh->env->now_tv,
&m->reply_list->start_time);
if(timeval_smaller(&mesh->jostle_max, &age)) {
if(m->has_first_reply_time)
timeval_subtract(&age, mesh->env->now_tv,
&m->first_reply_time);
if(!m->has_first_reply_time ||
timeval_smaller(&mesh->jostle_max, &age)) {
/* its a goner */
log_nametypeclass(VERB_ALGO, "query jostled out to "
"make space for a new one",
@@ -1960,6 +1962,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
r->qid = qid;
r->qflags = qflags;
r->start_time = *s->s.env->now_tv;
if(s->reply_list == NULL && !s->has_first_reply_time) {
s->first_reply_time = r->start_time;
s->has_first_reply_time = 1;
}
r->next = s->reply_list;
r->qname = regional_alloc_init(s->s.region, qinfo->qname,
s->s.qinfo.qname_len);
+6
View File
@@ -189,6 +189,12 @@ struct mesh_state {
struct module_qstate s;
/** the list of replies to clients for the results */
struct mesh_reply* reply_list;
/** if it has a first reply time */
int has_first_reply_time;
/** wall-clock time the first client reply was attached;
* used by mesh_make_new_space() so duplicate retransmits
* cannot reset jostle aging. */
struct timeval first_reply_time;
/** the list of callbacks for the results */
struct mesh_cb* cb_list;
/** set of superstates (that want this state's result)
+6 -4
View File
@@ -2468,6 +2468,7 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
{
struct auth_zones* az;
struct auth_zone* a;
struct dns_msg* ret = NULL;
struct clientip_synthesized_rr* raddr = NULL;
struct rpz* r = NULL;
struct local_zone* z = NULL;
@@ -2511,13 +2512,11 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones,
is->qchase.qclass, &match);
if(z != NULL) {
lock_rw_unlock(&a->lock);
break;
}
raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is);
if(raddr != NULL) {
lock_rw_unlock(&a->lock);
break;
}
lock_rw_unlock(&a->lock);
@@ -2532,9 +2531,12 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
if(z) {
lock_rw_unlock(&z->lock);
}
return rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a);
ret = rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a);
} else {
ret = rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a);
}
return rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a);
lock_rw_unlock(&a->lock);
return ret;
}
struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
+36 -18
View File
@@ -352,7 +352,6 @@ compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs,
(p = compress_tree_lookup(tree, dname, labs, &insertpt))) {
if(!write_compressed_dname(pkt, dname, labs, p))
return RETVAL_TRUNC;
(*compress_count)++;
} else {
if(!dname_buffer_write(pkt, dname))
return RETVAL_TRUNC;
@@ -360,6 +359,7 @@ compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs,
if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
!compress_tree_store(dname, labs, pos, region, p, insertpt))
return RETVAL_OUTMEM;
(*compress_count)++;
return RETVAL_OK;
}
@@ -804,7 +804,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
return 1;
}
uint16_t
size_t
calc_edns_field_size(struct edns_data* edns)
{
size_t rdatalen = 0;
@@ -840,7 +840,7 @@ calc_edns_option_size(struct edns_data* edns, uint16_t code)
}
uint16_t
calc_ede_option_size(struct edns_data* edns, uint16_t* txt_size)
calc_ede_option_size(struct edns_data* edns, size_t* txt_size)
{
size_t rdatalen = 0;
struct edns_option* opt;
@@ -942,6 +942,10 @@ attach_edns_record_max_msg_sz(sldns_buffer* pkt, struct edns_data* edns,
padding_option = opt;
continue;
}
if(sldns_buffer_position(pkt) + opt->opt_len + 4 > max_msg_sz)
break; /* no space for it */
if(!sldns_buffer_available(pkt, 4 + opt->opt_len))
break;
sldns_buffer_write_u16(pkt, opt->opt_code);
sldns_buffer_write_u16(pkt, opt->opt_len);
if(opt->opt_len != 0)
@@ -952,12 +956,18 @@ attach_edns_record_max_msg_sz(sldns_buffer* pkt, struct edns_data* edns,
padding_option = opt;
continue;
}
if(sldns_buffer_position(pkt) + opt->opt_len + 4 > max_msg_sz)
break; /* no space for it */
if(!sldns_buffer_available(pkt, 4 + opt->opt_len))
break;
sldns_buffer_write_u16(pkt, opt->opt_code);
sldns_buffer_write_u16(pkt, opt->opt_len);
if(opt->opt_len != 0)
sldns_buffer_write(pkt, opt->opt_data, opt->opt_len);
}
if (padding_option && edns->padding_block_size ) {
if (padding_option && edns->padding_block_size &&
sldns_buffer_position(pkt)+4 <= max_msg_sz &&
sldns_buffer_available(pkt, 4) /* if there is space for it */) {
size_t pad_pos = sldns_buffer_position(pkt);
size_t msg_sz = ((pad_pos + 3) / edns->padding_block_size + 1)
* edns->padding_block_size;
@@ -1001,7 +1011,7 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
{
uint16_t flags;
unsigned int attach_edns = 0;
uint16_t edns_field_size, ede_size, ede_txt_size;
size_t edns_field_size, ede_size, ede_txt_size;
if(!cached || rep->authoritative) {
/* original flags, copy RD and CD bits from query. */
@@ -1028,12 +1038,12 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
* calculate sizes once here */
edns_field_size = calc_edns_field_size(edns);
ede_size = calc_ede_option_size(edns, &ede_txt_size);
if(sldns_buffer_capacity(pkt) < udpsize)
if(sldns_buffer_capacity(pkt) < (size_t)udpsize)
udpsize = sldns_buffer_capacity(pkt);
if(!edns || !edns->edns_present) {
attach_edns = 0;
/* EDEs are optional, try to fit anything else before them */
} else if(udpsize < LDNS_HEADER_SIZE + edns_field_size - ede_size) {
} else if((size_t)udpsize < (size_t)LDNS_HEADER_SIZE + edns_field_size - ede_size) {
/* packet too small to contain edns, omit it. */
attach_edns = 0;
} else {
@@ -1047,13 +1057,13 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
return 0;
}
if(attach_edns) {
if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size)
if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size)
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
else if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_txt_size) {
else if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_txt_size) {
ede_trim_text(&edns->opt_list_inplace_cb_out);
ede_trim_text(&edns->opt_list_out);
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
} else if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_size) {
} else if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_size) {
edns_opt_list_remove(&edns->opt_list_inplace_cb_out, LDNS_EDNS_EDE);
edns_opt_list_remove(&edns->opt_list_out, LDNS_EDNS_EDE);
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
@@ -1115,22 +1125,30 @@ extended_error_encode(sldns_buffer* buf, uint16_t rcode,
sldns_buffer_write_u16(buf, qinfo->qclass);
}
sldns_buffer_flip(buf);
if(edns) {
if(edns && edns->edns_present) {
size_t edns_field_size, ede_size, ede_txt_size;
struct edns_data es = *edns;
es.edns_version = EDNS_ADVERTISED_VERSION;
es.udp_size = EDNS_ADVERTISED_SIZE;
es.ext_rcode = (uint8_t)(rcode >> 4);
es.bits &= EDNS_DO;
if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
edns->udp_size) {
/* EDEs are optional. If space is a concern try in order:
* - removing any EXTRA-TEXT fields from explicit EDEs, or
* - removing all EDEs,
* to see if EDNS can fit. */
edns_field_size = calc_edns_field_size(&es);
ede_size = calc_ede_option_size(&es, &ede_txt_size);
if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size)
attach_edns_record_max_msg_sz(buf, &es, edns->udp_size);
else if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_txt_size) {
ede_trim_text(&es.opt_list_inplace_cb_out);
ede_trim_text(&es.opt_list_out);
attach_edns_record_max_msg_sz(buf, &es, edns->udp_size);
} else if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_size) {
edns_opt_list_remove(&es.opt_list_inplace_cb_out, LDNS_EDNS_EDE);
edns_opt_list_remove(&es.opt_list_out, LDNS_EDNS_EDE);
if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
edns->udp_size) {
return;
}
attach_edns_record_max_msg_sz(buf, &es, edns->udp_size);
}
attach_edns_record(buf, &es);
}
}
+2 -2
View File
@@ -106,7 +106,7 @@ void qinfo_query_encode(struct sldns_buffer* pkt, struct query_info* qinfo);
* @param edns: edns data or NULL.
* @return octets to reserve for EDNS.
*/
uint16_t calc_edns_field_size(struct edns_data* edns);
size_t calc_edns_field_size(struct edns_data* edns);
/**
* Calculate the size of a specific EDNS option in packet.
@@ -127,7 +127,7 @@ uint16_t calc_edns_option_size(struct edns_data* edns, uint16_t code);
* extra text.
* @return octets the option will take up.
*/
uint16_t calc_ede_option_size(struct edns_data* edns, uint16_t* txt_size);
uint16_t calc_ede_option_size(struct edns_data* edns, size_t* txt_size);
/**
* Attach EDNS record to buffer. Buffer has complete packet. There must
+14 -5
View File
@@ -53,6 +53,8 @@
#include "sldns/parseutil.h"
#include "sldns/wire2str.h"
#define MAX_PARSED_EDNS_OPTIONS 100
/** smart comparison of (compressed, valid) dnames from packet */
static int
smart_compare(sldns_buffer* pkt, uint8_t* dnow,
@@ -950,6 +952,7 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
struct comm_reply* repinfo, uint32_t now, struct regional* region,
struct cookie_secrets* cookie_secrets)
{
int i = 0, nsid_seen = 0, cookie_seen = 0, padding_seen = 0;
/* To respond with a Keepalive option, the client connection must have
* received one message with a TCP Keepalive EDNS option, and that
* option must have 0 length data. Subsequent messages sent on that
@@ -969,7 +972,7 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
/* while still more options, and have code+len to read */
/* ignores partial content (i.e. rdata len 3) */
while(rdata_len >= 4) {
while(rdata_len >= 4 && i < MAX_PARSED_EDNS_OPTIONS) {
uint16_t opt_code = sldns_read_uint16(rdata_ptr);
uint16_t opt_len = sldns_read_uint16(rdata_ptr+2);
uint8_t server_cookie[40];
@@ -984,8 +987,9 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
/* handle parse time edns options here */
switch(opt_code) {
case LDNS_EDNS_NSID:
if (!cfg || !cfg->nsid)
if (!cfg || !cfg->nsid || nsid_seen)
break;
nsid_seen = 1;
if(!edns_opt_list_append(&edns->opt_list_out,
LDNS_EDNS_NSID, cfg->nsid_len,
cfg->nsid, region)) {
@@ -1027,8 +1031,9 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
case LDNS_EDNS_PADDING:
if(!cfg || !cfg->pad_responses ||
!c || c->type != comm_tcp ||!c->ssl)
!c || c->type != comm_tcp ||!c->ssl || padding_seen)
break;
padding_seen = 1;
if(!edns_opt_list_append(&edns->opt_list_out,
LDNS_EDNS_PADDING,
0, NULL, region)) {
@@ -1039,8 +1044,9 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
break;
case LDNS_EDNS_COOKIE:
if(!cfg || !cfg->do_answer_cookie || !repinfo)
if(!cfg || !cfg->do_answer_cookie || !repinfo || cookie_seen)
break;
cookie_seen = 1;
if(opt_len != 8 && (opt_len < 16 || opt_len > 40)) {
verbose(VERB_ALGO, "worker request: "
"badly formatted cookie");
@@ -1146,6 +1152,7 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
}
rdata_ptr += opt_len;
rdata_len -= opt_len;
i++;
}
return LDNS_RCODE_NOERROR;
}
@@ -1160,6 +1167,7 @@ parse_extract_edns_from_response_msg(struct msg_parse* msg,
struct rrset_parse* found_prev = 0;
size_t rdata_len;
uint8_t* rdata_ptr;
int i = 0;
/* since the class encodes the UDP size, we cannot use hash table to
* find the EDNS OPT record. Scan the packet. */
while(rrset) {
@@ -1219,7 +1227,7 @@ parse_extract_edns_from_response_msg(struct msg_parse* msg,
/* while still more options, and have code+len to read */
/* ignores partial content (i.e. rdata len 3) */
while(rdata_len >= 4) {
while(rdata_len >= 4 && i < MAX_PARSED_EDNS_OPTIONS) {
uint16_t opt_code = sldns_read_uint16(rdata_ptr);
uint16_t opt_len = sldns_read_uint16(rdata_ptr+2);
rdata_ptr += 4;
@@ -1234,6 +1242,7 @@ parse_extract_edns_from_response_msg(struct msg_parse* msg,
}
rdata_ptr += opt_len;
rdata_len -= opt_len;
i++;
}
/* ignore rrsigs */
return LDNS_RCODE_NOERROR;
+4
View File
@@ -98,6 +98,10 @@ extern time_t SERVE_EXPIRED_REPLY_TTL;
/** If we serve the original TTL or decrementing TTLs */
extern int SERVE_ORIGINAL_TTL;
/** Check if TTL is expired. 0 TTL is considered expired.
* Used mainly to identify parts of the code that do this comparison. */
#define TTL_IS_EXPIRED(ttl, now) ((ttl) <= (now))
/**
* Data stored in scratch pad memory during parsing.
* Stores the data that will enter into the msgreply and packet result.
+27 -1
View File
@@ -62,6 +62,13 @@
#include "sldns/rrdef.h"
#include "sldns/sbuffer.h"
/**
* The maximum salt length that the negative cache is willing to use.
* Larger salt increases the computation time, while recommendations are
* for zero salt length for zones.
*/
#define MAX_SALT_LENGTH 64
int val_neg_data_compare(const void* a, const void* b)
{
struct val_neg_data* x = (struct val_neg_data*)a;
@@ -826,7 +833,11 @@ void neg_insert_data(struct val_neg_cache* neg,
(slen != 0 && zone->nsec3_salt && s
&& memcmp(zone->nsec3_salt, s, slen) != 0))) {
if(slen > 0) {
if(slen > MAX_SALT_LENGTH) {
/* RFC 9276 s3.1: operators SHOULD NOT use a salt; large
* salts inflate per-hash block count. Decline to cache. */
return;
} else if(slen > 0) {
uint8_t* sa = memdup(s, slen);
if(sa) {
free(zone->nsec3_salt);
@@ -1169,6 +1180,15 @@ neg_find_nsec3_ce(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len,
uint8_t hashce[NSEC3_SHA_LEN];
uint8_t b32[257];
size_t celen, b32len;
int hashmax = MAX_NSEC3_CALCULATIONS;
if(qlabs > hashmax) {
/* strip leading labels so the walk costs at most
* MAX_NSEC3_CALCULATIONS hashes, mirroring val_nsec3.c */
while(qlabs > hashmax) {
dname_remove_label(&qname, &qname_len);
qlabs--;
}
}
*nclen = 0;
while(qlabs > 0) {
@@ -1269,6 +1289,12 @@ neg_nsec3_proof_ds(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len,
if(!zone->nsec3_hash)
return NULL; /* not nsec3 zone */
if(!topname && qlabs > zone->labs + 1)
return NULL; /* iterator caller; opt-out proof would be discarded
* at the !topname check below anyway.
* The qlabs check allows the exact-match for
* the one-label-below-zone case. */
if(!(data=neg_find_nsec3_ce(zone, qname, qname_len, qlabs, buf,
hashnc, &nclen))) {
return NULL;
+71 -5
View File
@@ -59,11 +59,6 @@
#include "sldns/sbuffer.h"
#include "util/config_file.h"
/**
* Max number of NSEC3 calculations at once, suspend query for later.
* 8 is low enough and allows for cases where multiple proofs are needed.
*/
#define MAX_NSEC3_CALCULATIONS 8
/**
* When all allowed NSEC3 calculations at once resulted in error treat as
* bogus. NSEC3 hash errors are not cached and this helps breaks loops with
@@ -456,6 +451,67 @@ filter_init(struct nsec3_filter* filter, struct ub_packed_rrset_key** list,
}
}
/** Check if the NSEC3s have the same parameter set. */
static int
param_set_same(struct nsec3_filter* flt, char** reason)
{
size_t rrsetnum;
int rrnum;
struct ub_packed_rrset_key* rrset;
int have_params = 0;
int first_algo = 0;
size_t first_iter = 0;
uint8_t* first_salt = NULL;
size_t first_saltlen = 0;
/* If the NSEC3 parameter sets have distinct values, then they are
* from different NSEC3 chains, and we do not want that. */
for(rrset=filter_first(flt, &rrsetnum, &rrnum); rrset;
rrset=filter_next(flt, &rrsetnum, &rrnum)) {
if(!have_params) {
first_algo = nsec3_get_algo(rrset, rrnum);
first_iter = nsec3_get_iter(rrset, rrnum);
if(!nsec3_get_salt(rrset, rrnum, &first_salt,
&first_saltlen)) {
verbose(VERB_ALGO, "NSEC3 salt malformed");
if(reason)
*reason = "NSEC3 salt malformed";
return 0;
}
have_params = 1;
} else {
uint8_t* salt = NULL;
size_t saltlen = 0;
if(nsec3_get_algo(rrset, rrnum) != first_algo) {
verbose(VERB_ALGO, "NSEC3 algorithm mismatch");
if(reason)
*reason = "NSEC3 algorithm mismatch";
return 0;
}
if(nsec3_get_iter(rrset, rrnum) != first_iter) {
verbose(VERB_ALGO, "NSEC3 iterations mismatch");
if(reason)
*reason = "NSEC3 iterations mismatch";
return 0;
}
if(!nsec3_get_salt(rrset, rrnum, &salt, &saltlen)) {
verbose(VERB_ALGO, "NSEC3 salt malformed");
if(reason)
*reason = "NSEC3 salt malformed";
return 0;
}
if(saltlen != first_saltlen ||
memcmp(salt, first_salt, saltlen) != 0) {
verbose(VERB_ALGO, "NSEC3 salt mismatch");
if(reason)
*reason = "NSEC3 salt mismatch";
return 0;
}
}
}
return 1;
}
/**
* Find max iteration count using config settings and key size
* @param ve: validator environment with iteration count config settings.
@@ -1192,6 +1248,8 @@ nsec3_prove_nameerror(struct module_env* env, struct val_env* ve,
filter_init(&flt, list, num, qinfo); /* init RR iterator */
if(!flt.zone)
return sec_status_bogus; /* no RRs */
if(!param_set_same(&flt, NULL))
return sec_status_bogus; /* nsec3 params from distinct chains*/
if(nsec3_iteration_count_high(ve, &flt, kkey))
return sec_status_insecure; /* iteration count too high */
log_nametypeclass(VERB_ALGO, "start nsec3 nameerror proof, zone",
@@ -1378,6 +1436,8 @@ nsec3_prove_nodata(struct module_env* env, struct val_env* ve,
filter_init(&flt, list, num, qinfo); /* init RR iterator */
if(!flt.zone)
return sec_status_bogus; /* no RRs */
if(!param_set_same(&flt, NULL))
return sec_status_bogus; /* nsec3 params from distinct chains*/
if(nsec3_iteration_count_high(ve, &flt, kkey))
return sec_status_insecure; /* iteration count too high */
return nsec3_do_prove_nodata(env, &flt, ct, qinfo, calc);
@@ -1401,6 +1461,8 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
filter_init(&flt, list, num, qinfo); /* init RR iterator */
if(!flt.zone)
return sec_status_bogus; /* no RRs */
if(!param_set_same(&flt, NULL))
return sec_status_bogus; /* nsec3 params from distinct chains*/
if(nsec3_iteration_count_high(ve, &flt, kkey))
return sec_status_insecure; /* iteration count too high */
@@ -1503,6 +1565,8 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
*reason = "no NSEC3 records";
return sec_status_bogus; /* no RRs */
}
if(!param_set_same(&flt, reason))
return sec_status_bogus; /* nsec3 params from distinct chains*/
if(nsec3_iteration_count_high(ve, &flt, kkey))
return sec_status_insecure; /* iteration count too high */
@@ -1596,6 +1660,8 @@ nsec3_prove_nxornodata(struct module_env* env, struct val_env* ve,
filter_init(&flt, list, num, qinfo); /* init RR iterator */
if(!flt.zone)
return sec_status_bogus; /* no RRs */
if(!param_set_same(&flt, NULL))
return sec_status_bogus; /* nsec3 params from distinct chains*/
if(nsec3_iteration_count_high(ve, &flt, kkey))
return sec_status_insecure; /* iteration count too high */
+6
View File
@@ -98,6 +98,12 @@ struct sldns_buffer;
/** The SHA1 hash algorithm for NSEC3 */
#define NSEC3_HASH_SHA1 0x01
/**
* Max number of NSEC3 calculations at once, suspend query for later.
* 8 is low enough and allows for cases where multiple proofs are needed.
*/
#define MAX_NSEC3_CALCULATIONS 8
/**
* Cache table for NSEC3 hashes.
* It keeps a *pointer* to the region its items are allocated.
+2 -2
View File
@@ -1066,10 +1066,10 @@ val_fill_reply(struct reply_info* chase, struct reply_info* orig,
if(query_dname_compare(name,
orig->rrsets[i]->rk.dname) == 0)
chase->rrsets[chase->an_numrrsets
+orig->ns_numrrsets+chase->ar_numrrsets++]
+chase->ns_numrrsets+chase->ar_numrrsets++]
= orig->rrsets[i];
} else if(rrset_has_signer(orig->rrsets[i], name, len)) {
chase->rrsets[chase->an_numrrsets+orig->ns_numrrsets+
chase->rrsets[chase->an_numrrsets+chase->ns_numrrsets+
chase->ar_numrrsets++] = orig->rrsets[i];
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
Acknowlegements
===============
Acknowledgements
================
Please see our [Thanks!][] page for the current acknowledgements.
+584 -197
View File
@@ -28,6 +28,354 @@ breaking changes, and mappings for the large list of deprecated functions.
[Migration guide]: https://github.com/openssl/openssl/tree/master/doc/man7/migration_guide.pod
### Changes between 3.0.19 and 3.0.20 [7 Apr 2026]
* Fixed incorrect failure handling in RSA KEM RSASVE encapsulation.
Severity: Moderate
Issue summary: Applications using RSASVE key encapsulation to establish
a secret encryption key can send contents of an uninitialized memory buffer
to a malicious peer.
Impact summary: The uninitialized buffer might contain sensitive data
from the previous execution of the application process which leads
to sensitive data leakage to an attacker.
Reported by: Simo Sorce (Red Hat).
([CVE-2026-31790])
*Nikola Pajkovsky*
* Fixed potential use-after-free in DANE client code.
Severity: Low
Issue summary: An uncommon configuration of clients performing DANE
TLSA-based server authentication, when paired with uncommon server DANE TLSA
records, may result in a use-after-free and/or double-free on the client
side.
Impact summary: A use after free can have a range of potential consequences
such as the corruption of valid data, crashes, or execution of arbitrary
code.
Reported by: Igor Morgenstern (Aisle Research).
([CVE-2026-28387])
*Viktor Dukhovni*
* Fixed NULL pointer dereference when processing a delta CRL.
Severity: Low
Issue summary: When a delta CRL that contains a Delta CRL Indicator extension
is processed, a NULL pointer dereference might happen if the required CRL
Number extension is missing.
Impact summary: A NULL pointer dereference can trigger a crash which
leads to a Denial of Service for an application.
Reported by: Igor Morgenstern (Aisle Research).
([CVE-2026-28388])
*Igor Morgenstern*
* Fixed possible NULL dereference when processing CMS KeyAgreeRecipientInfo.
Severity: Low
Issue summary: During processing of a crafted CMS EnvelopedData message
with KeyAgreeRecipientInfo a NULL pointer dereference can happen.
Impact summary: Applications that process attacker-controlled CMS data may
crash before authentication or cryptographic operations occur resulting in
Denial of Service.
Reported by: Nathan Sportsman (Praetorian), Daniel Rhea,
Jaeho Nam (Seoul National University), Muhammad Daffa,
Zhanpeng Liu (Tencent Xuanwu Lab), Guannan Wang (Tencent Xuanwu Lab),
Guancheng Li (Tencent Xuanwu Lab), and Joshua Rogers.
([CVE-2026-28389])
*Neil Horman*
* Fixed possible NULL dereference when processing CMS
KeyTransportRecipientInfo.
Severity: Low
Issue summary: During processing of a crafted CMS EnvelopedData message
with KeyTransportRecipientInfo a NULL pointer dereference can happen.
Impact summary: Applications that process attacker-controlled CMS data may
crash before authentication or cryptographic operations occur resulting in
Denial of Service.
Reported by: Muhammad Daffa, Zhanpeng Liu (Tencent Xuanwu Lab),
Guannan Wang (Tencent Xuanwu Lab), Guancheng Li (Tencent Xuanwu Lab),
Joshua Rogers, and Chanho Kim.
([CVE-2026-28390])
*Neil Horman*
* Fixed heap buffer overflow in hexadecimal conversion.
Severity: Low
Issue summary: Converting an excessively large OCTET STRING value to
a hexadecimal string leads to a heap buffer overflow on 32 bit platforms.
Impact summary: A heap buffer overflow may lead to a crash or possibly
an attacker controlled code execution or other undefined behavior.
Reported by: Quoc Tran (Xint.io - US Team).
([CVE-2026-31789])
*Igor Ustinov*
* Fixed usage of `openssl s_client -connect HOST -proxy PROXY` with `HOST`
containing a raw IPv6 address.
<!-- https://github.com/openssl/openssl/pull/30384 -->
*Peter Zhang*
### Changes between 3.0.18 and 3.0.19 [27 Jan 2026]
* Fixed Stack buffer overflow in CMS `AuthEnvelopedData` parsing.
Severity: High
Issue summary: Parsing CMS `AuthEnvelopedData` message with maliciously
crafted AEAD parameters can trigger a stack buffer overflow.
Impact summary: A stack buffer overflow may lead to a crash, causing Denial
of Service, or potentially remote code execution.
Reported by: Stanislav Fort (Aisle Research)
([CVE-2025-15467])
*Igor Ustinov*
* Fixed Heap out-of-bounds write in `BIO_f_linebuffer` on short writes.
Severity: Low
Issue summary: Writing large, newline-free data into a BIO chain using the
line-buffering filter where the next BIO performs short writes can trigger
a heap-based out-of-bounds write.
Impact summary: This out-of-bounds write can cause memory corruption
which typically results in a crash, leading to Denial of Service for
an application.
Reported by: Petr Simecek (Aisle Research) and Stanislav Fort (Aisle
Research)
([CVE-2025-68160])
*Stanislav Fort and Neil Horman*
* Fixed Unauthenticated/unencrypted trailing bytes with low-level OCB
function calls.
Severity: Low
Issue summary: When using the low-level OCB API directly with AES-NI or
other hardware-accelerated code paths, inputs whose length is not a multiple
of 16 bytes can leave the final partial block unencrypted and
unauthenticated.
Impact summary: The trailing 1-15 bytes of a message may be exposed in
cleartext on encryption and are not covered by the authentication tag,
allowing an attacker to read or tamper with those bytes without detection.
Reported by: Stanislav Fort (Aisle Research)
([CVE-2025-69418])
*Stanislav Fort*
* Fixed Out of bounds write in `PKCS12_get_friendlyname()` UTF-8 conversion.
Severity: Low
Issue summary: Calling `PKCS12_get_friendlyname()` function on a maliciously
crafted PKCS#12 file with a `BMPString` (UTF-16BE) friendly name containing
non-ASCII BMP code point can trigger a one byte write before the allocated
buffer.
Impact summary: The out-of-bounds write can cause a memory corruption
which can have various consequences including a Denial of Service.
Reported by: Stanislav Fort (Aisle Research)
([CVE-2025-69419])
*Norbert Pócs*
* Fixed Missing `ASN1_TYPE` validation in `TS_RESP_verify_response()` function.
Severity: Low
Issue summary: A type confusion vulnerability exists in the TimeStamp
Response verification code where an `ASN1_TYPE` union member is accessed
without first validating the type, causing an invalid or NULL pointer
dereference when processing a malformed `TimeStamp` Response file.
Impact summary: An application calling `TS_RESP_verify_response()`
with a malformed TimeStamp Response can be caused to dereference an invalid
or NULL pointer when reading, resulting in a Denial of Service.
Reported by: Luigino Camastra (Aisle Research)
([CVE-2025-69420])
*Bob Beck*
* Fixed NULL Pointer Dereference in `PKCS12_item_decrypt_d2i_ex()` function.
Severity: Low
Issue summary: Processing a malformed PKCS#12 file can trigger a NULL
pointer dereference in the `PKCS12_item_decrypt_d2i_ex()` function.
Impact summary: A NULL pointer dereference can trigger a crash which leads
to Denial of Service for an application processing PKCS#12 files.
Reported by: Luigino Camastra (Aisle Research)
([CVE-2025-69421])
*Luigino Camastra*
* Fixed Missing `ASN1_TYPE` validation in PKCS#12 parsing.
Severity: Low
Issue summary: An invalid or NULL pointer dereference can happen in
an application processing a malformed PKCS#12 file.
Impact summary: An application processing a malformed PKCS#12 file can be
caused to dereference an invalid or NULL pointer on memory read, resulting
in a Denial of Service.
Reported by: Luigino Camastra (Aisle Research)
([CVE-2026-22795])
*Bob Beck*
* Fixed `ASN1_TYPE` Type Confusion in the `PKCS7_digest_from_attributes()`
function.
Severity: Low
Issue summary: A type confusion vulnerability exists in the signature
verification of signed PKCS#7 data where an `ASN1_TYPE` union member
is accessed without first validating the type, causing an invalid or NULL
pointer dereference when processing malformed PKCS#7 data.
Impact summary: An application performing signature verification of PKCS#7
data or calling directly the `PKCS7_digest_from_attributes()` function can be
caused to dereference an invalid or NULL pointer when reading, resulting in
a Denial of Service.
Reported by: Luigino Camastra (Aisle Research)
([CVE-2026-22796])
*Bob Beck*
* Fixed incorrect acceptance of some malformed ECDSA signatures on s390x.
<!-- https://github.com/openssl/openssl/pull/29214 -->
*Holger Dengler*
* Source code has been reformatted with `clang-format`.
<!-- https://github.com/openssl/openssl/pull/29256 -->
*Bob Beck*
### Changes between 3.0.17 and 3.0.18 [30 Sep 2025]
* Fix Out-of-bounds read & write in RFC 3211 KEK Unwrap
Issue summary: An application trying to decrypt CMS messages encrypted using
password based encryption can trigger an out-of-bounds read and write.
Impact summary: This out-of-bounds read may trigger a crash which leads to
Denial of Service for an application. The out-of-bounds write can cause
a memory corruption which can have various consequences including
a Denial of Service or Execution of attacker-supplied code.
The issue was reported by Stanislav Fort (Aisle Research).
([CVE-2025-9230])
*Viktor Dukhovni*
* Fix Out-of-bounds read in HTTP client no_proxy handling
Issue summary: An application using the OpenSSL HTTP client API functions
may trigger an out-of-bounds read if the "no_proxy" environment variable is
set and the host portion of the authority component of the HTTP URL is an
IPv6 address.
Impact summary: An out-of-bounds read can trigger a crash which leads to
Denial of Service for an application.
The issue was reported by Stanislav Fort (Aisle Research).
([CVE-2025-9232])
*Stanislav Fort*
* Avoided a potential race condition introduced in 3.0.17, where
`OSSL_STORE_CTX` kept open during lookup while potentially being used
by multiple threads simultaneously, that could lead to potential crashes
when multiple concurrent TLS connections are served.
*Matt Caswell*
* Secure memory allocation calls are no longer used for HMAC keys.
*Dr Paul Dale*
* `openssl req` no longer generates certificates with an empty extension list
when SKID/AKID are set to `none` during generation.
*David Benjamin*
* The man page date is now derived from the release date provided
in `VERSION.dat` and not the current date for the released builds.
*Enji Cooper*
* Hardened the provider implementation of the RSA public key "encrypt"
operation to add a missing check that the caller-indicated output buffer
size is at least as large as the byte count of the RSA modulus. The issue
was reported by Arash Ale Ebrahim from SYSPWN.
This operation is typically invoked via `EVP_PKEY_encrypt(3)`. Callers that
in fact provide a sufficiently large buffer, but fail to correctly indicate
its size may now encounter unexpected errors. In applications that attempt
RSA public encryption into a buffer that is too small, an out-of-bounds
write is now avoided and an error is reported instead.
*Viktor Dukhovni*
### Changes between 3.0.16 and 3.0.17 [1 Jul 2025]
* none yet
### Changes between 3.0.15 and 3.0.16 [11 Feb 2025]
* Fixed timing side-channel in ECDSA signature computation.
@@ -951,6 +1299,24 @@ breaking changes, and mappings for the large list of deprecated functions.
### Changes between 3.0.0 and 3.0.1 [14 Dec 2021]
* Fixed carry bug in BN_mod_exp which may produce incorrect results on MIPS
squaring procedure. Many EC algorithms are affected, including some of the
TLS 1.3 default curves. Impact was not analyzed in detail, because the
pre-requisites for attack are considered unlikely and include reusing
private keys. Analysis suggests that attacks against RSA and DSA as a result
of this defect would be very difficult to perform and are not believed
likely. Attacks against DH are considered just feasible (although very
difficult) because most of the work necessary to deduce information about
a private key may be performed offline.
The amount of resources required for such an attack would be significant.
However, for an attack on TLS to be meaningful, the server would have
to share the DH private key among multiple clients, which is no longer
an option since CVE-2016-0701.
The issue only affects OpenSSL on MIPS platforms.
([CVE-2021-4160])
*Bernd Edlinger*
* Fixed invalid handling of X509_verify_cert() internal errors in libssl
Internally libssl in OpenSSL calls X509_verify_cert() on the client side to
verify a certificate supplied by a server. That function may return a
@@ -1814,7 +2180,7 @@ breaking changes, and mappings for the large list of deprecated functions.
*Richard Levitte*
* Fixed an overflow bug in the x64_64 Montgomery squaring procedure
* Fixed an overflow bug in the x86_64 Montgomery squaring procedure
used in exponentiation with 512-bit moduli. No EC algorithms are
affected. Analysis suggests that attacks against 2-prime RSA1024,
3-prime RSA1536, and DSA1024 as a result of this defect would be very
@@ -3273,7 +3639,7 @@ OpenSSL 1.1.1
* Support for TLSv1.3 added. Note that users upgrading from an earlier
version of OpenSSL should review their configuration settings to ensure
that they are still appropriate for TLSv1.3. For further information see:
<https://wiki.openssl.org/index.php/TLS1.3>
<https://github.com/openssl/openssl/wiki/TLS1.3>
*Matt Caswell*
@@ -4561,7 +4927,7 @@ OpenSSL 1.1.0
* The GOST engine was out of date and therefore it has been removed. An up
to date GOST engine is now being maintained in an external repository.
See: <https://wiki.openssl.org/index.php/Binaries>. Libssl still retains
See: <https://github.com/openssl/openssl/wiki/Binaries>. Libssl still retains
support for GOST ciphersuites (these are only activated if a GOST engine
is present).
@@ -5340,6 +5706,11 @@ OpenSSL 1.1.0
*Rob Percival <robpercival@google.com>*
* SSLv3 is by default disabled at build-time. Builds that are not
configured with "enable-ssl3" will not support SSLv3.
*Kurt Roeckx*
OpenSSL 1.0.2
-------------
@@ -19953,198 +20324,214 @@ ndif
<!-- Links -->
[CVE-2024-13176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-13176
[CVE-2024-9143]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-9143
[CVE-2024-6119]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-6119
[CVE-2024-5535]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-5535
[CVE-2024-4741]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-4741
[CVE-2024-4603]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-4603
[CVE-2024-2511]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-2511
[CVE-2024-0727]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-0727
[CVE-2023-6237]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-6237
[CVE-2023-6129]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-6129
[CVE-2023-5678]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-5678
[CVE-2023-5363]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-5363
[CVE-2023-4807]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-4807
[CVE-2023-3817]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3817
[CVE-2023-3446]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3446
[CVE-2023-2975]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-2975
[CVE-2002-0655]: https://openssl-library.org/news/vulnerabilities/#CVE-2002-0655
[CVE-2002-0656]: https://openssl-library.org/news/vulnerabilities/#CVE-2002-0656
[CVE-2002-0657]: https://openssl-library.org/news/vulnerabilities/#CVE-2002-0657
[CVE-2002-0659]: https://openssl-library.org/news/vulnerabilities/#CVE-2002-0659
[CVE-2003-0078]: https://openssl-library.org/news/vulnerabilities/#CVE-2003-0078
[CVE-2003-0543]: https://openssl-library.org/news/vulnerabilities/#CVE-2003-0543
[CVE-2003-0544]: https://openssl-library.org/news/vulnerabilities/#CVE-2003-0544
[CVE-2003-0545]: https://openssl-library.org/news/vulnerabilities/#CVE-2003-0545
[CVE-2003-0851]: https://openssl-library.org/news/vulnerabilities/#CVE-2003-0851
[CVE-2004-0079]: https://openssl-library.org/news/vulnerabilities/#CVE-2004-0079
[CVE-2004-0112]: https://openssl-library.org/news/vulnerabilities/#CVE-2004-0112
[CVE-2005-2969]: https://openssl-library.org/news/vulnerabilities/#CVE-2005-2969
[CVE-2006-2937]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-2937
[CVE-2006-2940]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-2940
[CVE-2006-3738]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-3738
[CVE-2006-4339]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-4339
[CVE-2006-4343]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-4343
[CVE-2007-4995]: https://openssl-library.org/news/vulnerabilities/#CVE-2007-4995
[CVE-2007-5135]: https://openssl-library.org/news/vulnerabilities/#CVE-2007-5135
[CVE-2008-0891]: https://openssl-library.org/news/vulnerabilities/#CVE-2008-0891
[CVE-2008-1672]: https://openssl-library.org/news/vulnerabilities/#CVE-2008-1672
[CVE-2008-1678]: https://openssl-library.org/news/vulnerabilities/#CVE-2008-1678
[CVE-2008-5077]: https://openssl-library.org/news/vulnerabilities/#CVE-2008-5077
[CVE-2009-0590]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-0590
[CVE-2009-0591]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-0591
[CVE-2009-0789]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-0789
[CVE-2009-1377]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-1377
[CVE-2009-1378]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-1378
[CVE-2009-1379]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-1379
[CVE-2009-1386]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-1386
[CVE-2009-3245]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-3245
[CVE-2009-3555]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-3555
[CVE-2009-4355]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-4355
[CVE-2010-0433]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-0433
[CVE-2010-0740]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-0740
[CVE-2010-1633]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-1633
[CVE-2010-3864]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-3864
[CVE-2010-4180]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-4180
[CVE-2010-4252]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-4252
[CVE-2011-0014]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-0014
[CVE-2011-3207]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-3207
[CVE-2011-3210]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-3210
[CVE-2011-4108]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4108
[CVE-2011-4109]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4109
[CVE-2011-4576]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4576
[CVE-2011-4577]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4577
[CVE-2011-4619]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4619
[CVE-2012-0027]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-0027
[CVE-2012-0050]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-0050
[CVE-2012-0884]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-0884
[CVE-2012-2110]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-2110
[CVE-2012-2333]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-2333
[CVE-2012-2686]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-2686
[CVE-2013-0166]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-0166
[CVE-2013-0169]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-0169
[CVE-2013-4353]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-4353
[CVE-2013-6450]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-6450
[CVE-2014-0076]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0076
[CVE-2014-0160]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0160
[CVE-2014-0195]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0195
[CVE-2014-0221]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0221
[CVE-2014-0224]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0224
[CVE-2014-3470]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3470
[CVE-2014-3505]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3505
[CVE-2014-3506]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3506
[CVE-2014-3507]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3507
[CVE-2014-3508]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3508
[CVE-2014-3509]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3509
[CVE-2014-3510]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3510
[CVE-2014-3511]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3511
[CVE-2014-3512]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3512
[CVE-2014-3513]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3513
[CVE-2014-3566]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3566
[CVE-2014-3567]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3567
[CVE-2014-3568]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3568
[CVE-2014-3569]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3569
[CVE-2014-3570]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3570
[CVE-2014-3571]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3571
[CVE-2014-3572]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3572
[CVE-2014-5139]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-5139
[CVE-2014-8275]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-8275
[CVE-2015-0204]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0204
[CVE-2015-0205]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0205
[CVE-2015-0206]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0206
[CVE-2015-0207]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0207
[CVE-2015-0208]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0208
[CVE-2015-0209]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0209
[CVE-2015-0285]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0285
[CVE-2015-0286]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0286
[CVE-2015-0287]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0287
[CVE-2015-0288]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0288
[CVE-2015-0289]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0289
[CVE-2015-0290]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0290
[CVE-2015-0291]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0291
[CVE-2015-0293]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0293
[CVE-2015-1787]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1787
[CVE-2015-1788]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1788
[CVE-2015-1789]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1789
[CVE-2015-1790]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1790
[CVE-2015-1791]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1791
[CVE-2015-1792]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1792
[CVE-2015-1793]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1793
[CVE-2015-3193]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3193
[CVE-2015-3194]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3194
[CVE-2015-3195]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3195
[CVE-2015-3196]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3196
[CVE-2015-3197]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3197
[CVE-2016-0701]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0701
[CVE-2016-0702]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0702
[CVE-2016-0705]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0705
[CVE-2016-0797]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0797
[CVE-2016-0798]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0798
[CVE-2016-0799]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0799
[CVE-2016-0800]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0800
[CVE-2016-2105]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2105
[CVE-2016-2106]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2106
[CVE-2016-2107]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2107
[CVE-2016-2109]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2109
[CVE-2016-2176]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2176
[CVE-2016-2177]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2177
[CVE-2016-2178]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2178
[CVE-2016-2179]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2179
[CVE-2016-2180]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2180
[CVE-2016-2181]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2181
[CVE-2016-2182]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2182
[CVE-2016-2183]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2183
[CVE-2016-6302]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6302
[CVE-2016-6303]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6303
[CVE-2016-6304]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6304
[CVE-2016-6305]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6305
[CVE-2016-6306]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6306
[CVE-2016-6307]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6307
[CVE-2016-6308]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6308
[CVE-2016-6309]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6309
[CVE-2016-7052]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-7052
[CVE-2016-7053]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-7053
[CVE-2016-7054]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-7054
[CVE-2016-7055]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-7055
[CVE-2017-3730]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3730
[CVE-2017-3731]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3731
[CVE-2017-3732]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3732
[CVE-2017-3733]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3733
[CVE-2017-3735]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3735
[CVE-2017-3736]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3736
[CVE-2017-3737]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3737
[CVE-2017-3738]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3738
[CVE-2018-0732]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0732
[CVE-2018-0733]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0733
[CVE-2018-0734]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0734
[CVE-2018-0735]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0735
[CVE-2018-0737]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0737
[CVE-2018-0739]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0739
[CVE-2018-5407]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-5407
[CVE-2019-1543]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1543
[CVE-2019-1547]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1547
[CVE-2019-1549]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1549
[CVE-2019-1551]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1551
[CVE-2019-1552]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1552
[CVE-2019-1559]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1559
[CVE-2019-1563]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1563
[CVE-2020-1967]: https://openssl-library.org/news/vulnerabilities/#CVE-2020-1967
[CVE-2020-1971]: https://openssl-library.org/news/vulnerabilities/#CVE-2020-1971
[CVE-2022-2097]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-2097
[CVE-2022-2274]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-2274
[CVE-2022-3996]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-3996
[CVE-2022-4203]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-4203
[CVE-2022-4304]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-4304
[CVE-2022-4450]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-4450
[CVE-2023-0215]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0215
[CVE-2023-0216]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0216
[CVE-2023-0217]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0217
[CVE-2023-0286]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0286
[CVE-2023-0401]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0401
[CVE-2023-0464]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0464
[CVE-2023-0465]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0465
[CVE-2023-0466]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0466
[CVE-2023-1255]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-1255
[CVE-2023-2650]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-2650
[CVE-2023-2975]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-2975
[CVE-2023-3446]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-3446
[CVE-2023-3817]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-3817
[CVE-2023-4807]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-4807
[CVE-2023-5363]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-5363
[CVE-2023-5678]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-5678
[CVE-2023-6129]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-6129
[CVE-2023-6237]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-6237
[CVE-2024-0727]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-0727
[CVE-2024-2511]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-2511
[CVE-2024-4603]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-4603
[CVE-2024-4741]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-4741
[CVE-2024-5535]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-5535
[CVE-2024-6119]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-6119
[CVE-2024-9143]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-9143
[CVE-2024-13176]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-13176
[CVE-2025-9230]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-9230
[CVE-2025-9232]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-9232
[CVE-2025-15467]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-15467
[CVE-2025-68160]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-68160
[CVE-2025-69418]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-69418
[CVE-2025-69419]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-69419
[CVE-2025-69420]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-69420
[CVE-2025-69421]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-69421
[CVE-2026-22795]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22795
[CVE-2026-22796]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22796
[CVE-2026-28387]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28387
[CVE-2026-28388]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28388
[CVE-2026-28389]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28389
[CVE-2026-28390]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28390
[CVE-2026-31789]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-31789
[CVE-2026-31790]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-31790
[RFC 2578 (STD 58), section 3.5]: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
[CVE-2023-2650]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-2650
[CVE-2023-1255]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-1255
[CVE-2023-0466]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0466
[CVE-2023-0465]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0465
[CVE-2023-0464]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0464
[CVE-2023-0401]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0401
[CVE-2023-0286]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0286
[CVE-2023-0217]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0217
[CVE-2023-0216]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0216
[CVE-2023-0215]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0215
[CVE-2022-4450]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4450
[CVE-2022-4304]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4304
[CVE-2022-4203]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4203
[CVE-2022-3996]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-3996
[CVE-2022-2274]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-2274
[CVE-2022-2097]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-2097
[CVE-2020-1971]: https://www.openssl.org/news/vulnerabilities.html#CVE-2020-1971
[CVE-2020-1967]: https://www.openssl.org/news/vulnerabilities.html#CVE-2020-1967
[CVE-2019-1563]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1563
[CVE-2019-1559]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1559
[CVE-2019-1552]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1552
[CVE-2019-1551]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1551
[CVE-2019-1549]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1549
[CVE-2019-1547]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1547
[CVE-2019-1543]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1543
[CVE-2018-5407]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-5407
[CVE-2018-0739]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0739
[CVE-2018-0737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0737
[CVE-2018-0735]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0735
[CVE-2018-0734]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0734
[CVE-2018-0733]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0733
[CVE-2018-0732]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0732
[CVE-2017-3738]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3738
[CVE-2017-3737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3737
[CVE-2017-3736]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3736
[CVE-2017-3735]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3735
[CVE-2017-3733]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3733
[CVE-2017-3732]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3732
[CVE-2017-3731]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3731
[CVE-2017-3730]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3730
[CVE-2016-7055]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7055
[CVE-2016-7054]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7054
[CVE-2016-7053]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7053
[CVE-2016-7052]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7052
[CVE-2016-6309]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6309
[CVE-2016-6308]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6308
[CVE-2016-6307]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6307
[CVE-2016-6306]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6306
[CVE-2016-6305]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6305
[CVE-2016-6304]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6304
[CVE-2016-6303]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6303
[CVE-2016-6302]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6302
[CVE-2016-2183]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2183
[CVE-2016-2182]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2182
[CVE-2016-2181]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2181
[CVE-2016-2180]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2180
[CVE-2016-2179]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2179
[CVE-2016-2178]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2178
[CVE-2016-2177]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2177
[CVE-2016-2176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2176
[CVE-2016-2109]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2109
[CVE-2016-2107]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2107
[CVE-2016-2106]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2106
[CVE-2016-2105]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2105
[CVE-2016-0800]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0800
[CVE-2016-0799]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0799
[CVE-2016-0798]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0798
[CVE-2016-0797]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0797
[CVE-2016-0705]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0705
[CVE-2016-0702]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0702
[CVE-2016-0701]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0701
[CVE-2015-3197]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3197
[CVE-2015-3196]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3196
[CVE-2015-3195]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3195
[CVE-2015-3194]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3194
[CVE-2015-3193]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3193
[CVE-2015-1793]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1793
[CVE-2015-1792]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1792
[CVE-2015-1791]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1791
[CVE-2015-1790]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1790
[CVE-2015-1789]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1789
[CVE-2015-1788]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1788
[CVE-2015-1787]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1787
[CVE-2015-0293]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0293
[CVE-2015-0291]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0291
[CVE-2015-0290]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0290
[CVE-2015-0289]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0289
[CVE-2015-0288]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0288
[CVE-2015-0287]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0287
[CVE-2015-0286]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0286
[CVE-2015-0285]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0285
[CVE-2015-0209]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0209
[CVE-2015-0208]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0208
[CVE-2015-0207]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0207
[CVE-2015-0206]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0206
[CVE-2015-0205]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0205
[CVE-2015-0204]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0204
[CVE-2014-8275]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-8275
[CVE-2014-5139]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-5139
[CVE-2014-3572]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3572
[CVE-2014-3571]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3571
[CVE-2014-3570]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3570
[CVE-2014-3569]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3569
[CVE-2014-3568]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3568
[CVE-2014-3567]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3567
[CVE-2014-3566]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3566
[CVE-2014-3513]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3513
[CVE-2014-3512]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3512
[CVE-2014-3511]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3511
[CVE-2014-3510]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3510
[CVE-2014-3509]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3509
[CVE-2014-3508]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3508
[CVE-2014-3507]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3507
[CVE-2014-3506]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3506
[CVE-2014-3505]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3505
[CVE-2014-3470]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3470
[CVE-2014-0224]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0224
[CVE-2014-0221]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0221
[CVE-2014-0195]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0195
[CVE-2014-0160]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0160
[CVE-2014-0076]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0076
[CVE-2013-6450]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-6450
[CVE-2013-4353]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-4353
[CVE-2013-0169]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-0169
[CVE-2013-0166]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-0166
[CVE-2012-2686]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2686
[CVE-2012-2333]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2333
[CVE-2012-2110]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2110
[CVE-2012-0884]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0884
[CVE-2012-0050]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0050
[CVE-2012-0027]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0027
[CVE-2011-4619]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4619
[CVE-2011-4577]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4577
[CVE-2011-4576]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4576
[CVE-2011-4109]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4109
[CVE-2011-4108]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4108
[CVE-2011-3210]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-3210
[CVE-2011-3207]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-3207
[CVE-2011-0014]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-0014
[CVE-2010-4252]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-4252
[CVE-2010-4180]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-4180
[CVE-2010-3864]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-3864
[CVE-2010-1633]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-1633
[CVE-2010-0740]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-0740
[CVE-2010-0433]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-0433
[CVE-2009-4355]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-4355
[CVE-2009-3555]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-3555
[CVE-2009-3245]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-3245
[CVE-2009-1386]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-1386
[CVE-2009-1379]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-1379
[CVE-2009-1378]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-1378
[CVE-2009-1377]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-1377
[CVE-2009-0789]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0789
[CVE-2009-0591]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0591
[CVE-2009-0590]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0590
[CVE-2008-5077]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-5077
[CVE-2008-1678]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-1678
[CVE-2008-1672]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-1672
[CVE-2008-0891]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-0891
[CVE-2007-5135]: https://www.openssl.org/news/vulnerabilities.html#CVE-2007-5135
[CVE-2007-4995]: https://www.openssl.org/news/vulnerabilities.html#CVE-2007-4995
[CVE-2006-4343]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-4343
[CVE-2006-4339]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-4339
[CVE-2006-3738]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-3738
[CVE-2006-2940]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2940
[CVE-2006-2937]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2937
[CVE-2005-2969]: https://www.openssl.org/news/vulnerabilities.html#CVE-2005-2969
[CVE-2004-0112]: https://www.openssl.org/news/vulnerabilities.html#CVE-2004-0112
[CVE-2004-0079]: https://www.openssl.org/news/vulnerabilities.html#CVE-2004-0079
[CVE-2003-0851]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0851
[CVE-2003-0545]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0545
[CVE-2003-0544]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0544
[CVE-2003-0543]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0543
[CVE-2003-0078]: https://www.openssl.org/news/vulnerabilities.html#CVE-2003-0078
[CVE-2002-0659]: https://www.openssl.org/news/vulnerabilities.html#CVE-2002-0659
[CVE-2002-0657]: https://www.openssl.org/news/vulnerabilities.html#CVE-2002-0657
[CVE-2002-0656]: https://www.openssl.org/news/vulnerabilities.html#CVE-2002-0656
[CVE-2002-0655]: https://www.openssl.org/news/vulnerabilities.html#CVE-2002-0655
+2 -1
View File
@@ -5,7 +5,8 @@
my $vc_win64a_info = {};
sub vc_win64a_info {
unless (%$vc_win64a_info) {
if (`nasm -v 2>NUL` =~ /NASM version ([0-9]+\.[0-9]+)/ && $1 >= 2.0) {
# Minimum NASM version is 2.09 otherwise SHA3 might be miscompiled
if (`nasm -v 2>NUL` =~ /NASM version ([0-9]+)\.([0-9]+)/ && ($1 > 2 || ($1 == 2 && $2 >= 9))) {
$vc_win64a_info = { AS => "nasm",
ASFLAGS => "-g",
asflags => "-Ox -f win64 -DNEAR",
@@ -167,12 +167,14 @@
# Build models
'nonstop-model-put' => {
template => 1,
disable => [ 'secure-memory' ],
defines => ['_PUT_MODEL_',
'_REENTRANT', '_THREAD_SUPPORT_FUNCTIONS'],
ex_libs => '-lput',
},
'nonstop-model-spt' => {
template => 1,
disable => [ 'secure-memory' ],
defines => ['_SPT_MODEL_',
'_REENTRANT', '_ENABLE_FLOSS_THREADS'],
ex_libs => '-lspt',
@@ -3,6 +3,8 @@
##
## {- join("\n## ", @autowarntext) -}
{-
use Time::Piece;
use OpenSSL::Util;
our $makedep_scheme = $config{makedep_scheme};
@@ -64,10 +66,20 @@ OPTIONS={- $config{options} -}
CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -})
SRCDIR={- $config{sourcedir} -}
BLDDIR={- $config{builddir} -}
RESULT_D=$(BLDDIR)/test-runs
FIPSKEY={- $config{FIPSKEY} -}
VERSION={- "$config{full_version}" -}
VERSION_NUMBER={- "$config{version}" -}
RELEASE_DATE={- my $t = localtime;
if ($config{"release_date"}) {
# Provide the user with a more meaningful error message
# than the default internal parsing error from
# `Time::Piece->strptime(..)`.
eval { $t = Time::Piece->strptime($config{"release_date"}, "%d %b %Y"); } ||
die "Parsing \$config{release_date} ('$config{release_date}') failed: $@";
}
$t->strftime("%Y-%m-%d") -}
MAJOR={- $config{major} -}
MINOR={- $config{minor} -}
SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
@@ -589,7 +601,7 @@ clean: libclean
-find . -name '*{- platform->objext() -}' \! -name '.*' \! -type d -exec $(RM) {} \;
$(RM) core
$(RM) tags TAGS doc-nits md-nits
$(RM) -r test/test-runs
$(RM) -r $(RESULT_D)
$(RM) providers/fips*.new
$(RM) openssl.pc libcrypto.pc libssl.pc
-find . -type l \! -name '.*' -exec $(RM) {} \;
@@ -1540,7 +1552,8 @@ EOF
return <<"EOF";
$args{src}: $pod
pod2man --name=$name --section=$section\$(MANSUFFIX) --center=OpenSSL \\
--release=\$(VERSION) $pod >\$\@
--date=\$(RELEASE_DATE) --release=\$(VERSION) \\
$pod >\$\@
EOF
} elsif (platform->isdef($args{src})) {
#
@@ -38,6 +38,7 @@
PLATFORM={- $config{target} -}
SRCDIR={- $config{sourcedir} -}
BLDDIR={- $config{builddir} -}
RESULT_D=$(BLDDIR)\test-runs
FIPSKEY={- $config{FIPSKEY} -}
VERSION={- "$config{full_version}" -}
@@ -217,7 +218,7 @@ OPENSSLDIR_dir={- canonpath($openssldir_dir) -}
LIBDIR={- our $libdir = $config{libdir} || "lib";
file_name_is_absolute($libdir) ? "" : $libdir -}
MODULESDIR_dev={- use File::Spec::Functions qw(:DEFAULT splitpath catpath);
our $modulesprefix = catdir($prefix,$libdir);
our $modulesprefix = file_name_is_absolute($libdir) ? $libdir : catdir($prefix,$libdir);
our ($modulesprefix_dev, $modulesprefix_dir,
$modulesprefix_file) =
splitpath($modulesprefix, 1);
@@ -477,7 +478,7 @@ clean: libclean
-del /Q /S /F engines\*.lib engines\*.exp
-del /Q /S /F apps\*.lib apps\*.rc apps\*.res apps\*.exp
-del /Q /S /F test\*.exp
-rd /Q /S test\test-runs
-@if exist "$(RESULT_D)" rd /Q /S "$(RESULT_D)"
distclean: clean
-del /Q /F include\openssl\configuration.h
+4 -3
View File
@@ -1,6 +1,6 @@
#! /usr/bin/env perl
# -*- mode: perl; -*-
# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
@@ -157,6 +157,7 @@ my @gcc_devteam_warn = qw(
-Wextra
-Wno-unused-parameter
-Wno-missing-field-initializers
-Wno-unterminated-string-initialization
-Wswitch
-Wsign-compare
-Wshadow
@@ -602,7 +603,7 @@ my @disable_cascades = (
# Without shared libraries, dynamic engines aren't possible.
# This is due to them having to link with libcrypto and register features
# using the ENGINE functionality, and since that relies on global tables,
# those *have* to be exacty the same as the ones accessed from the app,
# those *have* to be exactly the same as the ones accessed from the app,
# which cannot be guaranteed if shared libraries aren't present.
# (note that even with shared libraries, both the app and dynamic engines
# must be linked with the same library)
@@ -1791,7 +1792,7 @@ my %skipdir = ();
my %disabled_info = (); # For configdata.pm
foreach my $what (sort keys %disabled) {
# There are deprecated disablables that translate to themselves.
# They cause disabling cascades, but should otherwise not regiter.
# They cause disabling cascades, but should otherwise not register.
next if $deprecated_disablables{$what};
# The generated $disabled{"deprecated-x.y"} entries are special
# and treated properly elsewhere
+2 -2
View File
@@ -1471,7 +1471,7 @@ over the build process. Typically these should be defined prior to running
PERL
The name of the Perl executable to use when building OpenSSL.
Only needed if builing should use a different Perl executable
Only needed if building should use a different Perl executable
than what is used to run the Configure script.
RANLIB
@@ -1627,7 +1627,7 @@ working incorrectly. If you think you encountered a bug, please
Along with a short description of the bug, please provide the complete
configure command line and the relevant output including the error message.
Note: To make the output readable, pleace add a 'code fence' (three backquotes
Note: To make the output readable, please add a 'code fence' (three backquotes
` ``` ` on a separate line) before and after your output:
```
+279 -181
View File
@@ -18,6 +18,87 @@ OpenSSL Releases
OpenSSL 3.0
-----------
### Major changes between OpenSSL 3.0.19 and OpenSSL 3.0.20 [7 Apr 2026]
OpenSSL 3.0.20 is a security patch release. The most severe CVE fixed in this
release is Medium.
This release incorporates the following bug fixes and mitigations:
* Fixed incorrect failure handling in RSA KEM RSASVE encapsulation.
([CVE-2026-31790])
* Fixed potential use-after-free in DANE client code.
([CVE-2026-28387])
* Fixed NULL pointer dereference when processing a delta CRL.
([CVE-2026-28388])
* Fixed possible NULL dereference when processing CMS KeyAgreeRecipientInfo.
([CVE-2026-28389])
* Fixed possible NULL dereference when processing CMS
KeyTransportRecipientInfo.
([CVE-2026-28390])
* Fixed heap buffer overflow in hexadecimal conversion.
([CVE-2026-31789])
### Major changes between OpenSSL 3.0.18 and OpenSSL 3.0.19 [27 Jan 2026]
OpenSSL 3.0.19 is a security patch release. The most severe CVE fixed in this
release is High.
This release incorporates the following bug fixes and mitigations:
* Fixed Stack buffer overflow in CMS `AuthEnvelopedData` parsing.
([CVE-2025-15467])
* Fixed Heap out-of-bounds write in `BIO_f_linebuffer` on short writes.
([CVE-2025-68160])
* Fixed Unauthenticated/unencrypted trailing bytes with low-level OCB
function calls.
([CVE-2025-69418])
* Fixed Out of bounds write in `PKCS12_get_friendlyname()` UTF-8 conversion.
([CVE-2025-69419])
* Fixed Missing `ASN1_TYPE` validation in `TS_RESP_verify_response()`
function.
([CVE-2025-69420])
* Fixed NULL Pointer Dereference in `PKCS12_item_decrypt_d2i_ex()` function.
([CVE-2025-69421])
* Fixed Missing `ASN1_TYPE` validation in PKCS#12 parsing.
([CVE-2026-22795])
* Fixed `ASN1_TYPE` Type Confusion in the `PKCS7_digest_from_attributes()`
function.
([CVE-2026-22796])
### Major changes between OpenSSL 3.0.17 and OpenSSL 3.0.18 [30 Sep 2025]
OpenSSL 3.0.18 is a security patch release. The most severe CVE fixed in this
release is Moderate.
This release incorporates the following bug fixes and mitigations:
* Fix Out-of-bounds read & write in RFC 3211 KEK Unwrap.
([CVE-2025-9230])
* Fix Out-of-bounds read in HTTP client no_proxy handling.
([CVE-2025-9232])
### Major changes between OpenSSL 3.0.16 and OpenSSL 3.0.17 [1 Jul 2025]
OpenSSL 3.0.17 is a bug fix release.
This release incorporates the following bug fixes and mitigations:
* Miscellaneous minor bug fixes.
### Major changes between OpenSSL 3.0.15 and OpenSSL 3.0.16 [11 Feb 2025]
OpenSSL 3.0.16 is a security patch release. The most severe CVE fixed in this
@@ -142,7 +223,7 @@ This release incorporates the following bug fixes and mitigations:
* Fixed a bug where the RC4-MD5 ciphersuite incorrectly used the
AAD data as the MAC key ([CVE-2022-1434])
* Fix a bug in the OPENSSL_LH_flush() function that breaks reuse of the memory
occuppied by the removed hash table entries ([CVE-2022-1473])
occupied by the removed hash table entries ([CVE-2022-1473])
### Major changes between OpenSSL 3.0.1 and OpenSSL 3.0.2 [15 Mar 2022]
@@ -151,6 +232,8 @@ This release incorporates the following bug fixes and mitigations:
### Major changes between OpenSSL 3.0.0 and OpenSSL 3.0.1 [14 Dec 2021]
* Fixed carry bug in BN_mod_exp which may produce incorrect results on MIPS
([CVE-2021-4160])
* Fixed invalid handling of X509_verify_cert() internal errors in libssl
([CVE-2021-4044])
* Allow fetching an operation from the provider that owns an unexportable key
@@ -161,7 +244,7 @@ This release incorporates the following bug fixes and mitigations:
* Enhanced 'openssl list' with many new options.
* Added migration guide to man7.
* Implemented support for fully "pluggable" TLSv1.3 groups.
* Added suport for Kernel TLS (KTLS).
* Added support for Kernel TLS (KTLS).
* Changed the license to the Apache License v2.0.
* Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2,
RC4, RC5, and DES to the legacy provider.
@@ -204,7 +287,7 @@ This release incorporates the following bug fixes and mitigations:
* Deprecated ERR_put_error(), ERR_get_error_line(), ERR_get_error_line_data(),
ERR_peek_error_line_data(), ERR_peek_last_error_line_data() and
ERR_func_error_string().
* Added OSSL_PROVIDER_available(), to check provider availibility.
* Added OSSL_PROVIDER_available(), to check provider availability.
* Added 'openssl mac' that uses the EVP_MAC API.
* Added 'openssl kdf' that uses the EVP_KDF API.
* Add OPENSSL_info() and 'openssl info' to get built-in data.
@@ -278,7 +361,7 @@ OpenSSL 1.1.1
### Major changes between OpenSSL 1.1.1d and OpenSSL 1.1.1e [17 Mar 2020]
* Fixed an overflow bug in the x64_64 Montgomery squaring procedure
* Fixed an overflow bug in the x86_64 Montgomery squaring procedure
used in exponentiation with 512-bit moduli ([CVE-2019-1551])
### Major changes between OpenSSL 1.1.1c and OpenSSL 1.1.1d [10 Sep 2019]
@@ -329,7 +412,7 @@ OpenSSL 1.1.1
* Rewrite of the packet construction code for "safer" packet handling
* Rewrite of the extension handling code
For further important information, see the [TLS1.3 page](
https://wiki.openssl.org/index.php/TLS1.3) in the OpenSSL Wiki.
https://github.com/openssl/openssl/wiki/TLS1.3) in the OpenSSL Wiki.
* Complete rewrite of the OpenSSL random number generator to introduce the
following capabilities
@@ -1508,179 +1591,194 @@ OpenSSL 0.9.x
* Support for various new platforms
<!-- Links -->
[CVE-2024-13176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-13176
[CVE-2024-9143]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-9143
[CVE-2024-6119]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-6119
[CVE-2024-5535]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-5535
[CVE-2024-4741]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-4741
[CVE-2024-4603]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-4603
[CVE-2024-2511]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-2511
[CVE-2024-0727]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-0727
[CVE-2023-6237]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-6237
[CVE-2023-6129]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-6129
[CVE-2023-5678]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-5678
[CVE-2023-5363]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-5363
[CVE-2023-4807]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-4807
[CVE-2023-3817]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3817
[CVE-2023-3446]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3446
[CVE-2023-2975]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-2975
[CVE-2023-2650]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-2650
[CVE-2023-1255]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-1255
[CVE-2023-0466]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0466
[CVE-2023-0465]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0465
[CVE-2023-0464]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0464
[CVE-2023-0401]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0401
[CVE-2023-0286]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0286
[CVE-2023-0217]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0217
[CVE-2023-0216]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0216
[CVE-2023-0215]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0215
[CVE-2022-4450]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4450
[CVE-2022-4304]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4304
[CVE-2022-4203]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-4203
[CVE-2022-3996]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-3996
[CVE-2022-2274]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-2274
[CVE-2022-2097]: https://www.openssl.org/news/vulnerabilities.html#CVE-2022-2097
[CVE-2020-1971]: https://www.openssl.org/news/vulnerabilities.html#CVE-2020-1971
[CVE-2020-1967]: https://www.openssl.org/news/vulnerabilities.html#CVE-2020-1967
[CVE-2019-1563]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1563
[CVE-2019-1559]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1559
[CVE-2019-1552]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1552
[CVE-2019-1551]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1551
[CVE-2019-1549]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1549
[CVE-2019-1547]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1547
[CVE-2019-1543]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1543
[CVE-2018-5407]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-5407
[CVE-2018-0739]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0739
[CVE-2018-0737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0737
[CVE-2018-0735]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0735
[CVE-2018-0734]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0734
[CVE-2018-0733]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0733
[CVE-2018-0732]: https://www.openssl.org/news/vulnerabilities.html#CVE-2018-0732
[CVE-2017-3738]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3738
[CVE-2017-3737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3737
[CVE-2017-3736]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3736
[CVE-2017-3735]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3735
[CVE-2017-3733]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3733
[CVE-2017-3732]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3732
[CVE-2017-3731]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3731
[CVE-2017-3730]: https://www.openssl.org/news/vulnerabilities.html#CVE-2017-3730
[CVE-2016-7055]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7055
[CVE-2016-7054]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7054
[CVE-2016-7053]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7053
[CVE-2016-7052]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-7052
[CVE-2016-6309]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6309
[CVE-2016-6308]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6308
[CVE-2016-6307]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6307
[CVE-2016-6306]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6306
[CVE-2016-6305]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6305
[CVE-2016-6304]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6304
[CVE-2016-6303]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6303
[CVE-2016-6302]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-6302
[CVE-2016-2183]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2183
[CVE-2016-2182]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2182
[CVE-2016-2181]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2181
[CVE-2016-2180]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2180
[CVE-2016-2179]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2179
[CVE-2016-2178]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2178
[CVE-2016-2177]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2177
[CVE-2016-2176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2176
[CVE-2016-2109]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2109
[CVE-2016-2107]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2107
[CVE-2016-2106]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2106
[CVE-2016-2105]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-2105
[CVE-2016-0800]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0800
[CVE-2016-0799]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0799
[CVE-2016-0798]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0798
[CVE-2016-0797]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0797
[CVE-2016-0705]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0705
[CVE-2016-0702]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0702
[CVE-2016-0701]: https://www.openssl.org/news/vulnerabilities.html#CVE-2016-0701
[CVE-2015-3197]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3197
[CVE-2015-3196]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3196
[CVE-2015-3195]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3195
[CVE-2015-3194]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3194
[CVE-2015-3193]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-3193
[CVE-2015-1793]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1793
[CVE-2015-1792]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1792
[CVE-2015-1791]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1791
[CVE-2015-1790]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1790
[CVE-2015-1789]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1789
[CVE-2015-1788]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1788
[CVE-2015-1787]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-1787
[CVE-2015-0293]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0293
[CVE-2015-0291]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0291
[CVE-2015-0290]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0290
[CVE-2015-0289]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0289
[CVE-2015-0288]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0288
[CVE-2015-0287]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0287
[CVE-2015-0286]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0286
[CVE-2015-0285]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0285
[CVE-2015-0209]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0209
[CVE-2015-0208]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0208
[CVE-2015-0207]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0207
[CVE-2015-0206]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0206
[CVE-2015-0205]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0205
[CVE-2015-0204]: https://www.openssl.org/news/vulnerabilities.html#CVE-2015-0204
[CVE-2014-8275]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-8275
[CVE-2014-5139]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-5139
[CVE-2014-3572]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3572
[CVE-2014-3571]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3571
[CVE-2014-3570]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3570
[CVE-2014-3569]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3569
[CVE-2014-3568]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3568
[CVE-2014-3567]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3567
[CVE-2014-3566]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3566
[CVE-2014-3513]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3513
[CVE-2014-3512]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3512
[CVE-2014-3511]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3511
[CVE-2014-3510]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3510
[CVE-2014-3509]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3509
[CVE-2014-3508]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3508
[CVE-2014-3507]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3507
[CVE-2014-3506]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3506
[CVE-2014-3505]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3505
[CVE-2014-3470]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-3470
[CVE-2014-0224]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0224
[CVE-2014-0221]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0221
[CVE-2014-0198]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0198
[CVE-2014-0195]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0195
[CVE-2014-0160]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0160
[CVE-2014-0076]: https://www.openssl.org/news/vulnerabilities.html#CVE-2014-0076
[CVE-2013-6450]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-6450
[CVE-2013-6449]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-6449
[CVE-2013-4353]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-4353
[CVE-2013-0169]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-0169
[CVE-2013-0166]: https://www.openssl.org/news/vulnerabilities.html#CVE-2013-0166
[CVE-2012-2686]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2686
[CVE-2012-2333]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2333
[CVE-2012-2110]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-2110
[CVE-2012-0884]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0884
[CVE-2012-0050]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0050
[CVE-2012-0027]: https://www.openssl.org/news/vulnerabilities.html#CVE-2012-0027
[CVE-2011-4619]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4619
[CVE-2011-4577]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4577
[CVE-2011-4576]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4576
[CVE-2011-4108]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-4108
[CVE-2011-3210]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-3210
[CVE-2011-3207]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-3207
[CVE-2011-0014]: https://www.openssl.org/news/vulnerabilities.html#CVE-2011-0014
[CVE-2010-5298]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-5298
[CVE-2010-4252]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-4252
[CVE-2010-4180]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-4180
[CVE-2010-3864]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-3864
[CVE-2010-2939]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-2939
[CVE-2010-1633]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-1633
[CVE-2010-0740]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-0740
[CVE-2010-0433]: https://www.openssl.org/news/vulnerabilities.html#CVE-2010-0433
[CVE-2009-3555]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-3555
[CVE-2009-0789]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0789
[CVE-2009-0591]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0591
[CVE-2009-0590]: https://www.openssl.org/news/vulnerabilities.html#CVE-2009-0590
[CVE-2008-5077]: https://www.openssl.org/news/vulnerabilities.html#CVE-2008-5077
[CVE-2006-4343]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-4343
[CVE-2006-4339]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-4339
[CVE-2006-3737]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-3737
[CVE-2006-2940]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2940
[CVE-2006-2937]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2937
[CVE-2005-2969]: https://www.openssl.org/news/vulnerabilities.html#CVE-2005-2969
[CVE-2005-2969]: https://openssl-library.org/news/vulnerabilities/#CVE-2005-2969
[CVE-2006-2937]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-2937
[CVE-2006-2940]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-2940
[CVE-2006-3737]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-3737
[CVE-2006-4339]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-4339
[CVE-2006-4343]: https://openssl-library.org/news/vulnerabilities/#CVE-2006-4343
[CVE-2008-5077]: https://openssl-library.org/news/vulnerabilities/#CVE-2008-5077
[CVE-2009-0590]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-0590
[CVE-2009-0591]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-0591
[CVE-2009-0789]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-0789
[CVE-2009-3555]: https://openssl-library.org/news/vulnerabilities/#CVE-2009-3555
[CVE-2010-0433]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-0433
[CVE-2010-0740]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-0740
[CVE-2010-1633]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-1633
[CVE-2010-2939]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-2939
[CVE-2010-3864]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-3864
[CVE-2010-4180]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-4180
[CVE-2010-4252]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-4252
[CVE-2010-5298]: https://openssl-library.org/news/vulnerabilities/#CVE-2010-5298
[CVE-2011-0014]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-0014
[CVE-2011-3207]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-3207
[CVE-2011-3210]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-3210
[CVE-2011-4108]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4108
[CVE-2011-4576]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4576
[CVE-2011-4577]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4577
[CVE-2011-4619]: https://openssl-library.org/news/vulnerabilities/#CVE-2011-4619
[CVE-2012-0027]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-0027
[CVE-2012-0050]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-0050
[CVE-2012-0884]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-0884
[CVE-2012-2110]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-2110
[CVE-2012-2333]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-2333
[CVE-2012-2686]: https://openssl-library.org/news/vulnerabilities/#CVE-2012-2686
[CVE-2013-0166]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-0166
[CVE-2013-0169]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-0169
[CVE-2013-4353]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-4353
[CVE-2013-6449]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-6449
[CVE-2013-6450]: https://openssl-library.org/news/vulnerabilities/#CVE-2013-6450
[CVE-2014-0076]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0076
[CVE-2014-0160]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0160
[CVE-2014-0195]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0195
[CVE-2014-0198]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0198
[CVE-2014-0221]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0221
[CVE-2014-0224]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-0224
[CVE-2014-3470]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3470
[CVE-2014-3505]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3505
[CVE-2014-3506]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3506
[CVE-2014-3507]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3507
[CVE-2014-3508]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3508
[CVE-2014-3509]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3509
[CVE-2014-3510]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3510
[CVE-2014-3511]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3511
[CVE-2014-3512]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3512
[CVE-2014-3513]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3513
[CVE-2014-3566]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3566
[CVE-2014-3567]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3567
[CVE-2014-3568]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3568
[CVE-2014-3569]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3569
[CVE-2014-3570]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3570
[CVE-2014-3571]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3571
[CVE-2014-3572]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-3572
[CVE-2014-5139]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-5139
[CVE-2014-8275]: https://openssl-library.org/news/vulnerabilities/#CVE-2014-8275
[CVE-2015-0204]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0204
[CVE-2015-0205]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0205
[CVE-2015-0206]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0206
[CVE-2015-0207]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0207
[CVE-2015-0208]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0208
[CVE-2015-0209]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0209
[CVE-2015-0285]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0285
[CVE-2015-0286]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0286
[CVE-2015-0287]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0287
[CVE-2015-0288]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0288
[CVE-2015-0289]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0289
[CVE-2015-0290]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0290
[CVE-2015-0291]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0291
[CVE-2015-0293]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-0293
[CVE-2015-1787]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1787
[CVE-2015-1788]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1788
[CVE-2015-1789]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1789
[CVE-2015-1790]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1790
[CVE-2015-1791]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1791
[CVE-2015-1792]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1792
[CVE-2015-1793]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-1793
[CVE-2015-3193]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3193
[CVE-2015-3194]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3194
[CVE-2015-3195]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3195
[CVE-2015-3196]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3196
[CVE-2015-3197]: https://openssl-library.org/news/vulnerabilities/#CVE-2015-3197
[CVE-2016-0701]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0701
[CVE-2016-0702]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0702
[CVE-2016-0705]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0705
[CVE-2016-0797]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0797
[CVE-2016-0798]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0798
[CVE-2016-0799]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0799
[CVE-2016-0800]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-0800
[CVE-2016-2105]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2105
[CVE-2016-2106]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2106
[CVE-2016-2107]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2107
[CVE-2016-2109]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2109
[CVE-2016-2176]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2176
[CVE-2016-2177]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2177
[CVE-2016-2178]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2178
[CVE-2016-2179]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2179
[CVE-2016-2180]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2180
[CVE-2016-2181]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2181
[CVE-2016-2182]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2182
[CVE-2016-2183]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-2183
[CVE-2016-6302]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6302
[CVE-2016-6303]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6303
[CVE-2016-6304]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6304
[CVE-2016-6305]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6305
[CVE-2016-6306]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6306
[CVE-2016-6307]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6307
[CVE-2016-6308]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6308
[CVE-2016-6309]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-6309
[CVE-2016-7052]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-7052
[CVE-2016-7053]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-7053
[CVE-2016-7054]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-7054
[CVE-2016-7055]: https://openssl-library.org/news/vulnerabilities/#CVE-2016-7055
[CVE-2017-3730]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3730
[CVE-2017-3731]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3731
[CVE-2017-3732]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3732
[CVE-2017-3733]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3733
[CVE-2017-3735]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3735
[CVE-2017-3736]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3736
[CVE-2017-3737]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3737
[CVE-2017-3738]: https://openssl-library.org/news/vulnerabilities/#CVE-2017-3738
[CVE-2018-0732]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0732
[CVE-2018-0733]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0733
[CVE-2018-0734]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0734
[CVE-2018-0735]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0735
[CVE-2018-0737]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0737
[CVE-2018-0739]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-0739
[CVE-2018-5407]: https://openssl-library.org/news/vulnerabilities/#CVE-2018-5407
[CVE-2019-1543]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1543
[CVE-2019-1547]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1547
[CVE-2019-1549]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1549
[CVE-2019-1551]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1551
[CVE-2019-1552]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1552
[CVE-2019-1559]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1559
[CVE-2019-1563]: https://openssl-library.org/news/vulnerabilities/#CVE-2019-1563
[CVE-2020-1967]: https://openssl-library.org/news/vulnerabilities/#CVE-2020-1967
[CVE-2020-1971]: https://openssl-library.org/news/vulnerabilities/#CVE-2020-1971
[CVE-2022-2097]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-2097
[CVE-2022-2274]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-2274
[CVE-2022-3996]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-3996
[CVE-2022-4203]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-4203
[CVE-2022-4304]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-4304
[CVE-2022-4450]: https://openssl-library.org/news/vulnerabilities/#CVE-2022-4450
[CVE-2023-0215]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0215
[CVE-2023-0216]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0216
[CVE-2023-0217]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0217
[CVE-2023-0286]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0286
[CVE-2023-0401]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0401
[CVE-2023-0464]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0464
[CVE-2023-0465]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0465
[CVE-2023-0466]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-0466
[CVE-2023-1255]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-1255
[CVE-2023-2650]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-2650
[CVE-2023-2975]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-2975
[CVE-2023-3446]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-3446
[CVE-2023-3817]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-3817
[CVE-2023-4807]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-4807
[CVE-2023-5363]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-5363
[CVE-2023-5678]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-5678
[CVE-2023-6129]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-6129
[CVE-2023-6237]: https://openssl-library.org/news/vulnerabilities/#CVE-2023-6237
[CVE-2024-0727]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-0727
[CVE-2024-2511]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-2511
[CVE-2024-4603]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-4603
[CVE-2024-4741]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-4741
[CVE-2024-5535]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-5535
[CVE-2024-6119]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-6119
[CVE-2024-9143]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-9143
[CVE-2024-13176]: https://openssl-library.org/news/vulnerabilities/#CVE-2024-13176
[CVE-2025-9230]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-9230
[CVE-2025-9232]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-9232
[CVE-2025-15467]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-15467
[CVE-2025-68160]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-68160
[CVE-2025-69418]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-69418
[CVE-2025-69419]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-69419
[CVE-2025-69420]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-69420
[CVE-2025-69421]: https://openssl-library.org/news/vulnerabilities/#CVE-2025-69421
[CVE-2026-22795]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22795
[CVE-2026-22796]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22796
[CVE-2026-28387]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28387
[CVE-2026-28388]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28388
[CVE-2026-28389]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28389
[CVE-2026-28390]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28390
[CVE-2026-31789]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-31789
[CVE-2026-31790]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-31790
+5
View File
@@ -79,6 +79,11 @@ Quick start
OpenSSL or
- `perl Configure` to let Configure figure out the platform
a. If you don't plan to develop OpenSSL yourself and don't need to rebuild,
in other words, if you always do a new build, turning off the build
dependency feature can speed up build times by up to 50%:
`perl Configure no-makedepend`
6. `nmake`
7. `nmake test`
+1 -1
View File
@@ -8,7 +8,7 @@ The ENGINE API was introduced in OpenSSL version 0.9.6 as a low level
interface for adding alternative implementations of cryptographic
primitives, most notably for integrating hardware crypto devices.
The ENGINE interface has its limitations and it has been superseeded
The ENGINE interface has its limitations and it has been superseded
by the [PROVIDER API](README-PROVIDERS.md), it is deprecated in OpenSSL
version 3.0. The following documentation is retained as an aid for
users who need to maintain or support existing ENGINE implementations.
+4 -5
View File
@@ -128,8 +128,7 @@ available online.
Wiki
----
There is a Wiki at [wiki.openssl.org] which is currently not very active.
It contains a lot of useful information, not all of which is up to date.
There is a [GitHub Wiki] which is currently not very active.
License
=======
@@ -162,7 +161,7 @@ attempting to develop or distribute cryptographic code.
Copyright
=========
Copyright (c) 1998-2025 The OpenSSL Project
Copyright (c) 1998-2026 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
@@ -178,8 +177,8 @@ All rights reserved.
<https://github.com/openssl/openssl>
"OpenSSL GitHub Mirror"
[wiki.openssl.org]:
<https://wiki.openssl.org>
[GitHub Wiki]:
<https://github.com/openssl/openssl/wiki>
"OpenSSL Wiki"
[migration_guide(7ossl)]:
+2 -2
View File
@@ -1,7 +1,7 @@
MAJOR=3
MINOR=0
PATCH=16
PATCH=20
PRE_RELEASE_TAG=
BUILD_METADATA=
RELEASE_DATE="11 Feb 2025"
RELEASE_DATE="7 Apr 2026"
SHLIB_VERSION=3
+383
View File
@@ -0,0 +1,383 @@
#!/usr/bin/env perl
# Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
#
# Wrapper around the ca to make it easier to use
#
# WARNING: do not edit!
# Generated by Makefile from apps/CA.pl.in
use strict;
use warnings;
my $verbose = 1;
my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify");
my $openssl = $ENV{'OPENSSL'} // "openssl";
$ENV{'OPENSSL'} = $openssl;
my @openssl = split_val($openssl);
my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} // "";
my @OPENSSL_CONFIG = split_val($OPENSSL_CONFIG);
# Command invocations.
my @REQ = (@openssl, "req", @OPENSSL_CONFIG);
my @CA = (@openssl, "ca", @OPENSSL_CONFIG);
my @VERIFY = (@openssl, "verify");
my @X509 = (@openssl, "x509");
my @PKCS12 = (@openssl, "pkcs12");
# Default values for various configuration settings.
my $CATOP = "./demoCA";
my $CAKEY = "cakey.pem";
my $CAREQ = "careq.pem";
my $CACERT = "cacert.pem";
my $CACRL = "crl.pem";
my @DAYS = qw(-days 365);
my @CADAYS = qw(-days 1095); # 3 years
my @EXTENSIONS = qw(-extensions v3_ca);
my @POLICY = qw(-policy policy_anything);
my $NEWKEY = "newkey.pem";
my $NEWREQ = "newreq.pem";
my $NEWCERT = "newcert.pem";
my $NEWP12 = "newcert.p12";
# Commandline parsing
my %EXTRA;
my $WHAT = shift @ARGV // "";
@ARGV = parse_extra(@ARGV);
my $RET = 0;
sub split_val {
return split_val_win32(@_) if ($^O eq 'MSWin32');
my ($val) = @_;
my (@ret, @frag);
# Skip leading whitespace
$val =~ m{\A[ \t]*}ogc;
# Unix shell-compatible split
#
# Handles backslash escapes outside quotes and
# in double-quoted strings. Parameter and
# command-substitution is silently ignored.
# Bare newlines outside quotes and (trailing) backslashes are disallowed.
while (1) {
last if (pos($val) == length($val));
# The first char is never a SPACE or TAB. Possible matches are:
# 1. Ordinary string fragment
# 2. Single-quoted string
# 3. Double-quoted string
# 4. Backslash escape
# 5. Bare backlash or newline (rejected)
#
if ($val =~ m{\G([^'" \t\n\\]+)}ogc) {
# Ordinary string
push @frag, $1;
} elsif ($val =~ m{\G'([^']*)'}ogc) {
# Single-quoted string
push @frag, $1;
} elsif ($val =~ m{\G"}ogc) {
# Double-quoted string
push @frag, "";
while (1) {
last if ($val =~ m{\G"}ogc);
if ($val =~ m{\G([^"\\]+)}ogcs) {
# literals
push @frag, $1;
} elsif ($val =~ m{\G.(["\`\$\\])}ogc) {
# backslash-escaped special
push @frag, $1;
} elsif ($val =~ m{\G.(.)}ogcs) {
# backslashed non-special
push @frag, "\\$1" unless $1 eq "\n";
} else {
die sprintf("Malformed quoted string: %s\n", $val);
}
}
} elsif ($val =~ m{\G\\(.)}ogc) {
# Backslash is unconditional escape outside quoted strings
push @frag, $1 unless $1 eq "\n";
} else {
die sprintf("Bare backslash or newline in: '%s'\n", $val);
}
# Done if at SPACE, TAB or end, otherwise continue current fragment
#
next unless ($val =~ m{\G(?:[ \t]+|\z)}ogcs);
push @ret, join("", splice(@frag)) if (@frag > 0);
}
# Handle final fragment
push @ret, join("", splice(@frag)) if (@frag > 0);
return @ret;
}
sub split_val_win32 {
my ($val) = @_;
my (@ret, @frag);
# Skip leading whitespace
$val =~ m{\A[ \t]*}ogc;
# Windows-compatible split
# See: "Parsing C++ command-line arguments" in:
# https://learn.microsoft.com/en-us/cpp/cpp/main-function-command-line-args?view=msvc-170
#
# Backslashes are special only when followed by a double-quote
# Pairs of double-quotes make a single double-quote.
# Closing double-quotes may be omitted.
while (1) {
last if (pos($val) == length($val));
# The first char is never a SPACE or TAB.
# 1. Ordinary string fragment
# 2. Double-quoted string
# 3. Backslashes preceding a double-quote
# 4. Literal backslashes
# 5. Bare newline (rejected)
#
if ($val =~ m{\G([^" \t\n\\]+)}ogc) {
# Ordinary string
push @frag, $1;
} elsif ($val =~ m{\G"}ogc) {
# Double-quoted string
push @frag, "";
while (1) {
if ($val =~ m{\G("+)}ogc) {
# Two double-quotes make one literal double-quote
my $l = length($1);
push @frag, q{"} x int($l/2) if ($l > 1);
next if ($l % 2 == 0);
last;
}
if ($val =~ m{\G([^"\\]+)}ogc) {
push @frag, $1;
} elsif ($val =~ m{\G((?>[\\]+))(?=")}ogc) {
# Backslashes before a double-quote are escapes
my $l = length($1);
push @frag, q{\\} x int($l / 2);
if ($l % 2 == 1) {
++pos($val);
push @frag, q{"};
}
} elsif ($val =~ m{\G((?:(?>[\\]+)[^"\\]+)+)}ogc) {
# Backslashes not before a double-quote are not special
push @frag, $1;
} else {
# Tolerate missing closing double-quote
last;
}
}
} elsif ($val =~ m{\G((?>[\\]+))(?=")}ogc) {
my $l = length($1);
push @frag, q{\\} x int($l / 2);
if ($l % 2 == 1) {
++pos($val);
push @frag, q{"};
}
} elsif ($val =~ m{\G([\\]+)}ogc) {
# Backslashes not before a double-quote are not special
push @frag, $1;
} else {
die sprintf("Bare newline in: '%s'\n", $val);
}
# Done if at SPACE, TAB or end, otherwise continue current fragment
#
next unless ($val =~ m{\G(?:[ \t]+|\z)}ogcs);
push @ret, join("", splice(@frag)) if (@frag > 0);
}
# Handle final fragment
push @ret, join("", splice(@frag)) if (@frag);
return @ret;
}
# Split out "-extra-CMD value", and return new |@ARGV|. Fill in
# |EXTRA{CMD}| with list of values.
sub parse_extra
{
my @args;
foreach ( @OPENSSL_CMDS ) {
$EXTRA{$_} = [];
}
while (@_) {
my $arg = shift(@_);
if ( $arg !~ m{^-extra-(\w+)$} ) {
push @args, split_val($arg);
next;
}
$arg = $1;
die "Unknown \"-extra-${arg}\" option, exiting\n"
unless grep { $arg eq $_ } @OPENSSL_CMDS;
die "Missing \"-extra-${arg}\" option value, exiting\n"
unless (@_ > 0);
push @{$EXTRA{$arg}}, split_val(shift(@_));
}
return @args;
}
# See if reason for a CRL entry is valid; exit if not.
sub crl_reason_ok
{
my $r = shift;
if ($r eq 'unspecified' || $r eq 'keyCompromise'
|| $r eq 'CACompromise' || $r eq 'affiliationChanged'
|| $r eq 'superseded' || $r eq 'cessationOfOperation'
|| $r eq 'certificateHold' || $r eq 'removeFromCRL') {
return 1;
}
print STDERR "Invalid CRL reason; must be one of:\n";
print STDERR " unspecified, keyCompromise, CACompromise,\n";
print STDERR " affiliationChanged, superseded, cessationOfOperation\n";
print STDERR " certificateHold, removeFromCRL";
exit 1;
}
# Copy a PEM-format file; return like exit status (zero means ok)
sub copy_pemfile
{
my ($infile, $outfile, $bound) = @_;
my $found = 0;
open IN, $infile || die "Cannot open $infile, $!";
open OUT, ">$outfile" || die "Cannot write to $outfile, $!";
while (<IN>) {
$found = 1 if /^-----BEGIN.*$bound/;
print OUT $_ if $found;
$found = 2, last if /^-----END.*$bound/;
}
close IN;
close OUT;
return $found == 2 ? 0 : 1;
}
# Wrapper around system; useful for debugging. Returns just the exit status
sub run
{
my ($cmd, @args) = @_;
print "====\n$cmd @args\n" if $verbose;
my $status = system {$cmd} $cmd, @args;
print "==> $status\n====\n" if $verbose;
return $status >> 8;
}
if ( $WHAT =~ /^(-\?|-h|-help)$/ ) {
print STDERR <<EOF;
Usage:
CA.pl -newcert | -newreq | -newreq-nodes | -xsign | -sign | -signCA | -signcert | -crl | -newca [-extra-cmd parameter]
CA.pl -pkcs12 [certname]
CA.pl -verify certfile ...
CA.pl -revoke certfile [reason]
EOF
exit 0;
}
if ($WHAT eq '-newcert' ) {
# create a certificate
$RET = run(@REQ, qw(-new -x509 -keyout), $NEWKEY, "-out", $NEWCERT, @DAYS, @{$EXTRA{req}});
print "Cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT eq '-precert' ) {
# create a pre-certificate
$RET = run(@REQ, qw(-x509 -precert -keyout), $NEWKEY, "-out", $NEWCERT, @DAYS, @{$EXTRA{req}});
print "Pre-cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT =~ /^\-newreq(\-nodes)?$/ ) {
# create a certificate request
$RET = run(@REQ, "-new", (defined $1 ? ($1,) : ()), "-keyout", $NEWKEY, "-out", $NEWREQ, @{$EXTRA{req}});
print "Request is in $NEWREQ, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT eq '-newca' ) {
# create the directory hierarchy
my @dirs = ( "${CATOP}", "${CATOP}/certs", "${CATOP}/crl",
"${CATOP}/newcerts", "${CATOP}/private" );
die "${CATOP}/index.txt exists.\nRemove old sub-tree to proceed,"
if -f "${CATOP}/index.txt";
die "${CATOP}/serial exists.\nRemove old sub-tree to proceed,"
if -f "${CATOP}/serial";
foreach my $d ( @dirs ) {
if ( -d $d ) {
warn "Directory $d exists" if -d $d;
} else {
mkdir $d or die "Can't mkdir $d, $!";
}
}
open OUT, ">${CATOP}/index.txt";
close OUT;
open OUT, ">${CATOP}/crlnumber";
print OUT "01\n";
close OUT;
# ask user for existing CA certificate
print "CA certificate filename (or enter to create)\n";
my $FILE;
$FILE = "" unless defined($FILE = <STDIN>);
$FILE =~ s{\R$}{};
if ($FILE ne "") {
copy_pemfile($FILE,"${CATOP}/private/$CAKEY", "PRIVATE");
copy_pemfile($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
} else {
print "Making CA certificate ...\n";
$RET = run(@REQ, qw(-new -keyout), "${CATOP}/private/$CAKEY",
"-out", "${CATOP}/$CAREQ", @{$EXTRA{req}});
$RET = run(@CA, qw(-create_serial -out), "${CATOP}/$CACERT", @CADAYS,
qw(-batch -keyfile), "${CATOP}/private/$CAKEY", "-selfsign",
@EXTENSIONS, "-infiles", "${CATOP}/$CAREQ", @{$EXTRA{ca}})
if $RET == 0;
print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0;
}
} elsif ($WHAT eq '-pkcs12' ) {
my $cname = $ARGV[0];
$cname = "My Certificate" unless defined $cname;
$RET = run(@PKCS12, "-in", $NEWCERT, "-inkey", $NEWKEY,
"-certfile", "${CATOP}/$CACERT", "-out", $NEWP12,
qw(-export -name), $cname, @{$EXTRA{pkcs12}});
print "PKCS#12 file is in $NEWP12\n" if $RET == 0;
} elsif ($WHAT eq '-xsign' ) {
$RET = run(@CA, @POLICY, "-infiles", $NEWREQ, @{$EXTRA{ca}});
} elsif ($WHAT eq '-sign' ) {
$RET = run(@CA, @POLICY, "-out", $NEWCERT,
"-infiles", $NEWREQ, @{$EXTRA{ca}});
print "Signed certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-signCA' ) {
$RET = run(@CA, @POLICY, "-out", $NEWCERT, @EXTENSIONS,
"-infiles", $NEWREQ, @{$EXTRA{ca}});
print "Signed CA certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-signcert' ) {
$RET = run(@X509, qw(-x509toreq -in), $NEWREQ, "-signkey", $NEWREQ,
qw(-out tmp.pem), @{$EXTRA{x509}});
$RET = run(@CA, @POLICY, "-out", $NEWCERT,
qw(-infiles tmp.pem), @{$EXTRA{ca}}) if $RET == 0;
print "Signed certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-verify' ) {
my @files = @ARGV ? @ARGV : ( $NEWCERT );
foreach my $file (@files) {
my $status = run(@VERIFY, "-CAfile", "${CATOP}/$CACERT", $file, @{$EXTRA{verify}});
$RET = $status if $status != 0;
}
} elsif ($WHAT eq '-crl' ) {
$RET = run(@CA, qw(-gencrl -out), "${CATOP}/crl/$CACRL", @{$EXTRA{ca}});
print "Generated CRL is in ${CATOP}/crl/$CACRL\n" if $RET == 0;
} elsif ($WHAT eq '-revoke' ) {
my $cname = $ARGV[0];
if (!defined $cname) {
print "Certificate filename is required; reason optional.\n";
exit 1;
}
my @reason;
@reason = ("-crl_reason", $ARGV[1])
if defined $ARGV[1] && crl_reason_ok($ARGV[1]);
$RET = run(@CA, "-revoke", $cname, @reason, @{$EXTRA{ca}});
} else {
print STDERR "Unknown arg \"$WHAT\"\n";
print STDERR "Use -help for help.\n";
exit 1;
}
exit $RET;
Loaded 100 of 3294 files, more files were not shown because too many files have changed in this diff. Show more