v1.7.4 — Unions carry what they accept
A union refuses members it cannot tell apart, and hostile payloads no longer cost memory.
Unions refuse members they cannot tell apart
Section titled “Unions refuse members they cannot tell apart”A Union works out which member a value belongs to
from the value itself. Where two members could both answer to one value, it used
to pick the first it found.
local Payload = Net.Types.Union( Net.Types.Map(Net.Types.String, Net.Types.NumberU8), Net.Types.Array(Net.Types.NumberU8))Both members are a table when sent. The array was tried first, so every table was written as an array, and a map arrived empty, with no error or warning. The same fault had two other forms:
Union(NumberVarU, NumberF32)sent 1.5 and delivered 1. Its signed twin delivered -2.Union(Color3, Color3F32)quantised a colour to eight bits.
Members that share a runtime shape are now told apart by the widest of them, which carries everything the others could:
Union(NumberU8, NumberF64) -- keeps its doubleUnion(Vector3F32, Vector3F16) -- keeps its precisionUnion(CFrame, CFrameRot) -- keeps its skewA union with no such member is refused where it is declared, not where it is sent:
BuyItem argument 1 names 2 members that all look like table when sent,and nothing says which one a value meantTen more datatypes travel in a union
Section titled “Ten more datatypes travel in a union”UDim, UDim2, Rect, Region3, NumberRange, TweenInfo, DateTime,
BrickColor, NumberSequence and ColorSequence could be declared in a union
but never carried by one. They travel now.
A member of a kind that still cannot be recognised, such as Any, Nil or
Static, is refused at the declaration instead of at the first send.
Security fixes
Section titled “Security fixes”- Memory exhaustion in
Compress. A run of values carries its own count, and a table was built for that count before the values were read. Five bytes could ask for about 90 MB. A count is now weighed against the bytes that arrived with it, so a malformed payload returnsnil. - A replication guard that covered half its key.
SetValidatorrefusedSetandMutate, but never sawSetPath,SetPathFor,IncrementorIncrementFor. Every write now answers to the guard, and a field is tried on a copy first, so a refusal leaves nothing behind. - Unmetered instances. Metering weighed a message’s payload but not the instances travelling beside it. Both are charged now.
Other changes
Section titled “Other changes”- A colour crossing through a channel no screen can show returns a valid colour
instead of
nan. Tweenapplies the same finite-number rule to a rate and a repeat count as to a time and a delay.- The descriptions of
NavigationandNet.Listnow match what they do.
Full changelog
Section titled “Full changelog”Every change in this release is listed in the changelog.