Consider the following snippet:
void foo(InputStream& stream) {
if(!stream.eof()) {
u8 byte;
stream >> byte;
}
}
There is a very subtle bug in this snippet, for some input streams eof()
might return false even if no more data can be read. In this case an
error flag would be set on the stream.
Until now I've always ensured that this is not the case, but this made
the implementation of eof() unnecessarily complicated.
InputFileStream::eof had to keep a ByteBuffer around just to make this
possible. That meant a ton of unnecessary copies just to get a reliable
eof().
In most cases it isn't actually necessary to have a reliable eof()
implementation.
In most other cases a reliable eof() is avaliable anyways because in
some cases like InputMemoryStream it is very easy to implement.
It has been possible for a signal to arrive in between us checking
g_interrupted and exiting - sucessfully, even though we were interrupted.
This way, if a signal arrives before we reset the disposition, we
will reliably check for it later; if it arrives afterwards, it'll
kill us automatically.
No difference in practice, but it's tidier and protects us
if we ever use g_interrupted earlier in main -- in that case,
the compiler might chose to keep the variable in a register without
the volatile.
Found by @bugaevc, thanks!
With this, hitting ctrl-c twice in `for i in $(seq 10) { sleep 1 }`
terminates the loop as expected (...well, I'd expect it to quit after
just one ctrl-c, but serenity's shell makes a single ctrl-c only
quit the current loop iteration).
Part of #3419.
Using a pool.ntp.org server seems nicer and more open-source-y,
but until our pool use is approved, let's put in a default value
that works.
(time.google.com serves smeared time instead of doing leap seconds.
pool.ntp.org doesn't serve smeared time. I intend to implement
client-side leap second smearing since nobody likes jumpy timestamps.
For now, we get this for free.)
This fetches information from /var/run/utmp and shows the interactive
sessions in a little list. More things can be added here to make it
more interesting. :^)
To keep track of ongoing terminal sessions, we now have a sort-of
traditional /var/run/utmp file, like other Unix systems.
Unlike other Unix systems however, ours is of course JSON. :^)
The /bin/utmpupdate program is used to update the file, which is
not writable by regular user accounts. This helper program is
set-GID "utmp".
I suspected an error in CircularDuplexStream::read(Bytes, size_t). This
does not appear to be the case, this test case is useful regardless.
The following script was used to generate the test:
import gzip
uncompressed = []
for _ in range(0x100):
uncompressed.append(1)
for _ in range(0x7e00):
uncompressed.append(0)
for _ in range(0x100):
uncompressed.append(1)
compressed = gzip.compress(bytes(uncompressed))
compressed = ", ".join(f"0x{byte:02x}" for byte in compressed)
print(f"""\
TEST_CASE(gzip_decompress_repeat_around_buffer)
{{
const u8 compressed[] = {{
{compressed}
}};
u8 uncompressed[0x8011];
Bytes{{ uncompressed, sizeof(uncompressed) }}.fill(0);
uncompressed[0x8000] = 1;
const auto decompressed = Compress::GzipDecompressor::decompress_all({{ compressed, sizeof(compressed) }});
EXPECT(compare({{ uncompressed, sizeof(uncompressed) }}, decompressed.bytes()));
}}
""", end="")
Addresses #3394 which was caused by dereferencing null `test_name`
when no arguments were given to /bin/tt. Additionally, arguments
other than the defined tests now print usage and exit to avoid
running the default test.
This only queries a single NTP server, only does a point-to-point
request, doens't do any filtering, doesn't display the response
in any useful format, and is generally very bare-bones.
But maybe, over time it can learn to query more servers, do
filtering, run as a service that keeps state over time to
improve filtering, adjust system time, and maybe learn to
run as an NTP server then.
And also mark strlcpy() and strlcat() with __attribute__((warn_unused_result)).
Since our code is warning-free, this ensures we never misuse those functions.
(Or are very sure about doing it when turning off the warning for a particular
piece of code.)
There was a logic mistake in the code that computes the offset between
columns, forgetting to account for the extra characters after a name.
The comment was accurate, but the code didn't match the comment.
Now we have an actual stream implementation that can read arbitrary
(dynamic codes aren't supported yet) deflate encoded data. Even if
the blocks are really large.
And all of that happens with a single buffer of 32KiB. DEFLATE is
amazing!
The fact that a `MarkedValueList` had to be created was just annoying,
so here's an alternative.
This patchset also removes some (now) unneeded MarkedValueList.h includes.
While this _does_ add a point of failure, it'll be a pretty bad day when
google goes down.
And this is unlikely to put a (positive) dent in their incoming
requests, so let's just roll with it until we have our own TLS server.
A malicious caller of ifconfig could have caused the ifr_name field to
lack NUL-termination. I don't think this was an actual problem, though, as
the Kernel always forces NUL-termination by overwriting ifr_name's last byte
with NUL.
However, it feels better to do it properly.
LibJS doesn't store stacks for exception objects, so this
only amends test-common.js's __expect() with an optional
`details` function that can produce a more detailed error
message, and it lets test-js.cpp read and print that
error message. I added the optional details parameter to
a few matchers, most notably toBe() where it now prints
expected and actual value.
It'd be nice to have line numbers of failures, but that
seems hard to do with the current design, and this is already
much better than the current state.
Previously, the implementation would produce one Vector<u8> which
would contain the whole decompressed data. That can be a lot and
even exhaust memory.
With these changes it is still necessary to store the whole input data
in one piece (I am working on this next,) but the output can be read
block by block. (That's not optimal either because blocks can be
arbitrarily large, but it's good for now.)
This lets disasm output contain the symbol names of call and jump
destinations:
8048111: e8 88 38 01 00 call 805b99e <__cxa_atexit>
...
8048150: 74 15 je 8048167 <_start+0x4c>
The latter (the symbol of the current function with an offset) is
arguably more distracting than useful because you usually want to look
at the instruction at the absolute offset in this case, but the former
is very nice to have.
For reasons I do not understand, this cuts the time to run
`disasm /bin/id` in half, from ~1s to ~0.5s.
Let's use the one in AK/NumberFormat.h everywhere.
It has slightly different behavior than some of the copies this
removes, but it's probably nice to have uniform human readable
size outputs across the system.
The SI prefixes "k", "M", "G" mean "10^3", "10^6", "10^9".
The IEC prefixes "Ki", "Mi", "Gi" mean "2^10", "2^20", "2^30".
Let's use the correct name, at least in code.
Only changes the name of the constants, no other behavior change.
I originally defined the bytes() method for the String class, because it
made it obvious that it's a span of bytes instead of span of characters.
This commit makes this more consistent by defining a bytes() method when
the type of the span is known to be u8.
Additionaly, the cast operator to Bytes is overloaded for ByteBuffer and
such.
This is a follow up to #2936 / d3e3b4ae56aa79d9bde12ca1f143dcf116f89a4c.
Affected programs:
- Applications: Browser (Download, View source, Inspect DOM tree, JS
console), Terminal (Settings)
- Demos: Cube, Eyes, Fire, HelloWorld, LibGfxDemo, WebView,
WidgetGallery
- DevTools: HackStudio, Inspector, Profiler
- Games: 2048, Minesweeper, Snake, Solitaire
- Userland: test-web
A few have been left out where manual positioning is done on purpose,
e.g. ClipboardManager (to be close to the menu bar) or VisualBuilder (to
preserve alignment of the multiple application windows).
Decorated Interpreter::call() with [[nodiscard]] to provoke thinking
about the returned value at each call site. This is definitely not
perfect and we should really start thinking about slimming down the
public-facing LibJS interpreter API.
Fixes#3136.
This enables a nice warning in case a function becomes dead code. Also,
in the case of test-crypto.cpp, I took the liberty to add the prefix 'g_'
to the global event loop.
Technically, this can be 'exploited' to set the pgid of an exploiting process
to a near-arbitrary new pgid. This can cause conflicts when assigning future pgids,
destroys the session-boundary, and might confuse future pgid-to-session lookups.
In practice, I can't come up with a way that this causes actual harm.
The symbol name insertion scheme is different from objdump -d's.
Compare the output on Build/Userland/id:
* disasm:
...
_start (08048305-0804836b):
08048305 push ebp
...
08048366 call 0x0000df56
0804836b o16 nop
0804836d o16 nop
0804836f nop
(deregister_tm_clones (08048370-08048370))
08048370 mov eax, 0x080643e0
...
_ZN2AK8Utf8ViewC1ERKNS_6StringE (0805d9b2-0805d9b7):
_ZN2AK8Utf8ViewC2ERKNS_6StringE (0805d9b2-0805d9b7):
0805d9b2 jmp 0x00014ff2
0805d9b7 nop
* objdump -d:
08048305 <_start>:
8048305: 55 push %ebp
...
8048366: e8 9b dc 00 00 call 8056006 <exit>
804836b: 66 90 xchg %ax,%ax
804836d: 66 90 xchg %ax,%ax
804836f: 90 nop
08048370 <deregister_tm_clones>:
8048370: b8 e0 43 06 08 mov $0x80643e0,%eax
...
0805d9b2 <_ZN2AK8Utf8ViewC1ERKNS_6StringE>:
805d9b2: e9 eb f6 ff ff jmp 805d0a2 <_ZN2AK10StringViewC1ERKNS_6StringE>
805d9b7: 90 nop
Differences:
1. disasm can show multiple symbols that cover the same instructions.
I've only seen this happen for C1/C2 (and D1/D2) ctor/dtor pairs,
but it could conceivably happen with ICF as well.
2. disasm separates instructions that do not belong to a symbol with
a newline, so that nop padding isn't shown as part of a function
when it technically isn't.
3. disasm shows symbols that are skipped (due to having size 0)
in parenthesis, separated from preceding and following instructions.