# v0.3.8 (2023-02-25) Theme: Fixes from fuzzing (part 3/?) User-facing changes: - Change: Encoder: When encoding a `map`, sort the key:value pairs by the pre-string-encoded key rather than the post-string-encoded key. For instance, now `""` sorts before `" "`. # v0.3.8 (2023-02-25) Theme: Fixes from fuzzing (part 2/?) User-facing changes: - Feature: There is a new `DecodeString` helper function. - Change: Decoder: No longer bails when a type error (`DecodeTypeError`) is encountered. The part of the output value with the type error is either unmodified (if already existing) or set to nil/zero (if not already existing), and decoding continues. If no later fatal error (syntax, I/O) is encountered, then the first type error encountered is returned. This is consistent with the behavior of `encoding/json`. - Change: Several error strings have been reworded to match `encoding/json`. - Bugfix: Decoder: If there is a syntax error in a byte that invalid UTF-8, include that byte value in the error message rather than including the U+FFFD Unicode replacement character. - Bugfix: Syntax errors on raw-bytes (for invalid UTF-8) no longer show the raw byte as a `\u00XX` Unicode codepoint, but now as a `\xXX` byte. - Bugfix: compat/json: `io.EOF` is now correctly converted to "unexpected end of JSON input", same as `io.ErrUnexpectedEOF`. - Bugfix: ReEncoder: Don't count bytes already in the UTF-8 decode buffer toward the number of bytes returned from `.Write` and `.WriteString`. This only comes up if there is an I/O causing a partial write. - Bugfix: ReEncoder: The error messages for trailing partial UTF-8 now reflect the `InvalidUTF8` setting, rather than simply saying "unflushed unicode garbage". - Bugfix: No longer allows a comma after the last key:value pair in an object. # v0.3.7 (2023-02-20) Theme: Fixes from fuzzing (part 1?) User-facing changes: - General Changes: + Change: ReEncoder: No longer compact floating-point numbers by default, add a `CompactFloats` ReEncoderConfig option to control this. + Bugfix: Encoder, ReEncoder: Now correctly trims unnecessary the trailing '0's from the fraction-part when compacting numbers. + Bugfix: Decoder: Decoding `json.Unmarshaler` or `lowmemjson.Decodable` as a top-level value no longer needs to read past the closing `"`/`]`/`}`; this can be significant when reading streaming input, as that next read may block. - Compatibility bugfixes: + compat/json.Valid: No longer considers truncated JSON documents to be valid. + compat/json.Compact, compat/json.Indent: Don't write to the destination buffer if there is a syntax error. + compat/json.Compact, compat/json.Indent: No longer compact floating-point numbers; as `encoding/json` doesn't. + compat/json.HTMLEscape: Just look for problematic UTF-8 runes, don't actually parse as JSON. This is consistent with the function's lack of an `error` return value, and with the behavior of `encoding/json`. + compat/json.Indent: Preserve trailing whitespace, same as `encoding/json`. + compat/json.Decoder: No longer transforms "unexpected EOF" errors to "unexpected end of JSON input". This makes it different than `compat/json.Unmarshal`, but the same as `encoding/json`. + compat/json.Decoder, compat/json.Unmarshal: No longer mutate the target value at all if there is a syntax error in the input. - Unicode: + Feature: Encoder, ReEncoder: Add an `InvalidUTF8` ReEncoderConfig option and `BackslashEscapeRawByte` BackslashEscapeMode to allow emitted strings to contain invalid UTF-8. + Feature: ReEncoder: No longer unconditionally normalizes `\uXXXX` hex characters to lower-case; now this is controlled by the `BackslashEscaper` (and the default is now to leave the capitalization alone). + Change: EscapeDefault, EscapeDefaultNonHTMLSafe: No longer force long Unicode `\uXXXX` sequences for the U+FFFD Unicode replacement character. + Change: Encoder: Unless overridden by the BackslashEscaper, now by default uses `\uXXXX` sequences when emitting the U+FFFD Unicode replacement character in place of invalid UTF-8. + Bugfix: Encoder, ReEncoder: Fix an issue with decoding UTF-8 that when a codepoint straddles a write boundary it is interpreted as a sequence of U+FFFD runes. + Bugfix: compat/json.Valid: Do not consider JSON containing invalid UTF-8 to be valid (this is different than `encoding/json` at the time of this writing; but I consider that to be a bug in `encoding/json`; [go#58517][]). + Bugfix: compat/json.Compact, compat/json.Indent: Don't munge invalid UTF-8 in strings; as `encoding/json` doesn't. [go#58517]: https://github.com/golang/go/issues/58517 # v0.3.6 (2023-02-16) Theme: Architectural improvements User-facing changes: - Change: ReEncoder: The ReEncoderConfig struct member is no longer public. - Change: ReEncoder: `WriteRune` may now be called even if there is a partial UTF-8 codepoint from a `Write` or `WriteString` call, but now simply returns the width of the rune, rather than the number of bytes actually written. - Feature: `Number` and `RawMessage` type aliases are now available, so that a user of lowmemjson's native APIs does not need to import `encoding/json` or compat/json in order to use them. - Bugfix: Encoder, ReEncoder: If there was an error writing to the output stream, it may have returned a `*ReEncodeSyntaxError` even though it's not a syntax issue, or may have returned the underlying error without wrapping it. If there is an error writing to the output, Encoder and ReEncoder now return `*EncodeWriteError` and `*ReEncodeWriteError` respectively. # v0.3.5 (2023-02-10) Theme: Compatibility bugfixes User-facing changes: - Decoder: Fixes a bug where if an EOF is encountered, the reader is appended to, then another Decode is attempted, that EOF poisons future Decodes. This is something that `encoding/json` supports. - Encoder: Fixes a bug where if an encode error is encountered, all future Encode calls will fail. Reusing an Encoder is something that `encoding/json` supports. - compat/json.Encoder: Now buffers the output, to avoid partial writes if an encode error is encountered. This matches the behavior of `encoding/json`. For memory consumption reasons, the native lowmemjson Encoder still does not buffer. # v0.3.4 (2023-02-05) Theme: Fix compilation with Go 1.20 lowmemjson uses git.lukeshu.com/go/typedsync.CacheMap (since lowmemjson v0.3.1), which when compiled with Go 1.20 makes use of Go 1.20 language features. However, because lowmemjson's `go.mod` said `go 1.18`, those language features are disabled and compilation fails (see [go#58342][]). To work around this, lowmemjson's `go.mod` now says `go 1.20`. Despite this, lowmemjson still works fine with Go 1.18. [go#58342]: https://github.com/golang/go/issues/58342 # v0.3.3 (2023-02-04) Theme: Bugfix User-facing changes: - ReEncoder: Fixes a regression in v0.3.1 where it erroneously enters compact mode when CompactIfUnder is set and write barriers are in use. - ReEncoder: Fixes a regression in v0.3.1 where it sometimes emits extra (but syntactically valid) newlines when write barriers are in use. # v0.3.2 (2023-02-03) Theme: Bugfix User-facing changes: - ReEncoder: Fixes a regression in v0.3.1 where it sometimes emits extra (but syntactically valid) newlines. # v0.3.1 (2023-01-31) Theme: Performance This release does a bunch of performance tuning and optimizations, with no user-visible changes other than memory consumption and CPU time. Based on benchmarks with a real-world use-case, it is now roughly an order of magnitude faster, with much lower memory consumption (the big-O of memory consumption was always pretty low, but there were some big constant factors before). # v0.3.0 (2023-01-30) Theme: Breaking changes This release makes a breaking change to the way *ReEncoder works. This change both better fits what's convenient to use, and enables making future performance improvements. Breaking changes: - ReEncoder: Instead of instantiating a `*ReEncoder` with ```go reenc := &lowmemjson.ReEncoder{Out: w, settings} ``` it is now instantiated with ```go reenc := lowmemjson.NewReEncoder(w, lowmemjson.ReEncoderConfig{settings}) ``` # v0.2.1 (2023-01-30) Theme: Code quality This release improves code quality; getting various linters to pass, adding tests (and a few bug-fixes), refactoring things to be clearer, fixing some mistakes in the documentation. User-facing changes: - Encoder: `*EncodeMethodError` is now also used when a method produces invalid JSON. - Decoder: The offset in `*DecodeTypeError`s now correctly point the start of the value, rather than somewhere in the middle of it. # v0.2.0 (2023-01-26) Theme: Add documentation This release doesn't make any major changes, and is just adding documentation. I have removed a few minor things that I didn't want to write documentation for. Breaking changes: - Drop the following shorthand functions: + `func Decode(r io.RuneScanner, ptr any) error { return NewDecoder(r).Decode(ptr) }` + `func DecodeThenEOF(r io.RuneScanner, ptr any) error { return NewDecoder(r).DecodeThenEOF(ptr) }` + `func Encode(w io.Writer, obj any) (err error) { return NewEncoder(w).Encode(obj) }` - Drop `const Tab = "\t"`. # v0.1.0 (2022-09-19) Theme: Initial release