Skip to contentSkip to conversation

fix bug 5579: invalid long long format specifier

PATCH In review John Spencer 3 participants 4 messages Apr 24, 2012 – Apr 25, 2012

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fix bug 5579: invalid long long format specifier

the attached patch fixes an invalid long long format specifier issue (%L was used by mistake, which is the long double specifier). this lead to abort() on 64bit system, making some of the alsa-utils unusable.

--JS

Quoted 1 line

From 63fe3fa4765c423ef6904a4506e4ed74908ecfb6 Mon Sep 17 00:00:00 2001

From: John Spencer <[email protected]>
Date: Tue, 24 Apr 2012 12:41:27 +0200
Subject: [PATCH] fix bug 5579: invalid long long format specifier

Per POSIX:

L Specifies that a following a, A, e, E, f, F, g, or G conversion
specifier applies to a long double argument.

L is only intended to be used with long doubles, not long long ints.

the proper way is to use "ll" instead.

---
 src/conf.c      |    6 +++---
 test/midiloop.c |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)
src/conf.c +3 -3
index 5b1b5a6..32446a2 100644
@@ -496,7 +496,7 @@ static int safe_strtoll(const char *str, long long *val)
 	if (!*str)
 		return -EINVAL;
 	errno = 0;
-	if (sscanf(str, "%Li%n", &v, &endidx) < 1)
+	if (sscanf(str, "%lli%n", &v, &endidx) < 1)
 		return -EINVAL;
 	if (str[endidx])
 		return -EINVAL;
@@ -1378,7 +1378,7 @@ static int _snd_config_save_node_value(snd_config_t *n, snd_output_t *out,
 		snd_output_printf(out, "%ld", n->u.integer);
 		break;
 	case SND_CONFIG_TYPE_INTEGER64:
-		snd_output_printf(out, "%Ld", n->u.integer64);
+		snd_output_printf(out, "%lld", n->u.integer64);
 		break;
 	case SND_CONFIG_TYPE_REAL:
 		snd_output_printf(out, "%-16g", n->u.real);
@@ -2630,7 +2630,7 @@ int snd_config_get_ascii(const snd_config_t *config, char **ascii)
 		{
 			char res[32];
 			int err;
-			err = snprintf(res, sizeof(res), "%Li", config->u.integer64);
+			err = snprintf(res, sizeof(res), "%lli", config->u.integer64);
 			if (err < 0 || err == sizeof(res)) {
 				assert(0);
 				return -ENOMEM;
test/midiloop.c +1 -1
index ee2e563..d6548b5 100644
@@ -175,7 +175,7 @@ int main(int argc, char** argv)
 	printf("output.status.xruns = %zi\n", snd_rawmidi_status_get_xruns(ostat));
 
 	diff = timediff(end, start);
-	printf("Time diff: %Liusec (%Li bytes/sec)\n", diff, ((long long)opos * 1000000) / diff);
+	printf("Time diff: %lliusec (%lli bytes/sec)\n", diff, ((long long)opos * 1000000) / diff);
 
 	if (verbose) {
 		fprintf(stderr,"Closing\n");
Signature · 1 line
1.7.3.4
#1 lore raw

At Tue, 24 Apr 2012 12:58:48 +0200,

Quoted 5 lines · John Spencer

the attached patch fixes an invalid long long format specifier issue (%L was used by mistake, which is the long double specifier). this lead to abort() on 64bit system, making some of the alsa-utils unusable.

Applied now. Thanks.

Takashi

Quoted 75 lines

--JS
[2 0001-fix-bug-5579-invalid-long-long-format-specifier.patch <text/x-patch (7bit)>]

Quoted 1 line

From 63fe3fa4765c423ef6904a4506e4ed74908ecfb6 Mon Sep 17 00:00:00 2001

From: John Spencer <[email protected]>
Date: Tue, 24 Apr 2012 12:41:27 +0200
Subject: [PATCH] fix bug 5579: invalid long long format specifier

Per POSIX:

L Specifies that a following a, A, e, E, f, F, g, or G conversion
specifier applies to a long double argument.

L is only intended to be used with long doubles, not long long ints.

the proper way is to use "ll" instead.

---
 src/conf.c      |    6 +++---
 test/midiloop.c |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)
src/conf.c +3 -3
index 5b1b5a6..32446a2 100644
@@ -496,7 +496,7 @@ static int safe_strtoll(const char *str, long long *val)
 	if (!*str)
 		return -EINVAL;
 	errno = 0;
-	if (sscanf(str, "%Li%n", &v, &endidx) < 1)
+	if (sscanf(str, "%lli%n", &v, &endidx) < 1)
 		return -EINVAL;
 	if (str[endidx])
 		return -EINVAL;
@@ -1378,7 +1378,7 @@ static int _snd_config_save_node_value(snd_config_t *n, snd_output_t *out,
 		snd_output_printf(out, "%ld", n->u.integer);
 		break;
 	case SND_CONFIG_TYPE_INTEGER64:
-		snd_output_printf(out, "%Ld", n->u.integer64);
+		snd_output_printf(out, "%lld", n->u.integer64);
 		break;
 	case SND_CONFIG_TYPE_REAL:
 		snd_output_printf(out, "%-16g", n->u.real);
@@ -2630,7 +2630,7 @@ int snd_config_get_ascii(const snd_config_t *config, char **ascii)
 		{
 			char res[32];
 			int err;
-			err = snprintf(res, sizeof(res), "%Li", config->u.integer64);
+			err = snprintf(res, sizeof(res), "%lli", config->u.integer64);
 			if (err < 0 || err == sizeof(res)) {
 				assert(0);
 				return -ENOMEM;
test/midiloop.c +1 -1
index ee2e563..d6548b5 100644
@@ -175,7 +175,7 @@ int main(int argc, char** argv)
 	printf("output.status.xruns = %zi\n", snd_rawmidi_status_get_xruns(ostat));
 
 	diff = timediff(end, start);
-	printf("Time diff: %Liusec (%Li bytes/sec)\n", diff, ((long long)opos * 1000000) / diff);
+	printf("Time diff: %lliusec (%lli bytes/sec)\n", diff, ((long long)opos * 1000000) / diff);
 
 	if (verbose) {
 		fprintf(stderr,"Closing\n");
Signature · 7 lines
1.7.3.4

[3  <text/plain; us-ascii (7bit)>]
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
#2 lore raw
In reply to John Spencer
Quoted 4 lines · John Spencer

the attached patch fixes an invalid long long format specifier issue (%L was used by mistake, which is the long double specifier). this lead to abort() on 64bit system, making some of the alsa-utils unusable.

Thanks very much for this patch! I'm trying to access the bug tracker but it seems to be down - could you explain a little where and how this bug manifests itself, if you have any good test case etc?

Signature · 2 lines
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
#3 lore raw
Quoted 10 lines · David Henningsson
Quoted 4 lines · John Spencer

the attached patch fixes an invalid long long format specifier issue (%L was used by mistake, which is the long double specifier). this lead to abort() on 64bit system, making some of the alsa-utils unusable.

Thanks very much for this patch! I'm trying to access the bug tracker but it seems to be down - could you explain a little where and how this bug manifests itself, if you have any good test case etc?

it manifests itself when a POSIX compliant C library is used (i.e. not glibc).
musl libc's snprintf will return an error by detecting the invalid combination %Li

err = snprintf(res, sizeof(res), "%Li", config->u.integer64);

thus the following code is triggered

  			if (err<  0 || err == sizeof(res)) {
  				assert(0);
  				return -ENOMEM;

however, depending on how stdarg is implemented, a buggy implementation could eventually try to load a double from the floating point stack, instead of using the stack/integer registers, thus causing a crash, which would be even worse.