chris@226: #!/usr/bin/perl -w chris@226: chris@226: # Read a Doxyfile and print it out again to stdout, with only chris@226: # whitelisted keys in it and with some keys set to pre-fixed values. chris@226: # chris@226: # Note that OUTPUT_DIRECTORY is not included; it should be added by chris@226: # the caller chris@226: chris@226: use strict; chris@226: chris@226: my $txt = join "", <>; chris@226: $txt =~ s/^\s*#.*$//gm; chris@226: $txt =~ s/\\\n//gs; chris@226: $txt =~ s/\r//g; chris@226: $txt =~ s/\n\s*\n/\n/gs; chris@226: chris@226: my %fixed = ( chris@226: FULL_PATH_NAMES => "NO", chris@226: SYMBOL_CACHE_SIZE => 2, chris@226: EXCLUDE_SYMLINKS => "YES", chris@226: GENERATE_HTML => "YES", chris@226: PERL_PATH => "/usr/bin/perl", chris@226: HAVE_DOT => "YES", chris@226: HTML_OUTPUT => ".", chris@228: HTML_DYNAMIC_SECTIONS => "NO", chris@226: SEARCHENGINE => "NO", chris@226: DOT_FONTNAME => "FreeMono", chris@226: DOT_FONTSIZE => 10, chris@226: DOT_FONTPATH => "/usr/share/fonts/truetype/freefont", chris@226: DOT_IMAGE_FORMAT => "png", chris@226: DOT_PATH => "/usr/bin/dot", chris@226: DOT_TRANSPARENT => "YES", chris@226: ); chris@226: Chris@233: # These are the keys that are safe to take from the output and include Chris@233: # in the output; they may still need to be checked for safe values (if Chris@233: # file paths). chris@226: my @safe = qw( Chris@233: INPUT Chris@233: FILE_PATTERNS Chris@233: EXAMPLE_PATH Chris@233: EXAMPLE_PATTERNS Chris@233: IMAGE_PATH Chris@233: INCLUDE_PATH Chris@233: INCLUDE_FILE_PATTERNS chris@226: DOXYFILE_ENCODING chris@226: PROJECT_NAME chris@226: PROJECT_NUMBER chris@226: CREATE_SUBDIRS chris@226: OUTPUT_LANGUAGE chris@226: BRIEF_MEMBER_DESC chris@226: REPEAT_BRIEF chris@226: ABBREVIATE_BRIEF chris@226: ALWAYS_DETAILED_SEC chris@226: INLINE_INHERITED_MEMB chris@226: STRIP_FROM_PATH chris@226: STRIP_FROM_INC_PATH chris@226: JAVADOC_AUTOBRIEF chris@226: QT_AUTOBRIEF chris@226: MULTILINE_CPP_IS_BRIEF chris@226: INHERIT_DOCS chris@226: SEPARATE_MEMBER_PAGES chris@226: TAB_SIZE chris@226: ALIASES chris@226: OPTIMIZE_OUTPUT_FOR_C chris@226: OPTIMIZE_OUTPUT_JAVA chris@226: OPTIMIZE_FOR_FORTRAN chris@226: OPTIMIZE_OUTPUT_VHDL chris@226: EXTENSION_MAPPING chris@226: BUILTIN_STL_SUPPORT chris@226: CPP_CLI_SUPPORT chris@226: SIP_SUPPORT chris@226: IDL_PROPERTY_SUPPORT chris@226: DISTRIBUTE_GROUP_DOC chris@226: SUBGROUPING chris@226: TYPEDEF_HIDES_STRUCT chris@226: EXTRACT_ALL chris@226: EXTRACT_PRIVATE chris@226: EXTRACT_STATIC chris@226: EXTRACT_LOCAL_CLASSES chris@226: EXTRACT_LOCAL_METHODS chris@226: EXTRACT_ANON_NSPACES chris@226: HIDE_UNDOC_MEMBERS chris@226: HIDE_UNDOC_CLASSES chris@226: HIDE_FRIEND_COMPOUNDS chris@226: HIDE_IN_BODY_DOCS chris@226: INTERNAL_DOCS chris@226: HIDE_SCOPE_NAMES chris@226: SHOW_INCLUDE_FILES chris@226: FORCE_LOCAL_INCLUDES chris@226: INLINE_INFO chris@226: SORT_MEMBER_DOCS chris@226: SORT_BRIEF_DOCS chris@226: SORT_MEMBERS_CTORS_1ST chris@226: SORT_GROUP_NAMES chris@226: SORT_BY_SCOPE_NAME chris@226: GENERATE_TODOLIST chris@226: GENERATE_TESTLIST chris@226: GENERATE_BUGLIST chris@226: GENERATE_DEPRECATEDLIST chris@226: ENABLED_SECTIONS chris@226: MAX_INITIALIZER_LINES chris@226: SHOW_USED_FILES chris@226: SHOW_DIRECTORIES chris@226: SHOW_FILES chris@226: SHOW_NAMESPACES chris@226: QUIET chris@226: WARNINGS chris@226: WARN_IF_UNDOCUMENTED chris@226: WARN_IF_DOC_ERROR chris@226: WARN_NO_PARAMDOC chris@226: INPUT_ENCODING chris@226: RECURSIVE chris@226: EXCLUDE chris@226: EXCLUDE_SYMLINKS chris@226: EXCLUDE_PATTERNS chris@226: EXCLUDE_SYMBOLS chris@226: EXAMPLE_RECURSIVE chris@226: SOURCE_BROWSER chris@226: INLINE_SOURCES chris@226: STRIP_CODE_COMMENTS chris@226: REFERENCED_BY_RELATION chris@226: REFERENCES_RELATION chris@226: REFERENCES_LINK_SOURCE chris@226: VERBATIM_HEADERS chris@226: ALPHABETICAL_INDEX chris@226: COLS_IN_ALPHA_INDEX chris@226: IGNORE_PREFIX chris@226: HTML_TIMESTAMP chris@226: HTML_ALIGN_MEMBERS chris@226: ENABLE_PREPROCESSING chris@226: MACRO_EXPANSION chris@226: EXPAND_ONLY_PREDEF chris@226: SEARCH_INCLUDES chris@226: PREDEFINED chris@226: EXPAND_AS_DEFINED chris@226: SKIP_FUNCTION_MACROS chris@226: ALLEXTERNALS chris@226: EXTERNAL_GROUPS chris@226: CLASS_DIAGRAMS chris@226: HIDE_UNDOC_RELATIONS chris@226: CLASS_GRAPH chris@226: COLLABORATION_GRAPH chris@226: GROUP_GRAPHS chris@226: UML_LOOK chris@226: TEMPLATE_RELATIONS chris@226: INCLUDE_GRAPH chris@226: INCLUDED_BY_GRAPH chris@226: CALL_GRAPH chris@226: CALLER_GRAPH chris@226: GRAPHICAL_HIERARCHY chris@226: DIRECTORY_GRAPH chris@226: DOT_GRAPH_MAX_NODES chris@226: MAX_DOT_GRAPH_DEPTH chris@226: DOT_MULTI_TARGETS chris@226: DOT_CLEANUP chris@226: ); chris@226: chris@226: my %safehash; chris@226: for my $sk (@safe) { $safehash{$sk} = 1; } chris@226: chris@226: my @lines = split "\n", $txt; chris@226: chris@226: my %settings; chris@226: chris@226: sub is_safe { chris@226: my $key = shift; chris@226: defined $safehash{$key} and $safehash{$key} == 1; chris@226: } chris@226: chris@226: sub has_file_path { chris@226: # Returns true if the given key expects a file path as a value. chris@226: # We only need to test keys that are safe; unsafe keys have been chris@226: # rejected already. chris@226: my $key = shift; chris@226: $key eq "INPUT" or chris@226: $key =~ /^OUTPUT_/ or chris@226: $key =~ /_PATH$/ or chris@226: $key =~ /_PATTERNS$/; chris@226: } chris@226: chris@226: sub is_safe_file_path { chris@226: my $value = shift; chris@226: not $value =~ /^\// and not $value =~ /\.\./; chris@226: } chris@226: chris@226: foreach my $line (@lines) { chris@226: chris@226: chomp $line; chris@226: my ($key, $value) = split /\s*=\s*/, $line; chris@226: chris@226: next if !defined $key; chris@226: chris@226: if ($key =~ /^GENERATE_/ and not $key =~ /LIST$/) { chris@226: print STDERR "NOTE: Setting $key explicitly to NO\n"; chris@226: $settings{$key} = "NO"; chris@226: next; chris@226: } chris@226: chris@226: if (!is_safe($key)) { chris@226: print STDERR "NOTE: Skipping non-whitelisted key $key\n"; chris@226: next; chris@226: } chris@226: chris@226: if (has_file_path($key) and !is_safe_file_path($value)) { chris@226: print STDERR "ERROR: Unsafe file path \"$value\" for key $key\n"; chris@226: exit 1; chris@226: } chris@226: chris@226: $settings{$key} = $value; chris@226: } chris@226: chris@228: foreach my $key (keys %fixed) { chris@228: my $value = $fixed{$key}; chris@228: print STDERR "NOTE: Setting $key to fixed value $value\n"; chris@228: $settings{$key} = $value; chris@228: } chris@228: chris@226: print join "\n", map { "$_ = $settings{$_}" } keys %settings; chris@226: print "\n";