Skip to content

Fix using macro with regex in path parameter in fbtrace.conf#8238

Merged
AlexPeshkoff merged 3 commits intoFirebirdSQL:masterfrom
TreeHunter9:master-macro-and-regex-in-trace-conf
Sep 9, 2024
Merged

Fix using macro with regex in path parameter in fbtrace.conf#8238
AlexPeshkoff merged 3 commits intoFirebirdSQL:masterfrom
TreeHunter9:master-macro-and-regex-in-trace-conf

Conversation

@TreeHunter9
Copy link
Copy Markdown
Contributor

Currently we cannot use macro with regex in path parameter because PathUtils::fixupSeparators(value.begin()); happens too early, and it will fix \1 to /1 before we replace it with regex group, so we get unexpected path.
On Windows, we just get an error, because PathUtils::fixupSeparators(value.begin()); will change all / to \, and it will cause expandPattern() to throw an exception.

Comment thread src/common/config/config_file.cpp Outdated
Comment on lines +444 to +455
if (flags & FORCE_SLASHES_INSTEAD_OF_BACKSLASHES)
{
size_t pos = 0;
while ((pos = macro.find('\\', pos)) != String::npos)
macro[pos] = '/';
}
else
{
// Avoid incorrect slashes in pathnames
PathUtils::fixupSeparators(value.begin());
PathUtils::fixupSeparators(macro.begin());
}
Copy link
Copy Markdown
Contributor Author

@TreeHunter9 TreeHunter9 Sep 3, 2024

Choose a reason for hiding this comment

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

I'm trying to keep the old implementation, so I added FORCE_SLASHES_INSTEAD_OF_BACKSLASHES flag, but maybe we can just remove these PathUtils::fixupSeparators() because it will happen in PATH_PARAMETER after all parsing steps anyway?

Copy link
Copy Markdown
Member

@AlexPeshkoff AlexPeshkoff Sep 3, 2024

Choose a reason for hiding this comment

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

Please provide a sample of causing problems trace configuration

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

database = %[\\/](employee).fdb
{
	enabled = true
	log_filename = $(root)\1.log
	log_connections = true
	time_threshold = 0
}

Log filename should be fb_root_path/employee.log, but we get fb_root_path/1.log.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

On Windows it doesn't even get created because it's trying to parse backslashes as part of regex pattern (\1, \2, etc) but encounters \d[ev] in the file path and throws an error:

DESKTOP-86JTPHF	Tue Sep  3 10:37:29 2024
	Trace plugin fbtrace returned error on call trace_create.
	error while parsing trace configuration
	line 195, element "log_filename": pattern is invalid
	 E:\dev\MyFirebird\firebird\output_x64_debug\1.log

Copy link
Copy Markdown
Member

@AlexPeshkoff AlexPeshkoff left a comment

Choose a reason for hiding this comment

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

I'm afraid suggested solution is not complete. Imagine someone types (in windows):
log_filename = $(root)\audit-logs\1.log
Some problems are hardly avoidable when same char is used for 2 different purposes, but lets try to minimize them.

I suggest to use something like REGEXP_SUPPORT instead FORCE_SLASHES_INSTEAD_OF_BACKSLASHES and carefully parse both value and macro (moreover, value should be parsed when flag is set even when no macro-subst is done) in order to replace backslash with slash when next char is not a digit. At the first glance it appears more generic. Certainly if someone called directory '1' and tries to use it for logs I do not know how to guess what to do with that.

@aafemt
Copy link
Copy Markdown
Contributor

aafemt commented Sep 5, 2024

Some problems are hardly avoidable when same char is used for 2 different purposes, but lets try to minimize them.

If you are ready to review the initial design, I would suggest to use $(1) for subpattern substitutions.

@AlexPeshkoff
Copy link
Copy Markdown
Member

AlexPeshkoff commented Sep 5, 2024 via email

@TreeHunter9
Copy link
Copy Markdown
Contributor Author

I'm afraid suggested solution is not complete. Imagine someone types (in windows):
log_filename = $(root)\audit-logs\1.log
Some problems are hardly avoidable when same char is used for 2 different purposes, but lets try to minimize them.

Oh, for some reason I thought only / was allowed as a separator in the path. Now I looked more into it and found out that we should use \\ for backslashes in path (as it says in fbtrace.conf), and here is code snippet from TraceCfgReader::expandPattern:

if (c == '\\')
{
// Kill one of the backslash signs and loop again
valueToExpand.erase(pos, 1);
pos++;
continue;
}

So I guess the problem only remains on Linux because of PathUtils::fixupSeparators(value.begin()); will fixup \1 regex pattern.
I will do another test tomorrow.

@TreeHunter9
Copy link
Copy Markdown
Contributor Author

I'm afraid suggested solution is not complete. Imagine someone types (in windows):
log_filename = $(root)\audit-logs\1.log

We should write path like this: $(root)audit-logs\\\1.log, $(root) already have \\ at the end, and audit-logs\\\1.log so we can translate it into audit-logs\employee.log. So I guess we don't need to change the semantics of the regexp.
So we really only have one problem, where macro insertion fixes all regexp patterns (on Windows macro insertion uses incorrect backslashes for path) and this patch should fix that.

@AlexPeshkoff
Copy link
Copy Markdown
Member

Macro in config design supposed to provide smart behavior when merging paths, i.e. one need not know that $(root) already has \ at the end. In linux having double dir separators one after another (something like /usr//bin instead /usr/bin) is not dangerous but I'm not sure for other OS-es. Anyway, resulting file name may get visible to user somewhere else, i.e. I prefer to have correctly merged paths, not relying on presence of // at the end. Also we always tried to have config format as OS independent as possible, i.e. one should be able to have
$(root)\audit-logs\\1.log on linux or
$(root)/audit-logs/\1.log on windows (may be as a result of file copy when changing OS).

@TreeHunter9
Copy link
Copy Markdown
Contributor Author

Tested on these file paths:

Windows and Linux:
$(root)\1.log -> /path/to/root/employee.log
$(root)/\1.log -> /path/to/root/employee.log
$(root)\\\1.log -> /path/to/root/employee.log
$(root)\\1.log -> /path/to/root/1.log

Only Linux:
/$(root)/\1.log -> /path/to/root/employee.log
\\$(root)/\1.log -> /path/to/root/employee.log

@AlexPeshkoff AlexPeshkoff self-assigned this Sep 9, 2024
@AlexPeshkoff AlexPeshkoff merged commit 9f5b5bf into FirebirdSQL:master Sep 9, 2024
@AlexPeshkoff
Copy link
Copy Markdown
Member

I suggest you backport changes to previous versions

@dyemanov
Copy link
Copy Markdown
Member

dyemanov commented Sep 9, 2024

I will backport it.

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.

5 participants