Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ env:
# The exact toolchain used for tests and releases. go.mod declares a
# minimum - this is the pin. Raising it can change generated bytes, so the
# byte stability guard has to be green before it moves.
GO_VERSION: "1.27.0"
GO_VERSION: "1.27.2"

jobs:
test:
Expand Down Expand Up @@ -781,7 +781,7 @@ jobs:
# v1.8.0 since 2026-09-16, run on the tree before the pin moved: the same
# verdict as v1.7.0, exit 0 under Go 1.27 - the two pins before this one
# had stopped working with the compiler without anybody noticing.
run: go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 -tags "$(cat .github/build-tags)" ./...
run: go run golang.org/x/vuln/cmd/govulncheck@v1.9.0 -tags "$(cat .github/build-tags)" ./...

staticcheck:
name: staticcheck
Expand Down Expand Up @@ -826,7 +826,7 @@ jobs:
# both of them the word "Pillow" at the start of an error string, which
# is the name of the library that refused the image rather than a
# sentence. Zero findings with the config in place.
run: go run honnef.co/go/tools/cmd/staticcheck@v0.8.1 -tags "$(cat .github/build-tags)" ./...
run: go run honnef.co/go/tools/cmd/staticcheck@v0.8.2 -tags "$(cat .github/build-tags)" ./...

lint:
name: linters
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dev-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ concurrency:
cancel-in-progress: true

env:
GO_VERSION: "1.27.0"
GO_VERSION: "1.27.2"
# Fourteen days rather than the default ninety. These are throwaway builds
# handed to one person, and an unsigned binary should not sit for a quarter of
# a year behind a link somebody can pass on as if it were official.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ concurrency:
env:
# The same pin CI carries. A release built on a different toolchain than the
# one the byte stability guards ran under is a release nobody measured.
GO_VERSION: "1.27.0"
GO_VERSION: "1.27.2"

jobs:
check:
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ because it turns other people's test suites red.
against RFC 5322, which none of the three does. The smallest message at
the default settings is 289 B. mailparser refuses a message of more than
1000 MIME entities, which 999 attached files and the text reach.
- **Mail: pictures in the text, messages inside messages, many recipients,
base64 text and two more character sets.** `inline`, `inline_format` and
`inline_size` give the text pictures of any picture format. Beside an HTML
each one has a Content-ID and the HTML shows it through `cid:`, and beside
a plain text they follow it as pictures to show inline. Readers count them
differently: mailparser lists every picture among the attachments, Python's
email package lists them when the HTML is alone, and MimeKit never does.
`attachment_format=eml` attaches a message as it is, the way mail is
forwarded, and `message_depth` puts up to 2000 messages inside each other -
Python 3.14's email package runs out of recursion at around 490, and MimeKit
stops taking them apart past 513 without a word. `recipients` puts up to
100 000 addresses in To, each on a line of its own, past the 1 MiB of header
mailparser refuses. `charset` writes the text in `iso-8859-2` or
`windows-1250`, which write three Polish letters as different bytes, and
MimeKit with no code page provider reads both as Latin-1.
`text_encoding=base64` writes the whole text in base64.
`filename_style=none` writes no name at all.
- **GeoJSON: holes, features with no place, both types of id, and bbox.**
`holes` gives every polygon up to 100 000 holes of four points, each running
the other way round to its outline as RFC 7946 asks. Holes need 6 or more
Expand Down Expand Up @@ -272,6 +289,14 @@ because it turns other people's test suites red.
left, which you could not see, and Escape could stop a run there. On a tab
with nothing to run the three keys now do nothing.

### Security

- **Built with Go 1.27.2.** It fixes ten vulnerabilities in the Go standard
library, in `net/http`, `net/textproto`, `crypto/tls` and `html/template`,
that the desktop window could reach through its toolkit. The command line
tool does not use the network and was not affected. Building from source
now needs Go 1.27.2.

## [0.4.0] - 2026-09-25

### Changed
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ reached yet.

## Building it

Needs Go 1.27.0 or newer, and nothing else for the command line tool.
Needs Go 1.27.2 or newer, and nothing else for the command line tool.

```
git clone https://github.com/donislawdev/TestingFilesGenerator
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Linux has no equivalent to sign them with.
go install -tags noasm github.com/donislawdev/TestingFilesGenerator/cmd/tfg@latest
```

**From source.** Needs Go 1.27.0 or newer, and nothing else:
**From source.** Needs Go 1.27.2 or newer, and nothing else:

```
git clone https://github.com/donislawdev/TestingFilesGenerator
Expand Down Expand Up @@ -619,7 +619,7 @@ recipe. `tfg formats <id>` prints the allowed range or list for each:
| `txt`, `md`, `xml` | `encoding`, `bom` |
| `json` | `formatting` |
| `geojson` | `geometry`, `formatting`, `precision`, `altitude`, `vertices`, `holes`, `winding`, `antimeridian`, `unlocated`, `ids`, `bbox` |
| `eml` | `body`, `text_encoding`, `headers`, `line_endings`, `attachments`, `attachment_format`, `attachment_size`, `filename_style` |
| `eml` | `body`, `text_encoding`, `charset`, `headers`, `recipients`, `line_endings`, `attachments`, `attachment_format`, `attachment_size`, `filename_style`, `message_depth`, `inline`, `inline_format`, `inline_size` |
| `svg` | `width`, `height` |
| `html` | `structure` |
| `yaml`, `toml` | none in this build - the document is a fixed shape, and a size is the only thing to ask for |
Expand Down
10 changes: 9 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module github.com/donislawdev/TestingFilesGenerator
// which version it is. Kept honest by TestTheBuildFloorIsThePinnedToolchainAndTheReadmeSaysSo,
// which also holds the sentence in README.md against this number. See
// docs/STACK.md.
go 1.27.0
go 1.27.2

// How the line above got to the number it carries. There used to be a separate
// "toolchain" directive here saying which compiler produces our binaries, and
Expand Down Expand Up @@ -67,6 +67,14 @@ go 1.27.0
// closes a level zero stream went from five bytes to two. It measures the
// framing now, so the next release moves the bytes again but does not stop the
// format from being written.
//
// Raised to 1.27.2 on 2026-10-13 because govulncheck reported ten standard
// library vulnerabilities reachable from the window binary under 1.27.0, in
// net/http, net/textproto, crypto/tls and html/template, all fixed in 1.27.2.
// The command line binary links none of those packages. The byte stability
// guards were run under 1.27.2 the same day - all 104 golden values and every
// pinned standard library path - and none shifted, so D11 holds and no major
// version is owed.

require (
fyne.io/fyne/v2 v2.8.1
Expand Down
22 changes: 13 additions & 9 deletions internal/format/archive/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,19 @@ const DefaultSizeText = defaultSizeText

// Door is how a container names its contents, for GroupsThrough.
//
// The rules are one set for every container - both doors at once refused, the
// container never inside itself, one ceiling on both - and what differs is the
// words: which keys, how many files when nothing says, and the noun in the
// sentence that asks for fewer.
// The rules are one set for every container - both doors at once refused, one
// ceiling on both - and what differs is the words: which keys, how many files
// when nothing says, and the noun in the sentence that asks for fewer.
type Door struct {
Members format.Members
DefaultCount int
// Fewer is the remedy when more files are asked for than MaxMembers.
Fewer core.Said
// Nests says the container may hold a file of its own format. An archive
// inside an archive of the same kind is refused, and a message carries a
// message as message/rfc822, which is how mail is forwarded (RFC 2046
// section 5.2.1, docs/EML-2-2026-10-13.md section 8).
Nests bool
}

// archiveDoor is the door both archives share.
Expand All @@ -300,7 +304,7 @@ func GroupsThrough(id string, r format.Request, door Door) ([]format.Content, er
// which is a legitimate thing to ask for, and it is a different statement
// from saying nothing at all.
if r.Contains != nil {
return fromContains(id, r, stated, door.Fewer)
return fromContains(id, r, stated, door)
}

if r.SizeFromContents {
Expand All @@ -324,7 +328,7 @@ func GroupsThrough(id string, r format.Request, door Door) ([]format.Content, er
if v, ok := r.Properties[keys.Format]; ok && v != "" {
entryFmt = v
}
if entryFmt == id {
if entryFmt == id && !door.Nests {
return nil, &format.NestingUnsupportedError{Format: id}
}
return []format.Content{{Format: entryFmt, Count: entries, Bytes: entrySize}}, nil
Expand All @@ -335,13 +339,13 @@ func GroupsThrough(id string, r format.Request, door Door) ([]format.Content, er
// Split out of Groups so the branching stays under the ceiling the shape gates
// hold, and because it is one subject: everything here is about a contains list
// and nothing about it reads a property.
func fromContains(id string, r format.Request, stated []string, fewer core.Said) ([]format.Content, error) {
func fromContains(id string, r format.Request, stated []string, door Door) ([]format.Content, error) {
if len(stated) > 0 {
return nil, &format.ContentsConflictError{Format: id, Keys: stated}
}
asked := 0
for _, g := range r.Contains {
if g.Format == id {
if g.Format == id && !door.Nests {
return nil, &format.NestingUnsupportedError{Format: id}
}
asked += g.Count
Expand All @@ -357,7 +361,7 @@ func fromContains(id string, r format.Request, stated []string, fewer core.Said)
// to the exit code: a plain error here would have landed on 1 while
// the same request through entries lands on 4, which is the same
// disagreement one level further down.
return nil, tooMany(id, "contains", asked, fewer)
return nil, tooMany(id, "contains", asked, door.Fewer)
}
return r.Contains, nil
}
Expand Down
Loading
Loading