Skip to content

Releases: tecnickcom/nurago

v1.147.1

Choose a tag to compare

@github-actions github-actions released this 11 Jul 13:13
d947924

test: cover empty select branches reported as uncovered by Coveralls

Add tests exercising the two branches:

  • httpserver: the default branch of the non-blocking serve failure publish, taken when the serveErr buffer is already full
  • valkey: the subscription context Done branch in the delivery callback, taken when Close tears down the subscription while a message is blocked waiting for a consumer

Full Changelog: v1.147.0...v1.147.1

v1.147.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 10:02
bf9a259

Remove deprecated APIs

BREAKING CHANGE: the deprecated encode.JsonEncoder function, typeutil.Pointer function, and the NameErrorLevel constants in metrics/opentel and metrics/prometheus have been removed; use encode.JSONEncoder, new(), and NameLogLevel instead.

Full Changelog: v1.146.0...v1.147.0

v1.146.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 09:23
2071f22

feat!: rename module from gogen to nurago

Complete the rename started with the GitHub repository rename and the v1.145.0 deprecation release: the module path is now github.com/tecnickcom/nurago.

BREAKING CHANGE: importers must replace github.com/tecnickcom/gogen with github.com/tecnickcom/nurago in their import paths. The old module path remains frozen at v1.145.0 with a deprecation notice.

Full Changelog: v1.145.0...v1.146.0

v1.145.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 08:32
e6bfd09

gogen has been renamed to nurago — final release under this module path

This is the last release of github.com/tecnickcom/gogen. The project continues, unchanged and actively maintained, as github.com/tecnickcom/nurago: same library, same packages, same maintainer, new name.

This release contains no functional changes. It only adds the Go module deprecation notice to go.mod and a rename banner to the README, so that go get, go list -m -u, and pkg.go.dev inform users of the new import path.

To migrate, update your imports and dependencies:

go get github.com/tecnickcom/nurago@latest
find . -name '*.go' -exec sed -i 's|github.com/tecnickcom/gogen|github.com/tecnickcom/nurago|g' {} +
go mod tidy

Nothing breaks if you stay: every published gogen version remains permanently available via the Go module proxy. However, all future development, fixes, and releases happen only under nurago.

Why "nurago"? From nuraghe + Go: the Bronze Age Sardinian stone towers, built from dry-laid stone without mortar, thousands of which still stand after 3,500 years — modular, stone-solid foundations with no lock-in, which is exactly what this library aims to be.

Full Changelog: v1.144.0...v1.145.0

v1.144.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 12:50
5f82870

✨ Features

pkg/passwordhash: PHC string format support

Optional support for the cross-language PHC string format ($argon2id$v=19$m=...,t=...,p=...$salt$key) alongside the default self-describing base64-JSON format. This enables password-hash interoperability with other ecosystems — PHP password_hash, Python argon2-cffi/passlib, and the Argon2 reference CLI — without bulk re-hashing.

  • WithFormat(f, accept...) selects the serialization emitted by PasswordHash and the set of formats PasswordNeedsRehash treats as current. The default remains base64 JSON, so existing deployments are unaffected.
  • Auto-detected verification: PasswordVerify and PasswordNeedsRehash detect each stored value's format from its leading $, so both formats can coexist in one store, switching formats never invalidates a credential, and externally minted argon2id PHC hashes verify with no configuration change.
  • Format-aware rehash migration: PasswordNeedsRehash flags hashes stored in a non-accepted format as needing a rehash even when their Argon2 parameters are current, so a store converges to the configured format through the ordinary rehash-on-login flow. Listing both formats via accept keeps a deliberately mixed store; verification is never restricted by this option.
  • Safe by default: unknown emit values normalize to FormatJSON and unknown accept values are ignored (never aliased), so misconfiguration can neither select an unsupported serialization nor silently widen the accepted set. Pepper-encrypted methods are unaffected.
  • Strict, secure PHC parsing: deserialized parameters flow through the same bounds validation as the JSON format; only argon2id at version 19 with cost parameters in m,t,p order is accepted; optional keyid/data attributes and padded base64 are rejected; newline characters and non-canonical base64 trailing bits are rejected so byte-distinct strings can never decode to the same salt/key; and $/comma splits are capped so adversarial inputs cannot allocate large slices before rejection.

Tests pin the wire format with a frozen PHC reference, cross-implementation interop against a vector minted by PHP's password_hash(PASSWORD_ARGON2ID), cross-format verifiability, convergence/mixed-store semantics, and 15 malformed-PHC rejection cases. Fuzz seeds cover the PHC decode path, plus a new benchmark for PHC verification against the JSON baseline. Coverage remains 100% with a clean strict lint run.

🔧 Maintenance

  • Updated dependencies

Full Changelog: v1.143.0...v1.144.0

v1.143.0

Choose a tag to compare

@github-actions github-actions released this 09 Jul 15:39
7f79240

This release reworks pkg/filter for a ~4x evaluation speedup and secure-by-default input limits, with a smaller public API. It also refactors the example service startup wiring. It contains breaking changes in pkg/filter.

⚠️ Breaking changes (pkg/filter)

  • The package-level ParseJSON function, the Evaluator interface, and the Rule.Evaluate method are no longer exported. Rule is now a pure data struct, and untrusted input must be decoded via the size-limited entry points Processor.ParseJSON or Processor.ParseURLQuery.
  • New secure-by-default limits reject previously-accepted oversized inputs unless raised via the matching options: rule string/regexp values are capped at 4096 bytes (WithMaxValueLength), JSON payloads at 64 KiB (WithMaxFilterBytes), and field-selector nesting at depth 32 (WithMaxFieldDepth). The number of OR groups in a rule set is also capped.
  • A nil interface slice element combined with a field selector is now filtered out (non-match), consistent with nil-pointer handling, instead of returning an error.

Performance

  • Rules are evaluated on a reflect.Value instead of boxing every element and field into an any, and each rule's field path is resolved once per Apply for concrete slices instead of a per-element cache lookup. The Equal_10000 benchmark drops from ~1.85 ms to ~0.44 ms (~4x), and per-element allocations drop from ~2 per element to a small constant.

Security

  • All client-attributable errors are wrapped in the new ErrInvalidFilter sentinel, so handlers can reject bad filters generically (e.g. HTTP 400) without surfacing client input or internal type names.
  • Added a package Security section documenting RE2's linear-time matching (no ReDoS) and the caller's authorization responsibility, plus a FuzzFilterApply panic-safety fuzz harness.

Examples

  • examples/service: decomposed the startup wiring into focused helpers (newIpifyClient, bindServiceHandlers, newDatabases, newLogConfig), removing the gocognit/funlen/nestif/prealloc lint suppressions while keeping a linear, copy-paste-friendly startup blueprint.
  • The configured service logger is now threaded into healthcheck.NewHandler via WithLogger, so health-check warnings and recovered panics are structured and release-correlated like every other component.
  • Shared outbound HTTP client options are built once and reused per client; the ipify client is documented as a diagnostic-only dependency deliberately not registered as a health check.
  • Aligned the shipped config default db.{main,read}.conn_max_open with SetDefaults and the JSON schema (50), and added a "service enabled, database disabled" bind test restoring 100% statement coverage.

All packages retain 100% test coverage and pass strict golangci-lint.

Full Changelog: v1.142.1...v1.143.0

v1.142.1

Choose a tag to compare

@github-actions github-actions released this 09 Jul 11:45
3b44d83

What's Changed

This release hardens the AWS packages (awsopt, awssecretcache, sqs, s3) around a single set of conventions: exported sentinel errors matchable with errors.Is, response/input guards that return errors instead of panicking, skipping AWS config load when a client is injected, and expanded docs with runnable examples.

⚠️ This release contains breaking changes in every package below. See the Breaking changes section before upgrading.

awsopt — partition-agnostic region extraction

  • Reworked WithRegionFromURL to extract the region as the right-most region-shaped host label instead of anchoring on .amazonaws.com, so standard, dual-stack (api.aws), China (amazonaws.com.cn), GovCloud, ISO (c2s.ic.gov, sc2s.sgov.gov), VPC interface endpoints, and future partitions all resolve with no code changes.
  • Endpoint URLs are now parsed with net/url (host only; scheme optional; userinfo, port, and path ignored; case-insensitive), replacing the endpoint-extraction regexp with a small region-shape check.
  • Candidate labels are validated against the AWS region shape, so a service name or the vpce label never becomes a bogus region.
  • Fixed VPC interface endpoint region resolution and scheme-less endpoints whose path/query contains ://.
  • Documented that Options must be built from a single goroutine, then shared read-only.

awssecretcache — sentinel errors and nil/empty-secret guards

  • Added exported sentinel errors ErrEmptySecret and ErrEmptySecretID (wrapped with %w).
  • Guarded against a nil GetSecretValueOutput so GetSecretData, GetSecretBinary, and GetSecretString return ErrEmptySecret instead of panicking.
  • Skipped the AWS config load when a client is injected via WithSecretsManagerClient.
  • Rejected an empty secret id up front with ErrEmptySecretID instead of a guaranteed-failing upstream call.
  • Documented %w wrapping (typed SDK errors stay matchable via errors.As; context/abort errors via errors.Is), edge behavior on New, and added a runnable Example.

sqs — sentinel errors, nil-response guards, client injection, URL-derived region

  • Added exported sentinel errors (ErrInvalidQueueURL, ErrMissingMessageGroupID, ErrUnexpectedMessageGroupID, ErrDedupIDNotAllowed, ErrInvalidDedupID, ErrNilEncodeFunc, ErrNilDecodeFunc, ErrInvalidWaitTime, ErrInvalidVisibilityTimeout, ErrQueueNotResponding).
  • Added WithSQSClient to inject a custom implementation, skipping AWS config load when set.
  • Derived the AWS region from the queue URL via awsopt.WithRegionFromURL when no explicit region is set (an explicit WithAWSOptions region still wins).
  • Validated the queue URL and FIFO message-group constraints before loading AWS config, so misconfiguration fails fast.
  • Guarded against nil ReceiveMessage/GetQueueAttributes output in Receive and HealthCheck.
  • Wrapped encode/decode errors with %w, documented concurrency safety, and added a runnable Example.

s3 — sentinel errors, nil-response guards, client injection, health check, object metadata

  • Added exported sentinel errors (ErrEmptyBucketName, ErrEmptyKey, ErrEmptyObjectBody, ErrBucketNotResponding).
  • Added WithS3Client to inject a custom implementation, skipping AWS config load when set.
  • Added HealthCheck, probing bucket reachability and access via HeadBucket (requires s3:ListBucket).
  • Exposed object metadata on Object (ContentType, ContentLength, ETag, LastModified, plus Bucket and Key).
  • Added ListObjects returning per-object metadata (ObjectInfo with Key, Size, LastModified, ETag); ListKeys is now a thin projection over it sharing a single pagination path.
  • Defaulted a nil Put reader to http.NoBody, validated bucket/key before calling AWS, and stopped pagination when the continuation token does not advance (prevents an infinite loop against non-conformant endpoints).
  • Guarded against nil GetObject/ListObjectsV2 output, documented concurrency safety, and added a runnable Example.

Maintenance

  • Updated dependencies and bumped version.

⚠️ Breaking changes

awsopt

  • When the URL carries no region and no defaultRegion is given, WithRegionFromURL now adds no region option and defers to the SDK's canonical resolution (AWS_REGION, then AWS_DEFAULT_REGION, then the shared config file, then IMDS) instead of substituting a hardcoded us-east-2 default.
  • Region resolution no longer requires an amazonaws.com host: any host carrying a region-shaped label yields that region, so the host is no longer verified to be AWS-owned.

awssecretcache

  • GetSecretBinary and GetSecretString now return ErrEmptySecret when the response holds no value, instead of an empty value with a nil error (an explicitly empty ""/[]byte is still returned as a real value).
  • GetSecretData, GetSecretBinary, and GetSecretString now return ErrEmptySecretID for an empty key instead of attempting an upstream lookup.

sqs

  • New now returns ErrUnexpectedMessageGroupID when a message group ID is supplied for a standard (non-FIFO) queue instead of silently ignoring it.
  • New now validates the queue URL and returns ErrInvalidQueueURL for an empty or malformed URL instead of failing only on first use.
  • The region is now derived from the queue URL and takes precedence over the AWS_REGION environment variable (an explicit WithAWSOptions region still wins).
  • Package errors are now exported sentinel values and several error message texts changed.

s3

  • The S3 interface gains a HeadBucket method; existing implementations (including test mocks) must provide it.
  • New now returns ErrEmptyBucketName for an empty bucket name instead of failing only on first use.
  • Get, Put, and Delete now return ErrEmptyKey for an empty key instead of issuing an AWS request.
  • Package errors are now exported sentinel values, and the wrapped list error text changed from "cannot list s3 keys" to "cannot list s3 objects".

Full Changelog: v1.141.0...v1.142.1

v1.141.0

Choose a tag to compare

@github-actions github-actions released this 08 Jul 21:58
7533682

v1.141.0

This release makes gogen fully pure-Go, removes the go.uber.org/multierr dependency, and applies a consistent hardening pass across the HTTP-client, messaging, and country-data packages: exported sentinel errors matchable with errors.Is, construction-time validation instead of deferred or panicking failures, bounded/secret-safe response handling, and client injection for dependency-free unit tests.

⚠️ This is a breaking release. Every package below marked with ! changes behavior, option names, or error types. See Breaking changes for migration notes.

Highlights

  • gogen is now 100% pure-Go. The only CGO dependency, pkg/kafkacgo (Confluent/librdkafka), has been removed — cross-compilation, scratch/distroless images, and CGO-free builds now work out of the box.
  • go.uber.org/multierr dependency dropped. kafka, validator, and errutil now use the standard library's errors.Join, so the module no longer depends on multierr.
  • Uniform error taxonomy. HTTP clients (devlake, jirasrv, slack, sleuth, ipify) and messaging clients (kafka, redis, valkey) now export sentinel errors wrapped with %w, so callers can distinguish configuration problems from response/runtime failures via errors.Is.
  • Fail fast at construction. Retry/option validation moved from the first request/send into New/NewProducer/NewConsumer.
  • Safer responses. Response bodies are drained and capped with io.LimitReader for connection reuse, non-2xx snippets (secret-redacted) are appended to errors, and nil-request/nil-body guards replace latent panics.

Breaking changes

  • pkg/kafkacgo removed. Migrate to github.com/tecnickcom/gogen/pkg/kafka (context-native, no CGO); note the option/error surface differs (segmentio/kafka-go rather than librdkafka).
  • kafka: NewProducer/NewConsumer validate at construction and return errors matching ErrInvalidOptions/ErrNilEncodeFunc/ErrNilDecodeFunc; NewProducer's urls parameter renamed to brokers; Receive/FetchMessage/ReceiveData return ErrConsumerClosed after Close (no longer wrap io.EOF).
  • redis: Get/GetData return ErrKeyNotFound (no longer matches redis.Nil); WithSubscrChannelsWithChannels, WithSubscrChannelOptionsWithChannelOptions; empty channel names and Addr/Network mismatches rejected at construction.
  • valkey: subscription lifetime is bound to Close rather than the New context (Close is now mandatory when channels are configured); Get/GetData return ErrKeyNotFound (no longer matches valkeygo.Nil/IsValkeyNil); empty channel names rejected.
  • ipify: a 200 with an empty body now returns ErrInvalidResponse, non-http/https URLs are rejected at construction, and the response body is capped at 64 bytes.
  • devlake / jirasrv / sleuth: New validates retry options (ErrInvalidRetryConfig) at construction; retries now honor a server-provided Retry-After (capped at 60s); error message texts changed.
  • slack: HealthCheck now fails during an active Apps/Integrations/APIs incident (previously it could never fail); default ping URL changed to https://slack-status.com; retry validation moved to construction.
  • countryphone: NumInfo.Geo changes from []*GeoInfo to []GeoInfo; removed the unused PrefixData alias; dropped non-ISO codes CT (+90) and QN (+374) so +90TR and +374AM only.
  • countrycode: internal length/character/parse errors now wrap the exported ErrInvalidCode/ErrNotFound.
  • validator: the aggregate error from ValidateStruct/ValidateStructCtx now renders with newline separators (errors.Join) instead of multierr's "; ". The error type, errors.Is/errors.As traversal, and one-*Error-per-failed-tag structure are unchanged; only the concatenated Error() string differs.

Changes by package

kafka

  • Sentinel errors ErrInvalidOptions, ErrNilEncodeFunc, ErrNilDecodeFunc, ErrConsumerClosed.
  • WithKafkaReader/WithKafkaWriter inject an existing kafka-go reader/writer (via new KReader/KWriter interfaces) for dependency-free tests.
  • Add Producer.HealthCheck and WithBrokerCheckFunc (custom per-broker probe).
  • Replace go.uber.org/multierr with stdlib errors.Join; probe every broker and join errors only when all fail; clone the caller's broker slice at construction.

redis

  • Sentinel errors incl. ErrKeyNotFound, ErrNoSubscription, ErrSubscriptionClosed, ErrInvalidChannelName.
  • Unix domain socket support; WithRedisClient injection; idempotent Close.
  • Extensive doc and test rework (key-not-found, double Close, concurrent Close, nil-message skipping, unix socket validation); coverage stays 100%.

valkey

  • Sentinel errors mirroring redis; deterministic clean-closure reporting via an atomic closed flag; idempotent Close via sync.Once.
  • Skip InitAddress validation when a client is injected via WithValkeyClient.

ipify

  • Export ErrInvalidOptions/ErrInvalidResponse; URL validation at construction; nil-body guard; add Client.HealthCheck.

devlake / jirasrv / sleuth

  • Sentinel errors, single prebuilt retrier (method-aware read/write retriers in jirasrv), Retry-After support, bounded response drains, nil-request guards, and secret-safe error snippets.

slack

  • Real status-incident health check against the live Slack status API v2.0.0, sentinel errors, WithRetryDelay, and secret-safe address validation.

countryphone

  • Value-slice GeoInfo, sentinel errors (ErrNoMatch, ErrInvalidNumberType, ErrInvalidAreaType), nil-entry and empty-prefix guards, hoisted lookup tables, benchmarks, and runnable examples.

countrycode

  • Exported ErrInvalidCode/ErrNotFound; fixed custom-data field population and region/sub-region resolution by code; fuzz tests, benchmarks, and typo fixes.

validator / errutil

  • Drop go.uber.org/multierr: validator builds its aggregate error via errors.Join; the per-failed-tag *Error structure, count, and order are unchanged.
  • Add errutil.Errors, a dependency-free helper that enumerates the individual errors held in an errors.Join aggregate.

Maintenance

  • Updated dependencies.

Full Changelog: v1.140.0...v1.141.0

v1.140.0

Choose a tag to compare

@github-actions github-actions released this 08 Jul 12:46
9646c97

v1.140.0

Major security-focused reworks of the jwt, passwordhash, and passwordpwned packages. All three ship breaking API changes — see the Breaking Changes section before upgrading.

jwt — self-contained HMAC engine, verifier-based API, and security hardening

  • Tokens are now signed and verified by a standard-library-only HMAC-SHA2 (HS256/HS384/HS512) implementation of the RFC 7515/7519 compact JWS, removing the github.com/golang-jwt/jwt/v5 build dependency (retained test-only for cross-validation). Restricting the surface to symmetric HMAC and verifying the signature before decoding claims makes alg=none and algorithm-confusion attacks structurally impossible.
  • Pin the accepted signing algorithm and require exp; validate nbf with optional clock-skew leeway; enforce iss and the full aud set when configured.
  • Bound how long a session can be kept alive by renewals via an auth_time claim preserved across renewals and a configurable maximum lifetime, so a stolen token cannot be renewed indefinitely.
  • Support HMAC key rotation through previous keys accepted for verification, validate minimum key length against the method hash size, and copy caller-supplied key material.
  • Cap the login request body (413 on overflow) and reject unknown or trailing JSON; return generic client messages while logging details server-side; distinguish invalid credentials (401) from credential-backend failures (500).
  • Emit RFC 6750 WWW-Authenticate challenges on 401 responses and accept case-insensitive, multi-space Bearer prefixes per RFC 7235.
  • New API: Authenticate, VerifyToken, IssueToken, Middleware with ClaimsFromContext, and options WithMaxBodyBytes, WithMaxSessionLifetime, WithClockSkewLeeway, WithPreviousKeys.
  • Fuzz tests for the login body and token parser, benchmarks for the issue and verify paths, and a runnable example; 100% statement coverage.

passwordhash — parameter envelope, rehash API, sentinel errors, and hardening

  • Any hash the package can mint it can also verify: cost options clamp to the same [floor, ceiling] range the verification path accepts, and hashing rejects out-of-envelope configurations.
  • Panics replaced with errors: invalid or zero-value Params now return ErrInvalidParams instead of panicking inside argon2.
  • Verification hardened against forged or corrupt blobs: encoded hashes larger than 16 KiB are rejected before decoding, deserialized parameters are validated against their bounds, and salt/key byte lengths are cross-checked against their declared sizes.
  • New PasswordNeedsRehash and EncryptPasswordNeedsRehash detect hashes minted with outdated parameters, enabling transparent re-hashing on the next successful login.
  • Default parallelism is a flat 4 lanes (RFC 9106 §4) instead of runtime.NumCPU(), so minted hashes are reproducible across heterogeneous hardware and a mixed fleet cannot enter a rehash loop; key and salt minimums for new hashes raised to 16 and 8 bytes.
  • Minimum-length policy is enforced only when hashing, not on verification, so raising the minimum no longer locks out existing users.
  • Sentinel-error taxonomy matchable with errors.Is: ErrPasswordTooShort, ErrPasswordTooLong, ErrInvalidParams, ErrInvalidHashData, ErrAlgoMismatch, ErrVersionMismatch, ErrInvalidPepperKey.
  • Derived keys and decrypted pepper material are wiped after comparison; fuzz, envelope round-trip, panic-safety, and boundary tests added; 100% coverage.

passwordpwned — breach-count API, hardened response validation, sentinel errors, and live health probe

  • New PwnedCount returns the raw breach count for NIST-style threshold policies ("reject only if seen more than N times"); IsPwnedPassword is now a thin count>0 wrapper over it.
  • Decoded responses are capped at 8 MiB (configurable via WithResponseSizeLimit) so a decompression bomb cannot exhaust memory, and are decoded according to their declared Content-Encoding (brotli, gzip, identity) instead of assuming brotli.
  • Fail loud on garbage 200s: the body must begin with a structurally valid <35-hex>:<count> range line, so a captive-portal page returns ErrMalformedResponse instead of silently reading as "not pwned"; hash-suffix matching is case-insensitive, so lowercase-hex mirrors no longer produce silent false negatives.
  • HealthCheck is now a live probe: a lightweight GET on a fixed range prefix bounded by a dedicated ping timeout (default 5 s, WithPingTimeout), never retried.
  • The HTTP retrier is built once in New — invalid retry settings fail at construction — and a server-provided Retry-After header is honored (capped at 60 s) on 429.
  • Sentinel-error taxonomy: ErrInvalidURL, ErrInvalidUserAgent, ErrMalformedResponse, ErrResponseTooLarge, ErrUnsupportedEncoding, ErrUnexpectedStatus.
  • Tests pin the k-anonymity contract (only the 5-character hash prefix ever leaves the process), plus fuzz targets over the response parser and body reader; 100% coverage.

Other

  • Fixed a flaky test timeout.
  • Updated dependencies (including golang.org/x/sync v0.22.0 and golang.org/x/sys v0.47.0).

Breaking Changes

  • jwt: New takes VerifyCredentialsFn func(username, password string) (bool, error) instead of UserHashFn — credential verification is fully delegated (pair it with pkg/passwordhash) and the package no longer performs bcrypt comparison itself. SigningMethod is now an HS256/HS384/HS512 enum, Claims carries native fields instead of embedding jwt.RegisteredClaims, and WithClaimSubject is removed (the sub claim is now the authenticated username).
  • passwordhash: default parallelism is a flat 4 instead of runtime.NumCPU(); WithKeyLen/WithSaltLen clamp to [16, 1024]/[8, 1024] and WithTime/WithMemory cap at 1024 passes/4 GiB (previously stored hashes remain verifiable unchanged). PasswordVerify and EncryptPasswordVerify no longer reject candidate passwords below the configured minimum length. Invalid Params configurations that previously panicked now return ErrInvalidParams.
  • passwordpwned: HealthCheck now performs a live request instead of always returning nil. New rejects previously accepted configurations: URLs with a query or fragment, an empty or control-character User-Agent, zero retry attempts, and non-positive retry delays. A 200 response whose body is not valid HIBP range data now returns ErrMalformedResponse instead of reporting the password as not pwned, and WithTimeout ignores non-positive values instead of disabling the client timeout.

Full Changelog: v1.139.0...v1.140.0

v1.139.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 22:54
f0e6429

v1.139.0

Broad hardening, performance, and API-ergonomics pass across the utility packages. Every touched package keeps 100% test coverage and a clean strict golangci-lint run, with new fuzz targets and benchmarks throughout.

✨ Features

  • redact: Rework the redaction engine into a generic, allocation-free single-pass scanner for logs, HTTP dumps, JSON, XML, and form data. Adds detection for extra sensitive HTTP headers, URL userinfo passwords, JWT/JWE tokens, vendor credential literals (GitHub, GitLab, Slack, Stripe, AWS, Google, OpenAI/Anthropic, and more), and PEM private-key blocks; broadens credit-card detection to 13–19 digit PANs with grouped formats and a conservative Maestro policy; and guarantees convergent redaction backed by a permanent fuzz target. Introduces the canonical String/Bytes/AppendTo/BytesToString/Pooled API and a configurable Redactor (WithMarker, WithLuhnCheck, WithExtraTokens, WithoutTokens, WithoutRules), with HTTPData* retained as compatibility aliases.
  • dnscache: Add host normalization (case-fold + trailing-dot trim), IP-literal bypass, canonical de-duplication of resolved addresses, and RFC 6724-aware IPv4/IPv6 interleaving. Adds family-restricted network filtering, errors.Join failure aggregation, sentinel errors ErrNoAddresses/ErrInvalidIP, and functional options WithDialer, WithDialTimeout, WithAddressRotation, and WithStaleIfError.
  • mysqllock: Add configurable keep-alive tuning (WithKeepAliveInterval, WithKeepAlivePingTimeout, WithReleaseTimeout), explicit lock-loss signaling via ErrLockLost and per-acquisition/instance WithLostLockHandler, and a robust idempotent release path. Fixes a deadlock when releasing from within a lock-loss handler, bounds keep-alive pings to detect hung connections, and adds sentinel errors ErrNilDB, ErrInvalidKey, and ErrInvalidTimeout.
  • timeutil: Add sentinel errors ErrInvalidDuration, ErrDurationOverflow, and ErrParseDateTime; implement encoding.TextMarshaler/TextUnmarshaler on Duration and DateTime (usable as JSON map keys and with YAML/TOML/flag.TextVar); fix numeric overflow in Duration.UnmarshalJSON; and treat JSON null as a no-op.
  • paging: Add HasPreviousPage/HasNextPage flags (has_previous_page/has_next_page) so callers can toggle navigation links without re-deriving boundary conditions.

🐛 Fixes

  • validator: Drop the custom ein override in favor of the upstream built-in, fill in missing error templates (bcp47_strict_language_tag, mimetype, noneof, noneofci, origin), parse falseif numeric params in base 10, and validate error templates at registration time. Guards isE164NoPlus/isUSZIPCode against non-string fields.
  • strsplit: Fix ChunkLine emitting a blank chunk for whitespace-only input shorter than the size. Refactors Chunk/ChunkLine into single-purpose helpers (output byte-for-byte identical), pre-sizes result slices, and clarifies byte-size semantics and boundary handling.
  • testutil: Bound ReplaceDateTime to the RFC3339 grammar and ReplaceUnixTimestamp to a word-bounded 19-digit match; fix CaptureOutput to restore the logger's real destination and close both pipe ends on every exit path (avoiding a goroutine/FD leak); tighten NewErrorCloser's exported surface to exactly io.ReadCloser.

⚡ Performance

  • random: Reduce allocations and speed up UUID/UID generation. UUIDv7 reads entropy into a stack buffer (~3% faster), RandString maps accepted bytes in place (4→2 allocs, ~12% faster at n=16), and TUID128/TUID64 gain zero-allocation Format/Byte methods (TUID128.Hex ~36% faster, String 3→1 allocs, ~28% faster).
  • uhex: Use a 256-entry lookup table for ~2–3× faster fixed-width hex encoding.
  • stringkey: Single-pass field normalization (collapse whitespace + lowercase together) with norm.NFC.Bytes on a pre-grown buffer; BenchmarkNew drops from 9→2 allocs/op and ~30% faster with byte-identical output. Reimplements Hex via pkg/uhex.
  • stringmetric: Flatten the DP matrix to a single row-major slice, cutting allocations 15→4 and improving cache locality, plus documented metric guarantees.

🔧 Chores

  • make: Cap benchmarks in the test target with -benchtime=1x (compile/race smoke check) and add a dedicated bench target for real measurements; mirrored into the examples/service scaffold.
  • deps: Update dependencies.

Full Changelog: v1.138.0...v1.139.0