CodeSOD: A Symbol of Bad Code
As developers, when we send data over the network, we can usually safely ignore the physical implementation of that network. At some level, though, the bits you're sending become physical effects in your transmission medium, whether it's radio waves or electrical signals.
You can't just send raw bits over the wire. Those bits have to be converted into a symbol suitable for the transmission medium. Symbols could be the dots-and-dashes of morse code, tones transmitted over a phone line, or changing duty cycles on a pulse-width-modulated signal. The number of symbols per second is the baud rate of the channel. What this means for digital transmission is that even if your channel has a potential bit rate of one gigabit per second, the actual baud rate may be different- either much larger or much smaller. For example, modems might send 4-bits per symbol, meaning a 2,400 baud modem actually can transmit 9,600 bits per second. GPS, on the other hand, can transmit 50 bits/s, but over one million symbols per second thanks to spread spectrum broadcast.
Marnie works for a telcoms company which greatly cares about these sorts of details. There's a variety of client-side web apps which accrued over time which can help with things like symbol rate calculations.
For their environment, this calculation is straightforward: whatever the bits-per-second of the channel is, divide by 1.25 to find the symbol rate. Of course, this simple calculation can't be performed without regexes. Marnie found this code in the code base:
private bandwidthList = [6.4, 3.2, 1.6];private symbolRateList = [5.12, 2.56, 1.28]; public getSymbolRate(_bandwidth: number): string {let BW1DecimalPoint = _bandwidth.toString().match(/^-?\d+(?:\.\d{0,1})?/)[0];let symbolRate = this.symbolRateList[0];let symbolIndex = this.bandwidthList.indexOf(parseInt(BW1DecimalPoint));if (symbolIndex > 0) {symbolRate = this.symbolRateList[symbolIndex];}return formatValue(symbolRate);}
Now, this is TypeScript, so there is no guarantee that, at runtime, _bandwidth will actually be a number. But there's no need to convert it to a string, match against a regex, slice up the results, only to parse it back into a an int later. Which, it's important to note, because they use parseInt inside of the indexOf call, this will never find the target entry inside of bandwidthList- 6 is not 6.4.
So, as written, this method only ever returns 5.12. It's been in use, in production, for a few years now. Not only is in overly complex, it also just doesn't work.
Marnie fixed the code with a much simpler version:
public getSymbolRate(_bandwidth: number): string {let symbolRate = _bandwidth / 1.25;return formatValue(symbolRate);}[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.