Checking for this (and get()'ing it) is always invalid, so let's just
disallow it.
This also finds two bugs where the code is checking for types that can
never actually be in the variant (which was actually a refactor
artifact).
This changes the URL class to use the correct constness for getters,
setters and other methods. It also changes the entire class to use east
const style.
This patch introduces a new operator== to compare an Optional to its
contained type directly. If the Optional does not contain a value, the
comparison will always return false.
This also adds a test case for the new behavior as well as comparison
between Optional objects themselves.
This adds a hostname parameter as the third parameter to
URL::create_with_file_scheme(). If the hostname is "localhost", it will
be ignored (as per the URL specification).
This can for example be used by ls(1) to create more conforming file
URLs.
The m_path member variable has been superseded by m_paths. Thus, it has
been removed. The path() getter will continue to exist as a convenience
method for getting the path joined together as a string.
This adds URL serialization methods which are more in line with the
specification.
The serialize_for_display() method should be used e.g. in the browser
address bar, and as per the spec should not display username and
password. Furthermore, it could decode most percent-encoded code points,
although that is not implemented yet.
This adds a new URL parser, which aims to be compliant with the URL
specification (https://url.spec.whatwg.org/). It also contains a
rudimentary data URL parser.
This adds a few helper functions and a private constructor to
instantiate a data URL to the URL class. These will be needed by the
upcoming URL parser.
This adds the m_username, m_password, m_paths and m_cannot_be_a_base_url
member variables to the URL class. These are necessary for the upcoming
new URL parser.
The deprecated m_path variable shadows the m_paths variable if it is
non-null. This behavior will be removed once the old URL parser has been
removed.
This removes URLParser, because its two exposed functions, urlencode()
and urldecode(), have been superseded by URL::percent_encode() and
URL::percent_decode(). This is in preparation for the introduction of a
new URL parser.
This replaces all occurrences of those functions with the newly
implemented functions URL::percent_encode() and URL::percent_decode().
The old functions will be removed in a further commit.
This adds a few new functions to percent encode/decode strings according
to the URL specification. The functions allow specifying a
PercentEncodeSet, which is defined by the specification. It will be used
to replace the current urlencode() and urldecode() functions in a
further commit.
This commit adds a few duplicate helper functions in the URL class, such
as is_digit() and is_ascii_digit(). This will be cleaned up as soon as
the upcoming new URL parser will replace the current one.
This adds a peek method for Utf8CodepointIterator, which enables it to
be used in some parsing cases where peeking is necessary.
peek(0) is equivalent to operator*, expect that peek() does not contain
any assertions and will just return an empty Optional<u32>.
This also implements a test case for iterating UTF-8.
This renames all references to protocol to scheme, which is the name
used by the URL standard (https://url.spec.whatwg.org/). Externally, all
methods referencing "protocol" were duplicated with "scheme". The old
methods still exist as compatibility.
This patch removes unnecessary function parameter names in declarations
of the URL class. It also changes parameter types from String to
StringView where applicable.
For non-x86 targets, it's not very nice to define inline functions in
AK/Memory.h with asm volatile implementations. Guard this inline
assembly with ARCH(I386) and provide portable alternatives. Since we
always compile with optimizations, the hand-vectorized memset and
memcpy seem to be of dubious value, but we'll keep them here until
proven one way or another.
This should fix the Lagom build on native M1 macOS that was reported
on Discord the other day.
Previously the StringBuilder class would use memcpy() to write
directly into the ByteBuffer's buffer. Instead we should use the
append() method which ensures we don't overrun the buffer.
This allows us to mark the slow part (i.e. where we copy the buffer) as
NEVER_INLINE because this should almost never get called and therefore
should also not get inlined into callers.
Previously ByteBuffer::grow() behaved like Vector<T>::resize().
However the function name was somewhat ambiguous - and so this patch
updates ByteBuffer to behave more like Vector<T> by replacing grow()
with resize() and adding an ensure_capacity() method.
This also lets the user change the buffer's capacity without affecting
the size which was not previously possible.
Additionally this patch makes the capacity() method public (again).
Previously, we would go crazy and shift things way out of bounds.
Add tests to verify that the decoding algorithm is safe around the
limits of the result type.
printf didn't check whether the additional integer variable belongs to
the field width specifier or to the precision specifier, and always
applied it to the field width instead.
Implement the case distinction that we already use in literal width
and precision specifiers for the variable version as well so that
they are correctly attributed.
These dbgln's caused excessive load in the WebServer process,
accounting for ~67% of the processing time when serving a webpage
with a bunch of resources like serenityos.org/happy/2nd/.
We want to discourage folks from using APIs which lull you into a sense
of false safety in terms of OOM. There are cases where you want to force
allocations to succeed or crash, but those should use a more explicit
API than `AK::adopt_own(.)`.
The ASAN_[UN]POISON_MEMORY_REGION macros can be used to manually notify
the AddressSanitizer runtime about the reachability of instrumented code
accessing a memory region. This is most useful for manually managed
heaps and arenas that do not go directly to malloc or alligned_alloc.
Previously GCC came to the conclusion that we were reading
m_outline_capacity via ByteBuffer(ByteBuffer const&) -> grow()
-> capacity() even though that could never be the case because
m_size is 0 at that point which means we have an inline buffer
and capacity() would return inline_capacity in that case without
reading m_outline_capacity.
This makes GCC inline parts of the grow() function into the
ByteBuffer copy constructor which seems sufficient for GCC to
realize that m_outline_capacity isn't actually being read.
When compiling the Kernel with Og, the compiler complains that
m_outline_capacity might be uninitialized when calling capacity()
Note that this fix is not really what we want. Ideally only outline
buffer and outline capacity would need initialized, not the entire
inline buffer. However, clang considers the class to not be
default-constructible if we make that change, while gcc accepts it.
We had two functions for doing mostly the same thing. Combine both
of them into String::find() and use that everywhere.
Also add some tests to cover basic behavior.
Problem:
- The constructor is defined to be the default constructor.
Solution:
- Let the compiler generate the destructor by setting it to the
default.
We were accidentally calling calculate_base64_decoded_length instead,
which resulted in extra allocations during the StringBuilder::append
calls that can be avoided.
This patch implements a Unicode-safe substring method, which can be used
when offset and length should be specified in actual characters instead
of bytes.
This can be used to mitigate issues where a string is split in the
middle of a UTF-8 multi-byte character, which leads to invalid UTF-8.
Furthermore, it implements to common shorthands for substring methods
which take only an offset and return the substring until the end of the
string.
If a line was larger than 1024 bytes or the file ended without a
newline character, can_read_line would return false.
IODevice::can_read_line() now reads until a newline is found or
EOF is reached.
fixes#5907
This introduces the UnicodeUtils file, which contains helper functions
related to Unicode. This is in contrast to StringUtils, whose functions
are not directly related to Unicode and are, in theory,
encoding-agnostic.
Removing the element from the intrusive linked list might not be safe
if doing so requires a lock. Instead this is something the caller
should have done so let's verify instead that we're not on any lists.
Problem:
- Bitmasks are duplicated.
- Bitmasks are C-style arrays.
Solution:
- Move bitmasks to BitmapView.h.
- Change C-style arrays to be AK::Array for added safety.
Previously <AK/Function.h> also included <AK/OwnPtr.h>. That's about to
change though. This patch fixes a few build problems that will occur
when that change happens.
This changes Variant::visit() to forward the value returned by the
selected visitor invocation. By perfectly forwarding the returned value,
this allows for the visitor to return by value or reference.
Note that all provided visitors must return the same type - the compiler
will otherwise fail with the message: "inconsistent deduction for auto
return type".
Problem:
- Function local `constexpr` variables do not need to be
`static`. This consumes memory which is unnecessary and can prevent
some optimizations.
- C-style arrays are not as safe as AK::Arrays and require the user to
specify the length of the array manually.
Solution:
- Remove `static` keyword.
- Change from C-style array for AK::Array.
In case the write was to stderr/stdout, and it just so happened to fail
because of an issue like "the pty is gone", VERIFY() would end up
calling vout() back to write to stderr, which would then fail forever
until the stack is exhausted.
"Fixes" the issue where the Shell would crash in horrible ways when the
terminal is closed.
Previously StringBuilder would start allocating an external buffer
once the caller has used up more than half of the inline buffer's
capacity. Instead we should prefer to use the inline buffer until
it is full and only then start to allocate an external buffer.
Problem:
- `BitmapView` permits changing the underlying `Bitmap`. This violates
the idea of a "view" since views are simply overlays which can
themselves change but do not change the underlying data.
Solution:
- Migrate all non-`const` member functions to Bitmap.
Problem:
- Static variables take memory and can be subject to less optimization.
- This static variable is only used in 1 place.
Solution:
- Move the variable into the function and make it non-static.
This was removed as part of the ByteBuffer changes but the allocation
optimization is still necessary at least for non-SerenityOS targets
where malloc_good_size() isn't supported or returns a small value and
causes a whole bunch of unnecessary reallocations.
As the parser now flattens out the instructions and inserts synthetic
nesting/structured instructions where needed, we can treat the whole
thing as a simple parsed bytecode stream.
This currently knows how to execute the following instructions:
- unreachable
- nop
- local.get
- local.set
- {i,f}{32,64}.const
- block
- loop
- if/else
- branch / branch_if
- i32_add
- i32_and/or/xor
- i32_ne
This also extends the 'wasm' utility to optionally execute the first
function in the module with optionally user-supplied arguments.
Problem:
- `BitmapView` permits changing the underlying `Bitmap`. This violates
the idea of a "view" since views are simply overlays which can
themselves change but do not change the underlying data.
Solution:
- Migrate all non-`const` member functions to Bitmap.
The current code is factored such that reads to the entirety of the last
byte should be dropped. This was relying on the fact that last would be
one past the end in that case. Instead of actually reading that byte
when it's completely out of bounds of the bitmask, just skip reads that
would be invalid. Add more tests to make sure that the behavior is
correct for byte aligned reads of byte aligned bitmaps.
As we removed the support of VBE modesetting that was done by GRUB early
on boot, we need to determine if we can modeset the resolution with our
drivers, and if not, we should enable text mode and ensure that
SystemServer knows about it too.
Also, SystemServer should first check if there's a framebuffer device
node, which is an indication that text mode was not even if it was
requested. Then, if it doesn't find it, it should check what boot_mode
argument the user specified (in case it's self-test). This way if we
try to use bochs-display device (which is not VGA compatible) and
request a text mode, it will not honor the request and will continue
with graphical mode.
Also try to print critical messages with mininum memory allocations
possible.
In LibVT, We make the implementation flexible for kernel-specific
methods that are implemented in ConsoleImpl class.
Previously ByteBuffer would internally hold a RefPtr to the byte
buffer and would behave like a reference type, i.e. copying a
ByteBuffer would not create a duplicate byte buffer, but rather
two objects which refer to the same internal buffer.
This also changes ByteBuffer so that it has some internal capacity
much like the Vector<T> type. Unlike Vector<T> however a byte
buffer's data may be uninitialized.
With this commit ByteBuffer makes use of the kmalloc_good_size()
API to pick an optimal allocation size for its internal buffer.
This commit replaces the former, hand-written parser with a new one that
can be generated automatically according to a state change diagram.
The new `EscapeSequenceParser` class provides a more ergonomic interface
to dealing with escape sequences. This interface has been inspired by
Alacritty's [vte library](https://github.com/alacritty/vte/).
I tried to avoid changing the application logic inside the `Terminal`
class. While this code has not been thoroughly tested, I can't find
regressions in the basic command line utilities or `vttest`.
`Terminal` now displays nicer debug messages when it encounters an
unknown escape sequence. Defensive programming and bounds checks have
been added where we access parameters, and as a result, we can now
endure 4-5 seconds of `cat /dev/urandom`. :D
We generate EscapeSequenceStateMachine.h when building the in-kernel
LibVT, and we assume that the file is already in place when the userland
library is being built. This will probably cause problems later on, but
I can't find a way to do it nicely.
By constraining two implementations, the compiler will select the best
fitting one. All this will require is duplicating the implementation and
simplifying for the `void` case.
This constraining also informs both the caller and compiler by passing
the callback parameter types as part of the constraint
(e.g.: `IterationFunction<int>`).
Some `for_each` functions in LibELF only take functions which return
`void`. This is a minimal correctness check, as it removes one way for a
function to incompletely do something.
There seems to be a possible idiom where inside a lambda, a `return;` is
the same as `continue;` in a for-loop.
This implements the macOS API malloc_good_size() which returns the
true allocation size for a given requested allocation size. This
allows us to make use of all the available memory in a malloc chunk.
For example, for a malloc request of 35 bytes our malloc would
internally use a chunk of size 64, however the remaining 29 bytes
would be unused.
Knowing the true allocation size allows us to request more usable
memory that would otherwise be wasted and make that available for
Vector, HashTable and potentially other callers in the future.
If we're constructing a FlyString from a StringView, and we already
have a matching StringImpl in the table, use HashTable::find() to
locate the existing string without creating a temporary String.
Creating a ByteBuffer involves two allocations:
-One for the ByteBufferImpl object
-Another one for the actual byte buffer
This changes the ByteBuffer and ByteBufferImpl classes
so only one allocation is necessary.
This adds an `AK::ByteReader` to help with that so we don't duplicate
the logic all over the place.
No more `*(const u16*)` and `*(const u32*)` for anyone.
This should help a little with #7060.
We call placement new for the newly added slots. However, we should
also specify an initializer so primitive data types like u64 are
initialized appropriately.
Unfortunately adopt_ref requires a reference, which obviously does not
work well with when attempting to harden against allocation failure.
The adopt_ref_if_nonnull() variant will allow you to avoid using bare
pointers, while still allowing you to handle allocation failure.
Unfortunately adopt_own requires a reference, which obviously does not
work well with when attempting to harden against allocation failure.
The adopt_own_if_nonnull() variant will allow you to avoid using bare
pointers, while still allowing you to handle allocation failure.
This patch adds two new methods to LexicalPath. LexicalPath::append
appends a new path component to a LexicalPath, and LexicalPath::join
constructs a new LexicalPath from one or more components.
Co-authored-by: Gunnar Beutner <gunnar@beutner.name>
The get_dir_entries syscall failed if the serialized form of all the
directory entries together was too large to fit in its temporary buffer.
Now the kernel uses a fixed size buffer, that is flushed to an output
buffer when it is full. If this flushing operation fails because there
is not enough space available, the syscall will return -EINVAL. That
error code is then used in userspace as a signal to allocate a larger
buffer and retry the syscall.
This allows the construction of `Variant<int, int, int>`.
While this might not seem useful, it is very useful for making variants
that contain a series of member function pointers, which I plan to use
in LibGL for glGenLists() and co.
typeid() and RTTI was a nice clutch to implement this, but let's move
away from the horrible slowness and implement variants using type
indices for faster variants.
This commit introduces the ability to parse the document catalog dict,
as well as the page tree and individual pages. Pages obviously aren't
fully parsed, as we won't care about most of the fields until we
start actually rendering PDFs.
One of the primary benefits of the PDF format is laziness. PDFs are
not meant to be parsed all at once, and the same is true for pages.
When a Document is constructed, it builds a map of page number to
object index, but it does not fetch and parse any of the pages. A page
is only parsed when a caller requests that particular page (and is
cached going forwards).
Additionally, this commit also adds an object_cast function which
logs bad casts if DEBUG_PDF is set. Additionally, utility functions
were added to ArrayObject and DictObject to get all types of objects
from the collections to avoid having to manually cast.
This can currently parse a really simple module.
Note that it cannot parse the DataCount section, and it's still missing
almost all of the instructions.
This commit also adds a 'wasm' test utility that tries to parse a given
webassembly binary file.
It currently does nothing but exit when the parse fails, but it's a
start :^)
This enables us to use keys of type NonnullRefPtr in HashMaps and
HashTables.
This commit also includes fixes in various places that used
HashMap<T, NonnullRefPtr<U>>::get() and expected to get an
Optional<NonnullRefPtr<U>> and now get an Optional<U*>.
Additionally, the const version of get() returns Optional<ConstPeekType>
for smart pointers.
For example, if the value in the HashMap is OwnPtr<u32>,
HashMap::get() const returns Optional<const u32*>.
Also, the PeekType of smart pointers is now T* instead of const T*.
Note: This commit doesn't compile, it breaks HashMap::get() for some
types. Fixed in the next commit.
This currently (obviously) doesn't support any actual 3D hardware,
hence all calls are done via software rendering.
Note that any modern constructs such as shaders are unsupported,
as this driver only implements Fixed Function Pipeline functionality.
The library is split into a base GLContext interface and a software
based renderer implementation of said interface. The global glXXX
functions serve as an OpenGL compatible c-style interface to the
currently bound context instance.
Co-authored-by: Stephan Unverwerth <s.unverwerth@gmx.de>
Also adds an AK::Empty struct, because 'empty' variants are useful, but
this implementation leaves that to the user (i.e. a variant cannot
actually be empty, but it can contain an instance of Empty - i.e. a
byte).
Note that this is more of a constrained Any type, but they basically do
the same things anyway :^)
Adding -fno-semantic-interposition to the GCC command
line caused this new warning.
I don't see how output.data() could be uninitialized here. Also,
commenting out the ensure_capacity() call for the Vector
also gets rid of this warning.