summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Griffis <pgriffis@igalia.com>2023-03-16 13:43:10 -0500
committerPatrick Griffis <pgriffis@igalia.com>2023-03-16 14:16:14 -0500
commit4ca2386ecc32a63f25fb26f63e4d8f7736faec9e (patch)
treed03f10acb7019b0ab8c2e04d50f65bba4669adb5
parentb545d5f047d01f086c88abddacff9ba519b5afa1 (diff)
downloadlibsoup-pgriffis/soup-logger-crash.tar.gz
Fix crash using SOUP_LOGGER_LOG_BODY with SoupContentSnifferpgriffis/soup-logger-crash
-rw-r--r--libsoup/soup-message.c19
-rw-r--r--tests/logger-test.c36
2 files changed, 54 insertions, 1 deletions
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index ebe9e9f2..10c69102 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -2887,6 +2887,23 @@ soup_message_has_content_sniffer (SoupMessage *msg)
return priv->sniffer != NULL;
}
+static SoupContentSnifferStream *
+soup_content_sniffer_stream_from_stream (GFilterInputStream *stream)
+{
+ /* If SoupLoggerInputStream wraps our SoupContentSnifferStream we need to go up the chain to find the sniffer.
+ In this usage there should always be one in the chain and it is fine to extract it as long we
+ don't do a read() on the base stream which soup_content_sniffer_stream_sniff() does not.
+ */
+ while (stream) {
+ if (SOUP_IS_CONTENT_SNIFFER_STREAM (stream))
+ return SOUP_CONTENT_SNIFFER_STREAM (stream);
+ stream = G_FILTER_INPUT_STREAM (g_filter_input_stream_get_base_stream (stream));
+ }
+
+ g_assert_not_reached ();
+ return NULL;
+}
+
gboolean
soup_message_try_sniff_content (SoupMessage *msg,
GInputStream *stream,
@@ -2902,7 +2919,7 @@ soup_message_try_sniff_content (SoupMessage *msg,
if (!priv->sniffer)
return TRUE;
- sniffer_stream = SOUP_CONTENT_SNIFFER_STREAM (stream);
+ sniffer_stream = soup_content_sniffer_stream_from_stream (G_FILTER_INPUT_STREAM (stream));
if (!soup_content_sniffer_stream_is_ready (sniffer_stream, blocking, cancellable, error))
return FALSE;
diff --git a/tests/logger-test.c b/tests/logger-test.c
index b5d2f27b..16a3fad9 100644
--- a/tests/logger-test.c
+++ b/tests/logger-test.c
@@ -481,6 +481,41 @@ server_callback (SoupServer *server,
sizeof (body_data) - 1);
}
+static void
+do_logger_with_sniffer_test (void)
+{
+ SoupSession *session;
+ SoupLogger *logger;
+ SoupMessage *msg;
+ LogData log = { NULL, NULL, NULL, NULL };
+ GBytes *response;
+
+ session = soup_test_session_new (NULL);
+ logger = soup_logger_new (SOUP_LOGGER_LOG_BODY);
+ soup_logger_set_printer (logger, (SoupLoggerPrinter)printer, &log, NULL);
+ soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
+ g_object_unref (logger);
+
+ soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_SNIFFER);
+
+ msg = soup_message_new_from_uri ("GET", base_uri);
+ response = soup_test_session_async_send (session, msg, NULL, NULL);
+ g_object_unref (msg);
+ g_bytes_unref (response);
+
+ g_assert_nonnull (log.request);
+ g_assert_null (log.request_body);
+ g_assert_nonnull (log.response);
+ g_assert_nonnull (log.response_body);
+ g_assert_cmpmem (log.response_body->data,
+ log.response_body->len,
+ body_data, sizeof (body_data) - 1);
+
+ log_data_clear (&log);
+
+ soup_test_session_abort_unref (session);
+}
+
int
main (int argc, char **argv)
{
@@ -499,6 +534,7 @@ main (int argc, char **argv)
g_test_add_func ("/logger/filters", do_logger_filters_test);
g_test_add_func ("/logger/cookies", do_logger_cookies_test);
g_test_add_func ("/logger/preconnect", do_logger_preconnect_test);
+ g_test_add_func ("/logger/with-sniffer", do_logger_with_sniffer_test);
ret = g_test_run ();