mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-30 20:35:03 +01:00
Compare commits
178
Commits
stable/14
...
releng/14.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd31ee522f | ||
|
|
091c8ad19f | ||
|
|
7410d52364 | ||
|
|
96a1404d5b | ||
|
|
9686673eed | ||
|
|
e303b980d0 | ||
|
|
1258151af5 | ||
|
|
2540afe9af | ||
|
|
5dd0f22460 | ||
|
|
00ec12d48c | ||
|
|
1fe825bba4 | ||
|
|
409554009e | ||
|
|
ea6ecd1e37 | ||
|
|
7944824ae3 | ||
|
|
11f0c61eec | ||
|
|
1c821dc49b | ||
|
|
e1d55e72b3 | ||
|
|
a6ccb9d690 | ||
|
|
24aef4c96a | ||
|
|
8b3713b741 | ||
|
|
49084ed8ec | ||
|
|
9d0644e7a4 | ||
|
|
1c1575015c | ||
|
|
8e6bc7b3e9 | ||
|
|
790bfee896 | ||
|
|
4c3de56d28 | ||
|
|
ba6c8cdf98 | ||
|
|
11a5387a12 | ||
|
|
ebea5df751 | ||
|
|
9bb6f92b5d | ||
|
|
b38d9c709d | ||
|
|
53c5c19353 | ||
|
|
840fd9dc7d | ||
|
|
d7883b84b1 | ||
|
|
275b424d3c | ||
|
|
8544e4ce67 | ||
|
|
3e5e24f16e | ||
|
|
0cd984b41c | ||
|
|
8668302cb7 | ||
|
|
97e1e603bd | ||
|
|
357aa8af53 | ||
|
|
c905b34120 | ||
|
|
6fb0f13275 | ||
|
|
3de2d29b08 | ||
|
|
d46ec21610 | ||
|
|
b5eaa00cdb | ||
|
|
b20841b471 | ||
|
|
01b53d5d1e | ||
|
|
4ae10ff966 | ||
|
|
7a227adc1a | ||
|
|
72947d00fc | ||
|
|
3827644480 | ||
|
|
b819674449 | ||
|
|
ce422ff3fc | ||
|
|
d760b7f9b0 | ||
|
|
07a27f8c8e | ||
|
|
f145e3c02b | ||
|
|
99d936f985 | ||
|
|
5f83a1c159 | ||
|
|
d68c2e77d7 | ||
|
|
0848cdea83 | ||
|
|
9c06b54ab6 | ||
|
|
1c49551def | ||
|
|
800acf75eb | ||
|
|
9a6bccc57c | ||
|
|
0a7dd3d960 | ||
|
|
66efc521e0 | ||
|
|
62f64d81b5 | ||
|
|
8fbbc185a3 | ||
|
|
4c9e89c85d | ||
|
|
f902821db0 | ||
|
|
3d95ec8758 | ||
|
|
410ab2bff3 | ||
|
|
1929d9e173 | ||
|
|
799e830134 | ||
|
|
857abc1294 | ||
|
|
547fc2a98a | ||
|
|
889e306ded | ||
|
|
3fe0922820 | ||
|
|
a7062a6de0 | ||
|
|
eab757f954 | ||
|
|
0e8cc8d8a4 | ||
|
|
b9128fe195 | ||
|
|
d43259dd66 | ||
|
|
31f6086db8 | ||
|
|
1bfe60bae8 | ||
|
|
069cb89611 | ||
|
|
f977328c72 | ||
|
|
dd50cc216e | ||
|
|
70e6a19f3d | ||
|
|
ae34dd1a39 | ||
|
|
c21d23f0f8 | ||
|
|
6a299460f1 | ||
|
|
8d8694c224 | ||
|
|
79d6615af7 | ||
|
|
34da5845b8 | ||
|
|
081a9e9330 | ||
|
|
49be56ed6f | ||
|
|
dfcb69cdb0 | ||
|
|
d7784de043 | ||
|
|
4f0992ce23 | ||
|
|
a5cb4863d6 | ||
|
|
adaed0700d | ||
|
|
64c0919d2c | ||
|
|
0cbe512c7a | ||
|
|
d60456d859 | ||
|
|
73b801e3b5 | ||
|
|
943aa64ba9 | ||
|
|
b007852059 | ||
|
|
677aeab69b | ||
|
|
6dc9b78eb7 | ||
|
|
5787df30dc | ||
|
|
af294329c5 | ||
|
|
df8d2f9450 | ||
|
|
1abe7ead45 | ||
|
|
a5812c7763 | ||
|
|
b6865bca4b | ||
|
|
a429dbb47f | ||
|
|
984b570b49 | ||
|
|
4708ee4543 | ||
|
|
7ea03a4238 | ||
|
|
44dd8b5839 | ||
|
|
a456f852d1 | ||
|
|
041aa28386 | ||
|
|
12143e3e3a | ||
|
|
ca76ec7c4e | ||
|
|
3cf73e195a | ||
|
|
49684d7d93 | ||
|
|
20cff160e1 | ||
|
|
6ecd231b9e | ||
|
|
7465d0b094 | ||
|
|
0c49d9fafc | ||
|
|
7c81bf5191 | ||
|
|
02138275ef | ||
|
|
7805899ed7 | ||
|
|
65338ff41f | ||
|
|
28b5b653a5 | ||
|
|
0d08a243f2 | ||
|
|
8755b5f3a5 | ||
|
|
7f1e9f9451 | ||
|
|
f16fc39527 | ||
|
|
6316ab68d3 | ||
|
|
71ed9ae5e6 | ||
|
|
0235e9e569 | ||
|
|
39dd0d8a0d | ||
|
|
37fa2e7695 | ||
|
|
d2136eeb14 | ||
|
|
f2dc20d2d2 | ||
|
|
53e0a1d1ff | ||
|
|
e8918d58a2 | ||
|
|
8b34da3d3e | ||
|
|
fce4758b71 | ||
|
|
969e2b4068 | ||
|
|
2f47676012 | ||
|
|
572d4096d3 | ||
|
|
1e23939306 | ||
|
|
133eae6afd | ||
|
|
be256934d6 | ||
|
|
7d0345d32b | ||
|
|
0671ffe268 | ||
|
|
f8e20e75a6 | ||
|
|
36ebcb4f82 | ||
|
|
6444869020 | ||
|
|
4690a369ff | ||
|
|
3c10ed2ba3 | ||
|
|
7cf7c711d9 | ||
|
|
b4139147bb | ||
|
|
6761e55537 | ||
|
|
2434f3b279 | ||
|
|
238bf5ebf6 | ||
|
|
61dbfaa13c | ||
|
|
11b616d9de | ||
|
|
5d7d22588d | ||
|
|
df3c9a8a5f | ||
|
|
7fa4ccb8e4 | ||
|
|
e261ea9105 | ||
|
|
8039d22f6a | ||
|
|
9bbe9bfc66 |
No files matched your search
+1
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -117,7 +117,6 @@ fmtydhms(char *b, size_t l, time_t t)
|
||||
|
||||
y = t;
|
||||
|
||||
z = 0;
|
||||
o = 0;
|
||||
#define APPEND(a) \
|
||||
if (a) { \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
@@ -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,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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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 -
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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:
|
||||
# «Поясное время и новые границы часовых поясов» / сост. П.Н. Долгов,
|
||||
# отв. ред. Г.Д. Бурдун - М: Комитет стандартов, мер и измерительных
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 @@
|
||||
2025c
|
||||
2026e
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Vendored
+7
-1
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Acknowlegements
|
||||
===============
|
||||
Acknowledgements
|
||||
================
|
||||
|
||||
Please see our [Thanks!][] page for the current acknowledgements.
|
||||
|
||||
|
||||
+584
-197
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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`
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)]:
|
||||
|
||||
@@ -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
|
||||
Executable
+383
@@ -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
Reference in new issue
Block a user