| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
| |
The function decodeFirstFrame() allocates memory based on data from
the mp3 header. This can make the buffer size allocation overflow, or
lead to a DoS attack with a very large buffer. Cap this buffer at 8
million frames, which should really be enough for reasonable files.
|
|
|
|
|
|
| |
The assertion on "!client_is_expired(client)" was wrong, because
writing the command response may cause the client to become expired.
Replace that assertion with a check.
|
|
|
|
|
|
|
|
|
|
| |
A crafted mp4 file could cause an integer overflow in mp4_decode
function in src/inputPlugins/mp4_plugin.c. mp4ff_num_samples()
function returns some tainted value. sizeof(float) * numSamples is an
integer overflow operation if numSamples is too huge, so xmalloc will
allocate a small memory region. I constructe a mp4 file, and use
faad2 to open the file. mp4ff_num_samples() returns -1. So I think mpd
bears from the same problem.
|
|\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
* mk/client-merge: (49 commits)
client: shorten names of the struct client variables
client: simplified client_read()
client: client_input_received() returns 0
client: check for COMMAND_RETURN_CLOSE
client: renamed local variable "selret" to "ret"
client: moved CLOSE/KILL check after client_process_line()
client: don't check FD_ISSET(client->fd) on expired client
client: removed assert(client->fd)>=0
fix -Wcast-qual -Wwrite-strings warnings
playlist: return -1 after assert(0)
command: concatenate strings at compile time
audio: don't pass "fd" to {en,dis}ableAudioDevice()
volume: don't pass "fd" to changeVolumeLevel()
directory: printDirectoryInfo() does not call commandError()
directory: don't pass fd to traverseAllIn()
directory: don't pass fd to traverseAllIn() callbacks
playlist: PlaylistInfo() does not call commandError()
playlist: don't pass "fd" to storedPlaylist.c functions
playlist: don't pass "fd" to playlist.c functions
playlist: showPlaylist() and shufflePlaylist() cannot fail
...
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Seeing the token "client" repeatedly in the same blocks of code
adds to mental fatigue and makes it harder to follow code
because there's fewer unique tokens to distinguish.
"cl" is unique within mpd and conveys enough information
to be useful to anybody reading the code.
|
| |
| |
| |
| | |
Remove one comparison by changing branch order.
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Since the caller chain doesn't care about the return value (except for
COMMAND_RETURN_KILL, COMMAND_RETURN_CLOSE), just return 0 if there is
nothing special. This saves one local variable initialization, and
one access to it.
Also remove one unreachable "return 1" from client_read().
|
| |
| |
| |
| |
| |
| |
| | |
Don't close the client within client_process_line(), return
COMMAND_RETURN_CLOSE instead. This is the signal for the caller chain
to actually close it. This makes dealing with the client pointer a
lot safer, since the caller always knows whether it is still valid.
|
| |
| |
| |
| | |
It's easier to reuse the variable if it has a more generic name.
|
| |
| |
| |
| | |
Don't update client data if it is going to be closed anyway.
|
| |
| |
| |
| |
| | |
client->fd becomes -1 when the client expires. Don't use FD_ISSET()
with this expired client; doing so would cause a crash due to SIGBUS.
|
| |
| |
| |
| |
| |
| | |
Since client->fd==-1 has become our "expired" flag, it may already be
-1 when client_close() is called. Don't assert that it is still
non-negative, and call client_set_expired() instead.
|
| |\
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
* mk/client: (24 commits)
client: reorder function declarations
client: check "expired" after command execution
client: added global "expired" flag
client: removed superfluous assertion
client: more assertions
client: moved code to sockaddr_to_tmp_string()
client: replace "expired" flag with fd==-1
client: moved "expired" accesses into inline function
client: no while loop in client_manager_io()
client: select() errors are fatal
client: use client_defer_output() in client_write()
client: moved code to client_write()
client: client_defer_output() can create the first defer buffer
client: return early on error in client_defer_output()
client: moved code to client_defer_output()
client: don't free client resources except in client_close()
client: allocate clients dynamically
client: added function client_by_fd()
client: return early in client_new()
client: renamed all public functions
...
|
| | |
| | |
| | |
| | |
| | | |
Change the order of function declarations in client.h, to make it well
arranged and readable.
|
| | |
| | |
| | |
| | |
| | |
| | | |
The old code tried to write a response to the client, without even
checking if it was already closed. Now that we have added more
assertions, these may fail... perform the "expired" check earlier.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Patch bdeb8e14 ("client: moved "expired" accesses into inline
function") was created under the wrong assumption that
processListOfCommands() could modify the expired flag, which is not
the case. Although "expired" is a non-const pointer,
processListOfCommands() just reads it, using it as the break condition
in a "while" loop. I will address this issue with a better overall
solution, but for now provide a pointer to a global "expired" flag.
|
| | |
| | |
| | |
| | |
| | |
| | | |
client_defer_output() was modified so that it can create the
deferred_send list. With this patch, the assertion on
"deferred_send!=NULL" has become invalid. Remove it.
|
| | | |
|
| | |
| | |
| | |
| | |
| | | |
Unclutter the client_new() constructor by moving unrelated complex
code into a separate function.
|
| | |
| | |
| | |
| | | |
Why waste 4 bytes for a flag which we can hide in another variable.
|
| | |
| | |
| | |
| | | |
Hiding this flag allows us later to remove it easily.
|
| | |
| | |
| | |
| | |
| | |
| | | |
The last patch removed the "continue" directive, and now the while
loop is without function. Remove it. Also make client_manager_io()
return 0.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Previously, when select() failed, we assumed that there was an invalid
file descriptor in one of the client structs. Thus we tried select()
one by one. This is bogus, because we should never have invalid file
descriptors. Remove it, and make select() errors fatal.
|
| | |
| | |
| | |
| | |
| | | |
Eliminate duplicated code, call client_defer_output() which we
splitted from client_write_output() earlier.
|
| | |
| | |
| | |
| | |
| | | |
Move the second part of client_write_output() into a separate
function.
|
| | |
| | |
| | |
| | |
| | |
| | | |
client_defer_output() was designed to add new buffers to an existing
deferred_send buffer. Tweak it and allow it to create a new buffer
list.
|
| | |
| | |
| | |
| | |
| | | |
Exit the function when an error occurs, and move the rest of the
following code one indent level left.
|
| | |
| | |
| | |
| | |
| | | |
Split the large function client_write_output() into two parts; this is
the first code moving patch.
|
| | |
| | |
| | |
| | |
| | |
| | | |
All of the client's resources are freed in client_close(). It is
enough to set the "expired" flag, no need to duplicate lots of
destruction code again and again.
|
| | |
| | |
| | |
| | |
| | |
| | | |
Due to the large buffers in the client struct, the static client array
eats several megabytes of RAM with a maximum of only 10 clients. Stop
this waste and allocate each client struct from the heap.
|
| | |
| | |
| | |
| | |
| | | |
The code becomes less complex and more readable when we move this
linear search into a separate mini function.
|
| | |
| | |
| | |
| | | |
This saves one level of indent.
|
| | |
| | |
| | |
| | |
| | |
| | | |
Functions which operate on the whole client list are prefixed with
"client_manager_", and functions which handle just one client just get
"client_".
|
| | |
| | |
| | |
| | |
| | | |
Rename all static functions, variables and macros which have
"interface" in their name to something nicer prefixed with "client_".
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Second patch: rename the internal struct name. We will eventually
export this type as an opaque forward-declared struct later, so we
can pass a struct pointer instead of a file descriptor, which would
save us an expensive linear lookup.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
I don't believe "interface" is a good name for something like
"connection by a client to MPD", let's call it "client". This is the
first patch in the series which changes the name, beginning with the
file name.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
linux/list.h is a nice doubly linked list library - it is lightweight
and powerful at the same time. It will be useful later, when we begin
to allocate client structures dynamically. Import it, and strip out
all the stuff which we are not going to use.
|
| |\ \
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
* mk/strset:
use strset.h instead of tagTracker.h
strset: fix duplicate values
added string set library
Conflicts:
src/dbUtils.c
src/tagTracker.c
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The previous patch enabled these warnings. In Eric's branch, they
were worked around with a generic deconst_ptr() function. There are
several places where we can add "const" to pointers, and in others,
libraries want non-const strings. In the latter, convert string
literals to "static char[]" variables - this takes the same space, and
seems safer than deconsting a string literal.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
print_playlist_result() had an assert(0) at the end, in case there was
an invalid result value. With NDEBUG, this resulted in a function not
returning a value - add a dummy "return -1" at the end to keep gcc
quiet.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
String literals (including those defined in CPP macros) can be
concatenated at compile time. This saves some CPU cycles in
vsnprintf() at run time.
|
| | | |
| | | |
| | | |
| | | | |
No protocol code in the audio output library.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
The "volume" library shouldn't talk to the client. Move error
handling to command.c.
|
| | | |
| | | |
| | | |
| | | | |
Move another ocurrence of error handling over to command.c.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
This patch continues the work of the previous patch: don't pass a file
descriptor at all to traverseAllIn(). Since this fd was only used to
report "directory not found" errors, we can easily move that check to
the caller. This is a great relief, since it removes the dependency
on a client connection from a lot of enumeration functions.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Database traversal should be generic, and not bound to a client
connection. This is the first step: no file descriptor for the
callback functions forEachSong() and forEachDir(). If a callback
needs the file descriptor, it has to be passed in the void*data
pointer somehow; some callbacks might need a new struct for passing
more than one parameter. This might look a bit cumbersome right now,
but our goal is to have a clean API.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Continuing the effort of removing protocol specific calls from the
core libraries: let the command.c code call commandError() based on
PlaylistInfo's return value.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
Return an "enum playlist_result" value instead of calling
commandError() in storedPlaylist.c.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The playlist library shouldn't talk to the client if possible.
Introduce the "enum playlist_result" type which the caller
(i.e. command.c) may use to generate an error message.
|
| | | |
| | | |
| | | |
| | | | |
Make them both return void.
|