DEV Community

loading...

Things that are not strings

frantic profile image Alex Kotliarskyi Originally published at frantic.im on ・2 min read

As programmers, we have a collective delusion that anything that can be represented as a string, is a string. This thinking causes a whole bunch of problems.

Let’s take SQL for example. Every API in every programming language that I’ve seen considers SQL statement a string.

function execute(sql: string): Promise<Result>

Enter fullscreen mode Exit fullscreen mode

The problem with this API is that not every string is a valid SQL (nor sometimes it is the SQL you actually want to run).

Here’s a classic example of the misuse:

const query = 'SELECT * FROM posts WHERE id = '
  + params.id;

Enter fullscreen mode Exit fullscreen mode

In this example params.id can be anything, including invalid or malicious SQL.

The root problem here is not the lack of sanitization. The problem is that SQL is treated as a string.

Think about JSON for another example. You could certainly implement adding an item to a hash by doing this (I hope this code makes you cringe):

function addKeyValue(json, key, value) {
  return json.substr(0, json.length - 1)
    + ', "' + key + '": "' + value + '"}';
}

Enter fullscreen mode Exit fullscreen mode

As with the SQL example, you could add escaping and sanitization, but it’s just hacks hiding the real problem:

A string can be a representation of a thing, but it’s not the thing itself.

And it’s not only about concatenating strings. Can you spot the problem with this function? (hover to see the answer)

function isSafeDomain(url: string): boolean {
  return url.includes('https://safe.com/');
}

Enter fullscreen mode Exit fullscreen mode

Or in this one? (hover to see the answer)

function checkPassword(pass: string, hash: string): boolean {
  return bcrypt(pass) === hash;
}

Enter fullscreen mode Exit fullscreen mode

Strings are lower level, and thus are much more flexible than they need to be to properly implement valid operations.

Incomplete list of things that are not strings:

  • SQL
  • HTML
  • JSON
  • URL
  • File path
  • Password

Things are… things

You can save yourself a lot of headaches if you stop treating everything that can be represented as a string, as a string.

Both OO and FP styles allow for abstracting away something as a type or a class. You can make a closed opaque structure for the thing and limit the ways it can be constructed.

For example, for SQL, you might want to make sure it’s only created from static string literals.

Of course, at some point, you will need to serialize the thing into a string to pass it further, and that fine, as long as you never carelessly take a string and unserialize it yourself.

Here’s a few libraries for inspiration of how to treat things as… things:

Discussion

pic
Editor guide