Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pr/improve option handling #557

Open
wants to merge 14 commits into
base: 3.6.x
Choose a base branch
from

Conversation

uli42
Copy link
Member

@uli42 uli42 commented Nov 19, 2017

some improvements for Args.c

@uli42 uli42 requested a review from Ionic November 19, 2017 01:35
@uli42 uli42 force-pushed the pr/improve_option_handling branch from 561c93e to 66db29c Compare November 19, 2017 13:15
Copy link
Member

@sunweaver sunweaver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uil42: I left some comments on PR #557. Please amend. Thanks!

{
fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n");
FatalError("malloc failed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be good to mention what we tried to malloc here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, maybe. But if you happen to suffer from malloc failing you have other problems... ;-) Will extend these messages anyway.

{
envOptions = strcpy(envOptions, envDisplay);
FatalError("malloc failed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

{
fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n");
FatalError("malloc failed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

return 2;
} else {
FatalError("malloc failed");
FatalError("malloc failed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

@@ -758,16 +723,13 @@ int ddxProcessArgument(int argc, char *argv[], int i)
nxagentKeyboard = NULL;
}

/* FIXME: why limit to 256? */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably some comand line length limitation adopted here?

@@ -1351,7 +1351,7 @@ static void nxagentParseOptions(char *name, char *value)
errno = 0;
sleep_parse = strtol(value, NULL, 10);

if ((errno) && (0 == sleep_parse))
if ((errno) && (sleep_parse == 0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ionic: I noticed these comparisons, too, when you worked on the sleep and tolerance feature. Any reason for having the order == ?

Copy link
Member Author

@uli42 uli42 Nov 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a coding habit that prevents accidently writing = instead of ==. The compiler will complain if you try to assign a value to a constant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly for this reason. It's a pretty common pattern to avoid mistakes (and I'd like to keep that part.)

@@ -355,7 +355,7 @@ int ddxProcessArgument(int argc, char *argv[], int i)
/* FIXME: why limit 10 1024 bytes? */
if ((size = strlen(argv[i])) < 1024)
{
if ((nxagentOptionsFilename = strndup(argv[i], size)) == NULL;
if ((nxagentOptionsFilename = strndup(argv[i], size)) == NULL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the semicolon at the line end feels wrong. Also: please rebase with the previous commit that you try to fix with this commit.

@uli42
Copy link
Member Author

uli42 commented Nov 20, 2017

I also noticed I still have some fixup commits in there. New version to come soon ;-)

@uli42 uli42 force-pushed the pr/improve_option_handling branch 4 times, most recently from 836225d to 320f413 Compare November 20, 2017 23:49
@uli42
Copy link
Member Author

uli42 commented Nov 21, 2017

Ready for another round. I have added some more changes, so please start over again.

@uli42 uli42 force-pushed the pr/improve_option_handling branch from 320f413 to 5d022f7 Compare November 21, 2017 21:34
@uli42
Copy link
Member Author

uli42 commented Nov 21, 2017

rebased

/*
* This is the entry point, called from os/utils.c
*/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd drop the newline here and in the next hunk.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


if (nxagentOptionsFilenameOrString != NULL)
free(nxagentOptionsFilenameOrString);
if ((nxagentOptionsFilenameOrString = strdup(argv[j + 1])) == NULL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's more compact, but potentially also slower. We probably don't really care since this code will be only called "once". (Actually multiple times, but only once during the program's lifetime.) Just mentioning it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Speed was not an issue here. I just wanted to simplify the code to make it more readable.

free(envOptions);
}

for (j = 0; j < argc; j++)
{
/*
* Read the _last_ options file only and only at startup.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks compatibility. Previously, only the first options file was used, now it's the last one. Is that a good idea? At least it would make nxagent more compatible with other tools, since most programs allow users to override values for previous parameters by specifying them again with only the last one taking effect.

To be precise: it may look like it's compatible to the previous behavior, but it isn't. Previously, the code scanned for -option(s) and took the first match, then parsed it as an options file. Afterwards, subsequent uses of ddxProcessArgument() overrode the internal nxagentOptionFile (or nowadays nxagentOptionsFilenameOrString) variable. That's an important difference because it allows for a very special combination:

  • start up nxagent with a special options file (first -option(s) argument)
  • override it again via subsequent -option(s) arguments, which will only change the internal data, but NOT lead to immediate parsing
  • on reconnects ONLY parse the newly registered options file

With your changes, that would not be possible.

I wonder if that behavior is a bug or a feature (i.e., whether this was intended or just an unintentional feature).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making it behave like most other tools was the intention of my change.

You are also right about changing the options file name for reconnect (only). But consider this an unintended behaviour. The whole options parsing code is very ugly anyway... Besides: that is not documented anywhere, AFAIKS.


nxagentDisplayName[1023] = '\0';

strncpy(nxagentDisplayName, argv[i], sizeof(nxagentDisplayName) - 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will cause hard to debug problems if we ever decide to change nxagentDisplayName to a pure pointer instead of an array. The alternatives are either hardcoding a value (like previously), or using a length macro. Both aren't very nice, but I guess the latter is the safest and best-looking route.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(changing those array to pointers is on my list already)

Well, if we change nxagentDisplayName to be a pointer using a hardcoded value will also be wrong. So the situation does not get worse with my change. It only makes it easier to change that hardcoded value because it is now at only one location.

Besides, all this nullbyte stuffing will be gone once we are using pointers. We can even get rid of it now by using s(n)printf() instead of str(n)cpy().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if we change nxagentDisplayName to be a pointer using a hardcoded value will also be wrong. So the situation does not get worse with my change. It only makes it easier to change that hardcoded value because it is now at only one location.

Yes, that's why I recommend using a macro defining each length, e.g., NXAGENTDISPLAYNAME_LENGTH = ... in the header file and using that throughout the code instead of a hardcoded value.

Even if we change the variables to pure pointers, the situation wouldn't really change. We probably should bound the data length with pure pointers as well. Otherwise, str(n)cpy will crash on invalid input data. With bounding, we will in the worst case get LEN-1 bytes of garbage data, but no actual crashes.

sizeof(ptr) doesn't work for pure pointers, so we'd have to change these sections again anyway.

I agree that dropping the hardcoded numbers is a good idea, but IMHO the best way (also taking into account further changes to pure pointers) is to use macros instead.


*(nxagentSessionId + 255) = '\0';

strncpy(nxagentSessionId, argv[i], sizeof(nxagentSessionId) - 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

return 1;
}

if (!strcmp(argv[i], "-keystrokefile"))
{
if (i + 1 < argc)
{
if (NULL != (nxagentKeystrokeFile = strdup(argv[i + 1])))
if ((nxagentKeystrokeFile = strdup(argv[i + 1])) == NULL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd keep that as NULL == ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fully get you point here, but I want to keep the code uniform within a file. And the rest of the code has the constant at the right side. The Xorg code is also using this technique.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welll... okay.

Personally, I'll be keeping this style for new submissions, particularly since it's just a cosmetic issue and provides a potential benefit.

I totally respect your decision, though. It's fine.

@@ -1435,31 +1311,30 @@ static void nxagentParseOptions(char *name, char *value)
errno = 0;
tolerance_parse = strtol(value, NULL, 10);

if ((errno) && (0 == tolerance_parse))
if ((errno) && (tolerance_parse == 0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here.

strncpy(nxagentWindowName, "NX", 255);

*(nxagentWindowName + 255) = '\0';
strncpy(nxagentWindowName, "NX", sizeof(nxagentWindowName) - 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here as some hunks above.

@@ -2144,29 +2002,29 @@ static int nxagentGetDialogName()
{
strcpy(nxagentDialogName, "NX");

*(nxagentDialogName + 255) = '\0';
nxagentDialogName[sizeof(nxagentDialogName) - 1] = '\0';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same problem as some hunks above.

{
strncat(nxagentDialogName, nxagentSessionId, length - (MD5_LENGTH * 2 + 1));
strncat(nxagentDialogName, nxagentSessionId,
MIN(length, sizeof(nxagentDialogName) - 1 - strlen(prefix)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same problem as above.

Bounding the size is actually a pretty good idea here, though.

@Ionic
Copy link
Member

Ionic commented Nov 22, 2017

Took me a while go through all of this, sorry...

@uli42 uli42 force-pushed the pr/improve_option_handling branch 3 times, most recently from a973993 to 39fe99d Compare November 23, 2017 14:47
@uli42
Copy link
Member Author

uli42 commented Nov 23, 2017

pushed updated version


nxagentDisplayName[1023] = '\0';

strncpy(nxagentDisplayName, argv[i], sizeof(nxagentDisplayName) - 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if we change nxagentDisplayName to be a pointer using a hardcoded value will also be wrong. So the situation does not get worse with my change. It only makes it easier to change that hardcoded value because it is now at only one location.

Yes, that's why I recommend using a macro defining each length, e.g., NXAGENTDISPLAYNAME_LENGTH = ... in the header file and using that throughout the code instead of a hardcoded value.

Even if we change the variables to pure pointers, the situation wouldn't really change. We probably should bound the data length with pure pointers as well. Otherwise, str(n)cpy will crash on invalid input data. With bounding, we will in the worst case get LEN-1 bytes of garbage data, but no actual crashes.

sizeof(ptr) doesn't work for pure pointers, so we'd have to change these sections again anyway.

I agree that dropping the hardcoded numbers is a good idea, but IMHO the best way (also taking into account further changes to pure pointers) is to use macros instead.

return 1;
}

if (!strcmp(argv[i], "-keystrokefile"))
{
if (i + 1 < argc)
{
if (NULL != (nxagentKeystrokeFile = strdup(argv[i + 1])))
if ((nxagentKeystrokeFile = strdup(argv[i + 1])) == NULL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welll... okay.

Personally, I'll be keeping this style for new submissions, particularly since it's just a cosmetic issue and provides a potential benefit.

I totally respect your decision, though. It's fine.

@uli42 uli42 force-pushed the pr/improve_option_handling branch 2 times, most recently from ee8d03d to f5346e4 Compare December 11, 2017 22:08
@uli42 uli42 force-pushed the pr/improve_option_handling branch 2 times, most recently from f5346e4 to d11ebd1 Compare February 27, 2018 21:43
@sunweaver
Copy link
Member

@Ionic: @uli42: ping on the status of this PR.

@sunweaver
Copy link
Member

@Ionic: @uli42: ping (2) on the status of this PR.

uli42 added 5 commits August 23, 2018 23:53
Warnings that are guarded by ifdefs are for the users. Therefore they
must not contain the function name.

Also some of the messages had not been prefixed by "Warning".
we already know the exact value of the name variable so there's no need
to validate it.
Within Args.c values in messages are not enclosed by [] but ''.
The [] format is only used for debugging/testing messages.
Use strndup instead of malloc + strncpy. Don't issue just a warning if
that fails but issue a FatalError.
uli42 added 9 commits August 23, 2018 23:53
We use (variable == constant) everywhere.
An options string/filename can only be provided via the command line
or environment. Both are handled in the one-time init part of
ddxProcessArguments() and will not change during runtime. As we do not
want an options file to include another "options" option there's no
need to handle that a second time. Due to the (kind of crazy) way
nxagent handles all this option stuff we cannot remove the second
check completely.

This also removes the 1024 byte limit for nxagentOptionsFilenameOrString.
Could not find a reason to limit that string.
@uli42 uli42 force-pushed the pr/improve_option_handling branch from d11ebd1 to 19126af Compare August 23, 2018 21:54
@uli42
Copy link
Member Author

uli42 commented Aug 23, 2018

rebased

@sunweaver
Copy link
Member

sunweaver commented Aug 24, 2018

@uli42: Is this PR outdated now with #725 merged?

@uli42
Copy link
Member Author

uli42 commented Aug 24, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants