WEBVTT
Kind: captions
Language: en-GB

1
00:00:00.120 --> 00:00:05.600
Today, a link that could crash Google Chrome
hit the news. And here it is. If that was

2
00:00:05.600 --> 00:00:10.210
a real link, and you moused over it or clicked
it, Chrome would instantly crash. At least,

3
00:00:10.210 --> 00:00:14.730
as I record this, if you're watching this
off in the future, it's probably fixed. To

4
00:00:14.730 --> 00:00:19.080
understand why, we need to learn about how
computers store text.

5
00:00:19.080 --> 00:00:24.180
As you probably know, computers store letters
and words -- the term is strings of characters

6
00:00:24.180 --> 00:00:29.160
-- as ones and zeros. But the metaphors you
see on screen, of files and folders all neatly

7
00:00:29.160 --> 00:00:33.800
organised or, in programming languages, the
idea of individual variables stored separately

8
00:00:33.800 --> 00:00:38.989
in memory, those metaphors hide what's actually
going on -- which is that down at the metal,

9
00:00:38.989 --> 00:00:44.109
or at the silicon, it really is just ones
and zeros, with everything just stuffed next

10
00:00:44.109 --> 00:00:49.760
to each other. How does a computer know where
to start and stop reading in that jumble of binary?

11
00:00:50.149 --> 00:00:54.409
Finding the right string and starting to read
it is pretty easy, there's an index of memory

12
00:00:54.409 --> 00:00:58.239
locations somewhere. Most programmers never
actually have to deal with this, it's all

13
00:00:58.239 --> 00:01:02.519
abstracted away for you by the language you
choose, but at some point, the computer has

14
00:01:02.519 --> 00:01:08.750
to say: right, you see this bit of memory, right here. That is, let's say, the web page

15
00:01:08.750 --> 00:01:12.030
the user wants to see next. Start reading
that here.

16
00:01:12.030 --> 00:01:17.330
But remember: the memory it's reading is just
a huge, nearly-endless string of ones and

17
00:01:17.330 --> 00:01:21.590
zeros. If "start here" is all the information
the computer's got when it tries to read it

18
00:01:21.590 --> 00:01:26.700
back, then it doesn't know how long that string
is. It'll quite happily keep reading and reading

19
00:01:26.700 --> 00:01:31.270
and reading unless it knows that length. And
there are a couple of approaches on how to

20
00:01:31.270 --> 00:01:32.100
solve that.

21
00:01:32.100 --> 00:01:36.520
First, you could store the length of the string
with the string. Generally at the start. So

22
00:01:36.520 --> 00:01:39.810
the computer gets pointed to the location,
and the first thing it reads is something

23
00:01:39.810 --> 00:01:45.360
that says, right, you are looking for 14 characters.
And then it reads out the 14 characters, and

24
00:01:45.360 --> 00:01:46.170
everyone's happy.

25
00:01:46.170 --> 00:01:50.240
And that's the modern way of doing things,
now we've got plenty of memory, but there's

26
00:01:50.240 --> 00:01:54.510
a catch: if you're storing longer strings,
longer than a couple of sentences, you're

27
00:01:54.510 --> 00:01:59.840
also going to need more than one byte to store
the length of the string -- and you're going

28
00:01:59.840 --> 00:02:04.870
to need to do that for every string, no matter
how short or long it is. It's not that space-efficient.

29
00:02:04.870 --> 00:02:09.119
I mean, I'm simplifying, there are other ways
of handling that, but anyway -- there are

30
00:02:09.119 --> 00:02:14.480
still a lot of implementations that use the
older, dirtier version: which is to stick

31
00:02:14.480 --> 00:02:18.069
a NULL character on the end of your string.

32
00:02:18.069 --> 00:02:24.670
A NULL is a byte that is completely zeroed.
Eight binary zeros in a row. We're not talking

33
00:02:24.670 --> 00:02:29.530
about actually trying to type the number 0
here, that's got its own code, this is a special,

34
00:02:29.530 --> 00:02:34.370
separate character just called NULL. So this
is called a null-terminated string, the computer

35
00:02:34.370 --> 00:02:38.519
just starts reading the string where it's
told to, and when it gets to a NULL, when

36
00:02:38.519 --> 00:02:42.680
it sees eight binary zeros in a row, it goes,
ah! The string's over. Brilliant. Which means

37
00:02:42.680 --> 00:02:48.349
you don't need all this fuss about storing
the length. Now, there is a whole load of

38
00:02:48.349 --> 00:02:52.840
computer science lectures on which technique
is more efficient for which operation, and

39
00:02:52.840 --> 00:02:56.950
why you might want to store the length or
you might not: all you need to know right

40
00:02:56.950 --> 00:03:01.310
now is, both of those techniques are still
in use.

41
00:03:01.310 --> 00:03:03.540
Which brings me back to this URL.

42
00:03:03.540 --> 00:03:09.659
First of all, those percentage signs. In a
URL, that percentage sign means an encoded

43
00:03:09.659 --> 00:03:15.620
character. You can't put certain punctuation
marks in a URL because they have special meanings:

44
00:03:15.620 --> 00:03:20.370
a hash sign, for example, means "go to this
point on the web page", so if you actually

45
00:03:20.370 --> 00:03:25.969
need to use a hash sign in the filename, in
the URL, you have to encode it. And you encode

46
00:03:25.969 --> 00:03:31.400
it as its representation here on this chart,
which goes way back to the 1980s. But the

47
00:03:31.400 --> 00:03:36.459
important part is: percent sign, then two
letters or numbers means "convert this to

48
00:03:36.459 --> 00:03:37.969
something else".

49
00:03:37.969 --> 00:03:43.980
Right. So let's run that on this URL. We've
got two areas that match: percent three zero,

50
00:03:43.980 --> 00:03:49.549
here and here. And if we look that up on the
chart: that gets decoded to... the number

51
00:03:49.549 --> 00:03:52.959
zero. Not a NULL, just literally, as if you
typed the number zero.

52
00:03:52.959 --> 00:03:57.689
So far, so innocent. Except there's still
a percent sign left, so if we run that decoder

53
00:03:57.689 --> 00:04:03.459
again on the result, now we're trying to decode
percent zero zero. Which gets decoded: to

54
00:04:03.459 --> 00:04:04.019
NUL.

55
00:04:04.019 --> 00:04:07.700
So originally, I thought, okay, it's returning
a string of a different length than it expected,

56
00:04:07.700 --> 00:04:12.849
or something like that, it's putting a NULL
where it shouldn't be, but no: it's more subtle

57
00:04:12.849 --> 00:04:17.819
than that. Chrome is taking the full URL,
decoding it once -- which is still sort-of

58
00:04:17.819 --> 00:04:23.139
valid, 'cos that NUL is escaped -- marking
it as being guaranteed A-OK, safe to use,

59
00:04:23.139 --> 00:04:28.430
then sending it off to the next bit of code.
That function then decodes it again, notices

60
00:04:28.430 --> 00:04:32.830
that NUL, and says hey, that's not a valid
character. We can't have that. So it marks

61
00:04:32.830 --> 00:04:34.030
the URL as invalid...

62
00:04:34.030 --> 00:04:38.660
...but the earlier code doesn't care, it already
knows it's good, so it just passes it onwards,

63
00:04:38.660 --> 00:04:44.759
a guaranteed-safe URL that isn't. At which
point Chrome goes "something has gone terribly

64
00:04:44.759 --> 00:04:46.630
wrong here" and crash--

65
00:04:48.840 --> 00:04:50.840
[Translating this video? Add your name here if you'd like credit!]

