diff mbox series

[U-Boot,4/5] cmd: bcb: Use strcmp() instead of strncmp() for string literals

Message ID 20190712112059.25558-5-erosca@de.adit-jv.com
State Superseded
Delegated to: Tom Rini
Headers show
Series Fixes and improvements in BCB and Android docs | expand

Commit Message

Eugeniu Rosca July 12, 2019, 11:20 a.m. UTC
Quote from https://patchwork.ozlabs.org/patch/1104244/#2210814:

 ----------8<-----------
strncmp() is chosen for the sake of paranoid/defensive programming.
Indeed, strncmp() is not really needed when comparing a variable
with a string literal. We expect strcmp() to behave safely even if the
string variable is not NUL-terminated.

In the same scenario, Linux v5.2-rc7 uses both strcmp() and strncmp(),
but the frequency of strcmp() is higher:

$ git --version
git version 2.22.0
$ (Linux 5.2-rc7) git grep -En 'strncmp\([^"]*"[[:alnum:]]+"' | wc -l
1066
$ (Linux 5.2-rc7) git grep -En 'strcmp\([^"]*"[[:alnum:]]+"' | wc -l
1968

A quick "strcmp vs strncmp" object size test shows that strcmp()
generates smaller memory footprint (gcc-8, x86_64):

$ (U-Boot) size cmd/bcb-strncmp.o cmd/bcb-strcmp.o
   text	   data	    bss	    dec	    hex	filename
   3373	    400	   2048	   5821	   16bd	cmd/bcb-strncmp.o
   3314	    400	   2048	   5762	   1682	cmd/bcb-strcmp.o

So, overall, I agree to use strcmp() whenever variables are compared
with string literals.
 ----------8<-----------

Fixes: db7b7a05b267 ("cmd: Add 'bcb' command to read/modify/write BCB fields")
Reported-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
---
 cmd/bcb.c | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

Comments

Igor Opaniuk July 12, 2019, 11:54 a.m. UTC | #1
Hi Eugeniu,

On Fri, Jul 12, 2019 at 2:21 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote:
>
> Quote from https://patchwork.ozlabs.org/patch/1104244/#2210814:
>
>  ----------8<-----------
> strncmp() is chosen for the sake of paranoid/defensive programming.
> Indeed, strncmp() is not really needed when comparing a variable
> with a string literal. We expect strcmp() to behave safely even if the
> string variable is not NUL-terminated.
>
> In the same scenario, Linux v5.2-rc7 uses both strcmp() and strncmp(),
> but the frequency of strcmp() is higher:
>
> $ git --version
> git version 2.22.0
> $ (Linux 5.2-rc7) git grep -En 'strncmp\([^"]*"[[:alnum:]]+"' | wc -l
> 1066
> $ (Linux 5.2-rc7) git grep -En 'strcmp\([^"]*"[[:alnum:]]+"' | wc -l
> 1968
>
> A quick "strcmp vs strncmp" object size test shows that strcmp()
> generates smaller memory footprint (gcc-8, x86_64):
>
> $ (U-Boot) size cmd/bcb-strncmp.o cmd/bcb-strcmp.o
>    text    data     bss     dec     hex filename
>    3373     400    2048    5821    16bd cmd/bcb-strncmp.o
>    3314     400    2048    5762    1682 cmd/bcb-strcmp.o
>
> So, overall, I agree to use strcmp() whenever variables are compared
> with string literals.
>  ----------8<-----------
>
> Fixes: db7b7a05b267 ("cmd: Add 'bcb' command to read/modify/write BCB fields")
> Reported-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
> ---
>  cmd/bcb.c | 42 +++++++++++++++++++++---------------------
>  1 file changed, 21 insertions(+), 21 deletions(-)
>
> diff --git a/cmd/bcb.c b/cmd/bcb.c
> index 3b1c7434e287..c7138a5179a9 100644
> --- a/cmd/bcb.c
> +++ b/cmd/bcb.c
> @@ -24,17 +24,17 @@ static struct bootloader_message bcb = { { 0 } };
>
>  static int bcb_cmd_get(char *cmd)
>  {
> -       if (!strncmp(cmd, "load", sizeof("load")))
> +       if (!strcmp(cmd, "load"))
>                 return BCB_CMD_LOAD;
> -       if (!strncmp(cmd, "set", sizeof("set")))
> +       if (!strcmp(cmd, "set"))
>                 return BCB_CMD_FIELD_SET;
> -       if (!strncmp(cmd, "clear", sizeof("clear")))
> +       if (!strcmp(cmd, "clear"))
>                 return BCB_CMD_FIELD_CLEAR;
> -       if (!strncmp(cmd, "test", sizeof("test")))
> +       if (!strcmp(cmd, "test"))
>                 return BCB_CMD_FIELD_TEST;
> -       if (!strncmp(cmd, "store", sizeof("store")))
> +       if (!strcmp(cmd, "store"))
>                 return BCB_CMD_STORE;
> -       if (!strncmp(cmd, "dump", sizeof("dump")))
> +       if (!strcmp(cmd, "dump"))
>                 return BCB_CMD_FIELD_DUMP;
>         else
>                 return -1;
> @@ -85,21 +85,21 @@ err:
>
>  static int bcb_field_get(char *name, char **field, int *size)
>  {
> -       if (!strncmp(name, "command", sizeof("command"))) {
> -               *field = bcb.command;
> -               *size = sizeof(bcb.command);
> -       } else if (!strncmp(name, "status", sizeof("status"))) {
> -               *field = bcb.status;
> -               *size = sizeof(bcb.status);
> -       } else if (!strncmp(name, "recovery", sizeof("recovery"))) {
> -               *field = bcb.recovery;
> -               *size = sizeof(bcb.recovery);
> -       } else if (!strncmp(name, "stage", sizeof("stage"))) {
> -               *field = bcb.stage;
> -               *size = sizeof(bcb.stage);
> -       } else if (!strncmp(name, "reserved", sizeof("reserved"))) {
> -               *field = bcb.reserved;
> -               *size = sizeof(bcb.reserved);
> +       if (!strcmp(name, "command")) {
> +               *fieldp = bcb.command;
> +               *sizep = sizeof(bcb.command);
> +       } else if (!strcmp(name, "status")) {
> +               *fieldp = bcb.status;
> +               *sizep = sizeof(bcb.status);
> +       } else if (!strcmp(name, "recovery")) {
> +               *fieldp = bcb.recovery;
> +               *sizep = sizeof(bcb.recovery);
> +       } else if (!strcmp(name, "stage")) {
> +               *fieldp = bcb.stage;
> +               *sizep = sizeof(bcb.stage);
> +       } else if (!strcmp(name, "reserved")) {
> +               *fieldp = bcb.reserved;
> +               *sizep = sizeof(bcb.reserved);
>         } else {
>                 printf("Error: Unknown bcb field '%s'\n", name);
>                 return -1;
> --
> 2.22.0
>

Reviewed-by: Igor Opaniuk <igor.opaniuk@gmail.com>
Eugeniu Rosca July 12, 2019, 12:03 p.m. UTC | #2
Hi Igor,

On Fri, Jul 12, 2019 at 02:54:19PM +0300, Igor Opaniuk wrote:
> >  static int bcb_field_get(char *name, char **field, int *size)
> >  {
> > -       if (!strncmp(name, "command", sizeof("command"))) {
> > -               *field = bcb.command;
> > +       if (!strcmp(name, "command")) {
> > +               *fieldp = bcb.command;

Many thanks for the recent reviews!

There is a small issue committed by my autopilot, i.e. I didn't do the
best partitioning of the patches, such that they could provoke a build
breakage during git bisecting (see the intermixed usage of field and
fieldp variables above). I will fix it in v2, adding your Reviewed-by
in the other patches.

Thanks again!
Eugeniu Rosca July 13, 2019, 8:43 a.m. UTC | #3
Superseded by https://patchwork.ozlabs.org/patch/1131358/
("[v2,4/5] cmd: bcb: Use strcmp() instead of strncmp() for string literals")
diff mbox series

Patch

diff --git a/cmd/bcb.c b/cmd/bcb.c
index 3b1c7434e287..c7138a5179a9 100644
--- a/cmd/bcb.c
+++ b/cmd/bcb.c
@@ -24,17 +24,17 @@  static struct bootloader_message bcb = { { 0 } };
 
 static int bcb_cmd_get(char *cmd)
 {
-	if (!strncmp(cmd, "load", sizeof("load")))
+	if (!strcmp(cmd, "load"))
 		return BCB_CMD_LOAD;
-	if (!strncmp(cmd, "set", sizeof("set")))
+	if (!strcmp(cmd, "set"))
 		return BCB_CMD_FIELD_SET;
-	if (!strncmp(cmd, "clear", sizeof("clear")))
+	if (!strcmp(cmd, "clear"))
 		return BCB_CMD_FIELD_CLEAR;
-	if (!strncmp(cmd, "test", sizeof("test")))
+	if (!strcmp(cmd, "test"))
 		return BCB_CMD_FIELD_TEST;
-	if (!strncmp(cmd, "store", sizeof("store")))
+	if (!strcmp(cmd, "store"))
 		return BCB_CMD_STORE;
-	if (!strncmp(cmd, "dump", sizeof("dump")))
+	if (!strcmp(cmd, "dump"))
 		return BCB_CMD_FIELD_DUMP;
 	else
 		return -1;
@@ -85,21 +85,21 @@  err:
 
 static int bcb_field_get(char *name, char **field, int *size)
 {
-	if (!strncmp(name, "command", sizeof("command"))) {
-		*field = bcb.command;
-		*size = sizeof(bcb.command);
-	} else if (!strncmp(name, "status", sizeof("status"))) {
-		*field = bcb.status;
-		*size = sizeof(bcb.status);
-	} else if (!strncmp(name, "recovery", sizeof("recovery"))) {
-		*field = bcb.recovery;
-		*size = sizeof(bcb.recovery);
-	} else if (!strncmp(name, "stage", sizeof("stage"))) {
-		*field = bcb.stage;
-		*size = sizeof(bcb.stage);
-	} else if (!strncmp(name, "reserved", sizeof("reserved"))) {
-		*field = bcb.reserved;
-		*size = sizeof(bcb.reserved);
+	if (!strcmp(name, "command")) {
+		*fieldp = bcb.command;
+		*sizep = sizeof(bcb.command);
+	} else if (!strcmp(name, "status")) {
+		*fieldp = bcb.status;
+		*sizep = sizeof(bcb.status);
+	} else if (!strcmp(name, "recovery")) {
+		*fieldp = bcb.recovery;
+		*sizep = sizeof(bcb.recovery);
+	} else if (!strcmp(name, "stage")) {
+		*fieldp = bcb.stage;
+		*sizep = sizeof(bcb.stage);
+	} else if (!strcmp(name, "reserved")) {
+		*fieldp = bcb.reserved;
+		*sizep = sizeof(bcb.reserved);
 	} else {
 		printf("Error: Unknown bcb field '%s'\n", name);
 		return -1;