[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. v0.9.19-587-g179b291

Colin Guthrie gitmailer-noreply at 0pointer.de
Thu Oct 14 12:51:22 PDT 2010


This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.

The master branch has been updated
      from  4d84a00b495c44a9e348534bf754ace823c9abe8 (commit)

- Log -----------------------------------------------------------------
179b291 volume: Decrease PA_VOLUME_MAX to be < 2^31
3265424 pactl: Validate volume before setting
0edbb2c cli: Validate volume before setting
49101fc volume: Clamp volume to PA_VOLUME_MAX
1d2ef79 volume: Use a macro to check if a volume is valid
-----------------------------------------------------------------------

Summary of changes:
 src/modules/dbus/iface-core.c       |    2 +-
 src/modules/dbus/iface-device.c     |    2 +-
 src/modules/dbus/iface-sample.c     |    4 +-
 src/modules/dbus/iface-stream.c     |    2 +-
 src/modules/module-lirc.c           |    6 ++--
 src/modules/module-match.c          |    2 +-
 src/modules/module-mmkbd-evdev.c    |    4 +-
 src/modules/module-stream-restore.c |    2 +-
 src/modules/module-waveout.c        |    4 +-
 src/modules/oss/oss-util.c          |    4 +-
 src/pulse/scache.c                  |    4 +-
 src/pulse/volume.c                  |   54 ++++++++++++++++++-----------------
 src/pulse/volume.h                  |    8 ++++-
 src/pulsecore/cli-command.c         |   15 +++++++++
 src/pulsecore/core-scache.c         |    4 +-
 src/utils/pactl.c                   |   15 +++++++++
 16 files changed, 85 insertions(+), 47 deletions(-)

-----------------------------------------------------------------------

commit 1d2ef7923d28a74e08a4309b6fa3d36481d2df3b
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Sat Oct 9 22:30:20 2010 +0530

    volume: Use a macro to check if a volume is valid
    
    This adds a PA_VOLUME_IS_VALID() macro for checking if a given
    pa_volume_t is valid. This makes changes to the volume ranges simpler
    (just change PA_VOLUME_MAX, for example, without needing to modify any
    other code).

diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index e7c00a7..268a87e 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -1310,7 +1310,7 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u
     }
 
     for (i = 0; i < n_volume_entries; ++i) {
-        if (default_volume[i] > PA_VOLUME_MAX) {
+        if (!PA_VOLUME_IS_VALID(default_volume[i])) {
             pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u.", default_volume[i]);
             goto finish;
         }
diff --git a/src/modules/dbus/iface-device.c b/src/modules/dbus/iface-device.c
index bb91d71..a8652df 100644
--- a/src/modules/dbus/iface-device.c
+++ b/src/modules/dbus/iface-device.c
@@ -438,7 +438,7 @@ static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessag
     }
 
     for (i = 0; i < n_volume_entries; ++i) {
-        if (volume[i] > PA_VOLUME_MAX) {
+        if (!PA_VOLUME_IS_VALID(volume[i])) {
             pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too large volume value: %u", volume[i]);
             return;
         }
diff --git a/src/modules/dbus/iface-sample.c b/src/modules/dbus/iface-sample.c
index c1fa193..2381079 100644
--- a/src/modules/dbus/iface-sample.c
+++ b/src/modules/dbus/iface-sample.c
@@ -366,7 +366,7 @@ static void handle_play(DBusConnection *conn, DBusMessage *msg, void *userdata)
     if (!(property_list = pa_dbus_get_proplist_arg(conn, msg, &msg_iter)))
         return;
 
-    if (volume > PA_VOLUME_MAX) {
+    if (PA_VOLUME_IS_VALID(volume)) {
         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume.");
         goto finish;
     }
@@ -416,7 +416,7 @@ static void handle_play_to_sink(DBusConnection *conn, DBusMessage *msg, void *us
         goto finish;
     }
 
-    if (volume > PA_VOLUME_MAX) {
+    if (PA_VOLUME_IS_VALID(volume)) {
         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume.");
         goto finish;
     }
diff --git a/src/modules/dbus/iface-stream.c b/src/modules/dbus/iface-stream.c
index 0255be4..364572b 100644
--- a/src/modules/dbus/iface-stream.c
+++ b/src/modules/dbus/iface-stream.c
@@ -378,7 +378,7 @@ static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessag
     }
 
     for (i = 0; i < n_volume_entries; ++i) {
-        if (volume[i] > PA_VOLUME_MAX) {
+        if (PA_VOLUME_IS_VALID(volume[i])) {
             pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too large volume value: %u", volume[i]);
             return;
         }
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 346b6ad..5ce1c41 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -367,7 +367,7 @@ static int get_volume_arg(DBusConnection *conn, DBusMessage *msg, DBusMessageIte
         pa_assert_se(dbus_message_iter_next(&struct_iter));
         dbus_message_iter_get_basic(&struct_iter, &chan_vol);
 
-        if (chan_vol > PA_VOLUME_MAX) {
+        if (PA_VOLUME_IS_VALID(chan_vol)) {
             pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u", chan_vol);
             return -1;
         }
diff --git a/src/pulse/scache.c b/src/pulse/scache.c
index b2169b6..cb8d7c5 100644
--- a/src/pulse/scache.c
+++ b/src/pulse/scache.c
@@ -191,7 +191,7 @@ pa_operation *pa_context_play_sample(pa_context *c, const char *name, const char
     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
     pa_tagstruct_puts(t, dev);
 
-    if (volume == PA_VOLUME_INVALID && c->version < 15)
+    if (!PA_VOLUME_IS_VALID(volume) && c->version < 15)
         volume = PA_VOLUME_NORM;
 
     pa_tagstruct_putu32(t, volume);
@@ -232,7 +232,7 @@ pa_operation *pa_context_play_sample_with_proplist(pa_context *c, const char *na
     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
     pa_tagstruct_puts(t, dev);
 
-    if (volume == PA_VOLUME_INVALID && c->version < 15)
+    if (!PA_VOLUME_IS_VALID(volume) && c->version < 15)
         volume = PA_VOLUME_NORM;
 
     pa_tagstruct_putu32(t, volume);
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 59e9a18..7d4951b 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -201,8 +201,8 @@ pa_volume_t pa_cvolume_min_mask(const pa_cvolume *a, const pa_channel_map *cm, p
 
 pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
 
-    pa_return_val_if_fail(a != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
-    pa_return_val_if_fail(b != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(a), PA_VOLUME_INVALID);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), PA_VOLUME_INVALID);
 
     /* cbrt((a/PA_VOLUME_NORM)^3*(b/PA_VOLUME_NORM)^3)*PA_VOLUME_NORM = a*b/PA_VOLUME_NORM */
 
@@ -211,8 +211,8 @@ pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
 
 pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) {
 
-    pa_return_val_if_fail(a != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
-    pa_return_val_if_fail(b != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(a), PA_VOLUME_INVALID);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), PA_VOLUME_INVALID);
 
     if (b <= PA_VOLUME_MUTED)
         return 0;
@@ -238,7 +238,7 @@ pa_volume_t pa_sw_volume_from_dB(double dB) {
 
 double pa_sw_volume_to_dB(pa_volume_t v) {
 
-    pa_return_val_if_fail(v != PA_VOLUME_INVALID, PA_DECIBEL_MININFTY);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), PA_DECIBEL_MININFTY);
 
     if (v <= PA_VOLUME_MUTED)
         return PA_DECIBEL_MININFTY;
@@ -267,7 +267,7 @@ pa_volume_t pa_sw_volume_from_linear(double v) {
 double pa_sw_volume_to_linear(pa_volume_t v) {
     double f;
 
-    pa_return_val_if_fail(v != PA_VOLUME_INVALID, 0.0);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), 0.0);
 
     if (v <= PA_VOLUME_MUTED)
         return 0.0;
@@ -317,7 +317,7 @@ char *pa_volume_snprint(char *s, size_t l, pa_volume_t v) {
 
     pa_init_i18n();
 
-    if (v == PA_VOLUME_INVALID) {
+    if (!PA_VOLUME_IS_VALID(v)) {
         pa_snprintf(s, l, _("(invalid)"));
         return s;
     }
@@ -367,7 +367,7 @@ char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v) {
 
     pa_init_i18n();
 
-    if (v == PA_VOLUME_INVALID) {
+    if (!PA_VOLUME_IS_VALID(v)) {
         pa_snprintf(s, l, _("(invalid)"));
         return s;
     }
@@ -384,7 +384,7 @@ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) {
     pa_assert(a);
 
     pa_return_val_if_fail(pa_cvolume_valid(a), 0);
-    pa_return_val_if_fail(v != PA_VOLUME_INVALID, 0);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), 0);
 
     for (c = 0; c < a->channels; c++)
         if (a->values[c] != v)
@@ -418,7 +418,7 @@ pa_cvolume *pa_sw_cvolume_multiply_scalar(pa_cvolume *dest, const pa_cvolume *a,
     pa_assert(a);
 
     pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
-    pa_return_val_if_fail(b != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), NULL);
 
     for (i = 0; i < a->channels; i++)
         dest->values[i] = pa_sw_volume_multiply(a->values[i], b);
@@ -453,7 +453,7 @@ pa_cvolume *pa_sw_cvolume_divide_scalar(pa_cvolume *dest, const pa_cvolume *a, p
     pa_assert(a);
 
     pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
-    pa_return_val_if_fail(b != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), NULL);
 
     for (i = 0; i < a->channels; i++)
         dest->values[i] = pa_sw_volume_divide(a->values[i], b);
@@ -472,7 +472,7 @@ int pa_cvolume_valid(const pa_cvolume *v) {
         return 0;
 
     for (c = 0; c < v->channels; c++)
-        if (v->values[c] == PA_VOLUME_INVALID)
+        if (!PA_VOLUME_IS_VALID(v->values[c]))
             return 0;
 
     return 1;
@@ -686,7 +686,7 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) {
     pa_assert(v);
 
     pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
-    pa_return_val_if_fail(max != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(max), NULL);
 
     t = pa_cvolume_max(v);
 
@@ -705,7 +705,7 @@ pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map
 
     pa_assert(v);
 
-    pa_return_val_if_fail(max != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(max), NULL);
 
     if (!cm)
         return pa_cvolume_scale(v, max);
@@ -834,7 +834,7 @@ pa_cvolume* pa_cvolume_set_position(
 
     pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(cv, map), NULL);
     pa_return_val_if_fail(t < PA_CHANNEL_POSITION_MAX, NULL);
-    pa_return_val_if_fail(v != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), NULL);
 
     for (c = 0; c < map->channels; c++)
         if (map->map[c] == t) {
@@ -891,7 +891,7 @@ pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t lim
     pa_assert(v);
 
     pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
-    pa_return_val_if_fail(inc != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(inc), NULL);
 
     m = pa_cvolume_max(v);
 
@@ -913,7 +913,7 @@ pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
     pa_assert(v);
 
     pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
-    pa_return_val_if_fail(dec != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(dec), NULL);
 
     m = pa_cvolume_max(v);
 
diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index 594cf91..9ef26f1 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -118,6 +118,9 @@ typedef uint32_t pa_volume_t;
 /** Special 'invalid' volume. \since 0.9.16 */
 #define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX)
 
+/** Check if volume is valid. \since 0.9.22 */
+#define PA_VOLUME_IS_VALID(v) ((v) <= PA_VOLUME_MAX)
+
 /** A structure encapsulating a per-channel volume */
 typedef struct pa_cvolume {
     uint8_t channels;                     /**< Number of channels */
diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c
index 0172419..cd388ef 100644
--- a/src/pulsecore/core-scache.c
+++ b/src/pulsecore/core-scache.c
@@ -336,12 +336,12 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
 
     pass_volume = TRUE;
 
-    if (e->volume_is_set && volume != PA_VOLUME_INVALID) {
+    if (e->volume_is_set && !PA_VOLUME_IS_VALID(volume)) {
         pa_cvolume_set(&r, e->sample_spec.channels, volume);
         pa_sw_cvolume_multiply(&r, &r, &e->volume);
     } else if (e->volume_is_set)
         r = e->volume;
-    else if (volume != PA_VOLUME_INVALID)
+    else if (!PA_VOLUME_IS_VALID(volume))
         pa_cvolume_set(&r, e->sample_spec.channels, volume);
     else
         pass_volume = FALSE;

commit 49101fc540aec9a249e97a9f650be38f9f92f5ac
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Sat Oct 9 15:38:43 2010 +0530

    volume: Clamp volume to PA_VOLUME_MAX
    
    This ensures that we always clamp the volume to PA_VOLUME_MAX. While
    this currently has no effect, it will be required for making sure we
    don't exceed PA_VOLUME_MAX when its value changes in the future.

diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c
index e977862..15f3442 100644
--- a/src/modules/module-lirc.c
+++ b/src/modules/module-lirc.c
@@ -172,7 +172,7 @@ fail:
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
-    pa_volume_t volume_limit = PA_VOLUME_NORM*3/2;
+    pa_volume_t volume_limit = PA_CLAMP_VOLUME(PA_VOLUME_NORM*3/2);
     pa_volume_t volume_step = PA_VOLUME_NORM/20;
 
     pa_assert(m);
@@ -199,8 +199,8 @@ int pa__init(pa_module*m) {
     u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
     u->lirc_fd = -1;
     u->mute_toggle_save = 0;
-    u->volume_limit = volume_limit;
-    u->volume_step = volume_step;
+    u->volume_limit = PA_CLAMP_VOLUME(volume_limit);
+    u->volume_step = PA_CLAMP_VOLUME(volume_step);
 
     if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) {
         pa_log("lirc_init() failed.");
diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index b1693f1..d83c86c 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -127,7 +127,7 @@ static int load_rules(struct userdata *u, const char *filename) {
 
         *d = 0;
         if (pa_atou(v, &k) >= 0) {
-            volume = (pa_volume_t) k;
+            volume = (pa_volume_t) PA_CLAMP_VOLUME(k);
         } else if (*v == '"') {
             char *e;
 
diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c
index 193c1f4..4e89aed 100644
--- a/src/modules/module-mmkbd-evdev.c
+++ b/src/modules/module-mmkbd-evdev.c
@@ -188,8 +188,8 @@ int pa__init(pa_module*m) {
     u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
     u->fd = -1;
     u->fd_type = 0;
-    u->volume_limit = volume_limit;
-    u->volume_step = volume_step;
+    u->volume_limit = PA_CLAMP_VOLUME(volume_limit);
+    u->volume_step = PA_CLAMP_VOLUME(volume_step);
 
     if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) {
         pa_log("Failed to open evdev device: %s", pa_cstrerror(errno));
diff --git a/src/modules/module-waveout.c b/src/modules/module-waveout.c
index d1b9f2f..6fedceb 100644
--- a/src/modules/module-waveout.c
+++ b/src/modules/module-waveout.c
@@ -359,8 +359,8 @@ static int sink_get_hw_volume_cb(pa_sink *s) {
     if (waveOutGetVolume(u->hwo, &vol) != MMSYSERR_NOERROR)
         return -1;
 
-    left = (vol & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME;
-    right = ((vol >> 16) & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME;
+    left = PA_CLAMP_VOLUME((vol & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME);
+    right = PA_CLAMP_VOLUME(((vol >> 16) & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME);
 
     /* Windows supports > 2 channels, except for volume control */
     if (s->hw_volume.channels > 2)
diff --git a/src/modules/oss/oss-util.c b/src/modules/oss/oss-util.c
index b95023c..966a6ca 100644
--- a/src/modules/oss/oss-util.c
+++ b/src/modules/oss/oss-util.c
@@ -271,10 +271,10 @@ int pa_oss_get_volume(int fd, unsigned long mixer, const pa_sample_spec *ss, pa_
 
     pa_cvolume_reset(volume, ss->channels);
 
-    volume->values[0] = ((vol & 0xFF) * PA_VOLUME_NORM) / 100;
+    volume->values[0] = PA_CLAMP_VOLUME(((vol & 0xFF) * PA_VOLUME_NORM) / 100);
 
     if (volume->channels >= 2)
-        volume->values[1] = (((vol >> 8) & 0xFF) * PA_VOLUME_NORM) / 100;
+        volume->values[1] = PA_CLAMP_VOLUME((((vol >> 8) & 0xFF) * PA_VOLUME_NORM) / 100);
 
     pa_log_debug("Read mixer settings: %s", pa_cvolume_snprint(cv, sizeof(cv), volume));
     return 0;
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 7d4951b..f74d720 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -79,7 +79,9 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) {
     a->channels = (uint8_t) channels;
 
     for (i = 0; i < a->channels; i++)
-        a->values[i] = v;
+        /* Clamp in case there is stale data that exceeds the current
+         * PA_VOLUME_MAX */
+        a->values[i] = PA_CLAMP_VOLUME(v);
 
     return a;
 }
@@ -206,7 +208,7 @@ pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
 
     /* cbrt((a/PA_VOLUME_NORM)^3*(b/PA_VOLUME_NORM)^3)*PA_VOLUME_NORM = a*b/PA_VOLUME_NORM */
 
-    return (pa_volume_t) (((uint64_t) a * (uint64_t) b + (uint64_t) PA_VOLUME_NORM / 2ULL) / (uint64_t) PA_VOLUME_NORM);
+    return (pa_volume_t) PA_CLAMP_VOLUME((((uint64_t) a * (uint64_t) b + (uint64_t) PA_VOLUME_NORM / 2ULL) / (uint64_t) PA_VOLUME_NORM));
 }
 
 pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) {
@@ -261,7 +263,7 @@ pa_volume_t pa_sw_volume_from_linear(double v) {
      * same volume value! That's why we need the lround() below!
      */
 
-    return (pa_volume_t) lround(cbrt(v) * PA_VOLUME_NORM);
+    return (pa_volume_t) PA_CLAMP_VOLUME(lround(cbrt(v) * PA_VOLUME_NORM));
 }
 
 double pa_sw_volume_to_linear(pa_volume_t v) {
@@ -667,12 +669,12 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo
             if (left == 0)
                 v->values[c] = nleft;
             else
-                v->values[c] = (pa_volume_t) (((uint64_t) v->values[c] * (uint64_t) nleft) / (uint64_t) left);
+                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nleft) / (uint64_t) left);
         } else if (on_right(map->map[c])) {
             if (right == 0)
                 v->values[c] = nright;
             else
-                v->values[c] = (pa_volume_t) (((uint64_t) v->values[c] * (uint64_t) nright) / (uint64_t) right);
+                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nright) / (uint64_t) right);
         }
     }
 
@@ -694,7 +696,7 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) {
         return pa_cvolume_set(v, v->channels, max);
 
     for (c = 0; c < v->channels; c++)
-        v->values[c] = (pa_volume_t) (((uint64_t)  v->values[c] * (uint64_t) max) / (uint64_t) t);
+        v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) max) / (uint64_t) t);
 
     return v;
 }
@@ -718,7 +720,7 @@ pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map
         return pa_cvolume_set(v, v->channels, max);
 
     for (c = 0; c < v->channels; c++)
-        v->values[c] = (pa_volume_t) (((uint64_t)  v->values[c] * (uint64_t) max) / (uint64_t) t);
+        v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t)  v->values[c] * (uint64_t) max) / (uint64_t) t);
 
     return v;
 }
@@ -808,12 +810,12 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float
             if (front == 0)
                 v->values[c] = nfront;
             else
-                v->values[c] = (pa_volume_t) (((uint64_t) v->values[c] * (uint64_t) nfront) / (uint64_t) front);
+                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nfront) / (uint64_t) front);
         } else if (on_rear(map->map[c])) {
             if (rear == 0)
                 v->values[c] = nrear;
             else
-                v->values[c] = (pa_volume_t) (((uint64_t) v->values[c] * (uint64_t) nrear) / (uint64_t) rear);
+                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nrear) / (uint64_t) rear);
         }
     }
 
diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index 9ef26f1..2f71a62 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -121,6 +121,9 @@ typedef uint32_t pa_volume_t;
 /** Check if volume is valid. \since 0.9.22 */
 #define PA_VOLUME_IS_VALID(v) ((v) <= PA_VOLUME_MAX)
 
+/** Clamp volume to the permitted range. \since 0.9.22 */
+#define PA_CLAMP_VOLUME(v) (PA_CLAMP_UNLIKELY((v), PA_VOLUME_MUTED, PA_VOLUME_MAX))
+
 /** A structure encapsulating a per-channel volume */
 typedef struct pa_cvolume {
     uint8_t channels;                     /**< Number of channels */

commit 0edbb2c6aa28faf564d2929318ab21c872335f04
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Sat Oct 9 23:10:00 2010 +0530

    cli: Validate volume before setting
    
    This causes an error to be generated if an invalid volume is provided to
    commands that set sink/sink-input/source volume.

diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index d23331d..a18ebd3 100644
--- a/src/pulsecore/cli-command.c
+++ b/src/pulsecore/cli-command.c
@@ -527,6 +527,11 @@ static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *bu
         return -1;
     }
 
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_strbuf_puts(buf, "Volume outside permissible range.\n");
+        return -1;
+    }
+
     if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
         return -1;
@@ -569,6 +574,11 @@ static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strb
         return -1;
     }
 
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_strbuf_puts(buf, "Volume outside permissible range.\n");
+        return -1;
+    }
+
     if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
         pa_strbuf_puts(buf, "No sink input found with this index.\n");
         return -1;
@@ -605,6 +615,11 @@ static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *
         return -1;
     }
 
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_strbuf_puts(buf, "Volume outside permissible range.\n");
+        return -1;
+    }
+
     if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
         pa_strbuf_puts(buf, "No source found by this name or index.\n");
         return -1;

commit 3265424f271f15f334a299cc10086c0b9be34979
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Sat Oct 9 23:11:26 2010 +0530

    pactl: Validate volume before setting
    
    This makes sure that a valid volume is provided before setting on
    sink/sink-input/source.

diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index cae96f2..98c4d45 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -1248,6 +1248,11 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
+            if (!PA_VOLUME_IS_VALID(v)) {
+                pa_log(_("Volume outside permissible range.\n"));
+                goto quit;
+            }
+
             sink_name = pa_xstrdup(argv[optind+1]);
             volume = (pa_volume_t) v;
 
@@ -1265,6 +1270,11 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
+            if (!PA_VOLUME_IS_VALID(v)) {
+                pa_log(_("Volume outside permissible range.\n"));
+                goto quit;
+            }
+
             source_name = pa_xstrdup(argv[optind+1]);
             volume = (pa_volume_t) v;
 
@@ -1287,6 +1297,11 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
+            if (!PA_VOLUME_IS_VALID(v)) {
+                pa_log(_("Volume outside permissible range.\n"));
+                goto quit;
+            }
+
             volume = (pa_volume_t) v;
 
         } else if (pa_streq(argv[optind], "set-sink-mute")) {

commit 179b291b18b9a7366955948ce0ddfb2e65a6b66e
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Sat Oct 9 23:29:51 2010 +0530

    volume: Decrease PA_VOLUME_MAX to be < 2^31
    
    This decrease PA_VOLUME_MAX to be less than 2^31. We want to do this in
    order to simplify signed arithmetic when applying software volume
    scaling (since the volume can now always be safely treated as a signed
    number).

diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index 2f71a62..98bbac1 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -113,7 +113,7 @@ typedef uint32_t pa_volume_t;
 #define PA_VOLUME_MUTED ((pa_volume_t) 0U)
 
 /** Maximum valid volume we can store. \since 0.9.15 */
-#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX-1)
+#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX/2)
 
 /** Special 'invalid' volume. \since 0.9.16 */
 #define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX)

-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list