hotcell-core 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hot_cell/core/version.rb +1 -1
- data/lib/hot_cell/descriptors.rb +24 -2
- data/lib/hot_cell/payload.rb +12 -18
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6649b9636b553b02ac5d1a178dd39eadb95884a83665b15d7d0278ae8af20260
|
|
4
|
+
data.tar.gz: 6726a7fa1abff37e8c478e2d7ee0818b7c1038983da282b237c4575c67da4e07
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ea9a2f0004527eef4f9078df8e4acef195fe86988372991a1488900b2d1e6c122de3f1bb5abd29cd8edd371538776a6a8a5b456a2db592b15cb1bf9760b35b9b
|
|
7
|
+
data.tar.gz: 8ab1b757c91463fe99380c7af6a878545578c5b1bf74b70c65a87ff61312c5cd6d905fe5be5b3804c5f4bb59cbb0e50e5563b80d50d09ffabf0d085de542ca9d
|
data/lib/hot_cell/descriptors.rb
CHANGED
|
@@ -39,8 +39,30 @@ module HotCell
|
|
|
39
39
|
# readable at any size, where staging it would be a write and RLIMIT_FSIZE bounds writes. Reopening
|
|
40
40
|
# `/dev/fd/N` gives a fresh file description at offset zero, so a read here does not disturb the
|
|
41
41
|
# descriptor the supervisor still holds.
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
#
|
|
43
|
+
# Darwin cannot keep that promise, so it keeps the behavior instead. `/dev/fd` has no procfs behind it
|
|
44
|
+
# there, and opening the path is dup(2): one shared offset, so what one reader consumes the next open
|
|
45
|
+
# skips. libvips sniffs a format by opening the path once per candidate loader, so the second loader
|
|
46
|
+
# reads past the magic bytes and a readable file is called unreadable.
|
|
47
|
+
#
|
|
48
|
+
# Darwin answers with the filename behind the descriptor, which a by-name open does start at zero. That
|
|
49
|
+
# hands a tool a path the cold side chose, which the rest of this class exists to prevent — a corner cut
|
|
50
|
+
# on purpose. Darwin is a development platform and nothing else: no container, no isolation, the cell
|
|
51
|
+
# running as the caller on the caller's own filesystem, where hiding a path it could already reach
|
|
52
|
+
# protected nothing. What has to match across platforms is what an operation sees — a path that reads
|
|
53
|
+
# from the first byte however many times it is opened — not how that is arrived at.
|
|
54
|
+
if RUBY_PLATFORM.include?("darwin")
|
|
55
|
+
F_GETPATH = 50 # sys/fcntl.h; Ruby's Fcntl module does not carry it
|
|
56
|
+
|
|
57
|
+
def fd_path
|
|
58
|
+
buffer = "\0" * 1024 # F_GETPATH writes the path into a buffer the caller supplies, MAXPATHLEN wide
|
|
59
|
+
io.fcntl F_GETPATH, buffer
|
|
60
|
+
buffer[/\A[^\0]+/]
|
|
61
|
+
end
|
|
62
|
+
else
|
|
63
|
+
def fd_path
|
|
64
|
+
"/dev/fd/#{io.fileno}"
|
|
65
|
+
end
|
|
44
66
|
end
|
|
45
67
|
|
|
46
68
|
def close
|
data/lib/hot_cell/payload.rb
CHANGED
|
@@ -22,27 +22,21 @@ module HotCell
|
|
|
22
22
|
JSON.generate object
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
# Keys are
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# round trip, which the JSON-native rule already forbids.
|
|
25
|
+
# Keys are symbolized so operations read payload[:format] and can splat a nested hash into keyword
|
|
26
|
+
# arguments. Values are not: a Symbol would not survive the round trip, which the JSON-native rule
|
|
27
|
+
# already forbids.
|
|
29
28
|
#
|
|
30
|
-
# JSON
|
|
31
|
-
#
|
|
29
|
+
# One rescue for the whole JSON layer. Naming what JSON.parse raises has been wrong twice: a report
|
|
30
|
+
# that was not an object raised TypeError past a rescue for JSON::ParserError, and a key holding
|
|
31
|
+
# invalid UTF-8 raised EncodingError past both. The supervisor parses worker reports inside its
|
|
32
|
+
# deadline loop with nothing above it rescuing, so each miss denies service to every request in the
|
|
33
|
+
# cell.
|
|
32
34
|
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
# holding bytes that are not valid UTF-8 raises EncodingError past both. The supervisor reads worker
|
|
37
|
-
# reports through here inside the loop that enforces every request's deadline, and nothing above it
|
|
38
|
-
# rescues anything, so each miss is a one-line denial of service against every request in the cell.
|
|
39
|
-
#
|
|
40
|
-
# The body is a single JSON.parse call, so this is scoped to "the JSON layer failed" and cannot
|
|
41
|
-
# swallow a bug in our own code. NoMemoryError is deliberately not caught: it is not a StandardError,
|
|
42
|
-
# and a document large enough to raise it is the worker's own memory verdict rather than a bad line.
|
|
35
|
+
# The body is one JSON.parse call, so the rescue cannot hide a bug of our own. NoMemoryError is not
|
|
36
|
+
# a StandardError and stays uncaught: a document that large is the worker's memory verdict, not a
|
|
37
|
+
# bad line.
|
|
43
38
|
def parse(json)
|
|
44
|
-
JSON.parse json, symbolize_names: true, max_nesting: MAX_NESTING, allow_nan: false
|
|
45
|
-
create_additions: false
|
|
39
|
+
JSON.parse json, symbolize_names: true, max_nesting: MAX_NESTING, allow_nan: false
|
|
46
40
|
rescue StandardError => error
|
|
47
41
|
raise MessageError, "#{error.class}: #{Failure.sanitize(error.message)}"
|
|
48
42
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hotcell-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Dalessio
|
|
@@ -43,8 +43,8 @@ licenses:
|
|
|
43
43
|
- MIT
|
|
44
44
|
metadata:
|
|
45
45
|
homepage_uri: https://github.com/basecamp/hotcell
|
|
46
|
-
source_code_uri: https://github.com/basecamp/hotcell/tree/v0.
|
|
47
|
-
changelog_uri: https://github.com/basecamp/hotcell/blob/v0.
|
|
46
|
+
source_code_uri: https://github.com/basecamp/hotcell/tree/v0.4.0/hotcell-core
|
|
47
|
+
changelog_uri: https://github.com/basecamp/hotcell/blob/v0.4.0/CHANGELOG.md
|
|
48
48
|
bug_tracker_uri: https://github.com/basecamp/hotcell/issues
|
|
49
49
|
rubygems_mfa_required: 'true'
|
|
50
50
|
rdoc_options: []
|