Unfathomable Bugs #4: Keys that aren’t
Today’s bug design flaw comes courtesy of Adobe. Thank you, Adobe, this series wouldn’t exist without the generous support of entities like you.
I mentioned this bug design flaw in passing in a previous post, but it’s so good it deserves one of its own.
—
Here’s the hypothetical situation: you’re making a flash game. In that game users can create named profiles. You store the profiles, keyed by their name, so that you ca- OOPS, you just introduced a bug. What’s the problem? The dictionary.
Dictionaries (a.k.a. maps or hash tables or associative arrays) are a very useful construct. Most languages, including ActionScript 3.0, have one built in to their standard library. However, ActionScript 3.0′s dictionary is… special.
Action script is, at heart, a dynamic language. Object methods can be (in principle) added, changed, and removed at runtime. As a consequence, every object contains a mapping from method names to method instances (a “method table”). When the AS3 Dictionary class was implemented, the implementor(s) used a “small trick”. They noticed that the method table implemented all of the functionality of a dictionary, and decided to shove each dictionary’s contents into its own method table. Cool, that’s probably more efficient and it works perfectly!…? Right? Wrong.
Dictionaries have methods. Methods that are stored in the method table. The same place the “small trick” is trying to read and write unstructured data. Clearly we’ll need an additional trick to ensure the dictionary’s keys don’t intersect with method na- NOPE. RUNTIME FAIL.
var d:Dictionary = new Dictionary();
//Error #1037: Cannot assign to a method hasOwnProperty on flash.utils.Dictionary.
d["hasOwnProperty"] = "oh";
//Error #1037: Cannot assign to a method isPrototypeOf on flash.utils.Dictionary.
d["isPrototypeOf"] = "god";
//Error #1037: Cannot assign to a method propertyIsEnumerable on flash.utils.Dictionary.
d["propertyIsEnumerable"] = "why";
The reason we had a bug in our hypothetical situation is that the user could name a profile “hasOwnProperty”, or some other method name, and cause an unexpected exception. If you’ve ever used user input as the key to a dictionary in action script, you probably have this bug.
Even worse than the existence of this bug is the fact that there’s a special exception for it, meaning it’s actually a design flaw. Clearly someone knew about it, but didn’t fix the real problem. It is a blatant violation of the principle that correctness is more important than simplicity or efficiency. As a result, AS3 has an almost-a-dictionary class instead of an actual dictionary class.
—
Discuss on Reddit
—
Twisted Oak Studios offers consulting and development on high-tech interactive projects. Check out our portfolio, or Give us a shout if you have anything you think some really rad engineers should help you with.
Older Posts
- Unfathomable Bugs #6: Pretend Precision
- My Bug, My Bad #3: Accidentally Attacking WarCraft 3
- Collapsing Types vs Monads (followup)
- Collapsing Futures: Easy to Use, Hard to Represent
- Eventual Exceptions vs Programming in a Minimal Functional Style
- The Mystery of Flunf
- Explain it like I’m Five: The Socialist Millionaire Problem and Secure Multi-Party Computation
- Computer Science Blows My Mind
- A visit to Execution Labs in Montréal
- Transmuting Dice, Conserving Entropy
- Rule of Thumb: Ask for the Clock
- Rule of Thumb: Use Purposefully Weakened Methods
- Rule of thumb: Preconditions Should be Checked Explicitly
- Intersecting Linked Lists Faster
- Mouse Path Smoothing for Jack Lumber
- My Bug, My Bad #2: Sunk by Float
- Repeat Yourself Differently
- Grover’s Quantum Search Algorithm
- Followup to Non-Nullable Types vs C#
- Optimizing Just in Time with Expression Trees
- When One-Way Latency Doesn’t Matter
- Determining exactly if/when/where a moving line intersected a moving point
- Emulating Actors in C# with Async/Await
- Making an immutable queue with guaranteed constant time operations
- Improving Checked Exceptions
- Perishable Collections: The Benefits of Removal-by-Lifetime
- Decoupling shared control
- Decoupling inlined UI code
- Linq to Collections: Beyond IEnumerable<T>
- Publish your .Net library as a NuGet package
- When null is not enough: an option type for C#
- Unfathomable Bugs #5: Readonly or not
- Minkowski sums: examples
- My Bug, My Bad #1: Fractal Spheres
- Working around the brittle UI Virtualization in Windows 8
- Encapsulating Angles
- How would I even use a monad (in C#)?
- Useful/Interesting Methods #1: Observable.WhenEach
- Unfathomable Bugs #3: Stringing you along
- Anonymous Implementation Classes – A Design Pattern for C#
- Tasks for ActionScript 3 – Improving on Event-Driven Programming
- Minkowski sums and differences
- Non-Nullable Types vs C#: Fixing the Billion Dollar Mistake
- Unfathomable Bugs #2: Slashing Out
- Script templates and base classes
- Unity font extraction
- Abusing “Phantom Types” to Encode List Lengths Into Their Type
- Constructive Criticism of the Reactive Extensions API
- Quaternions part 3
- Quaternions part 2
- Quaternions part 1
- Unfathomable Bugs #1: You can have things! You can have things IN things! You can have …
- Coroutines – More than you want to know
- Asset Bundle Helper
- The Visual Studio goes away
- .Net’s time traveling StopWatch
- Polish
- Introducing Catalyst
