Skip to content

Commit

Permalink
fix: #5671 out of memory error (#5789)
Browse files Browse the repository at this point in the history
  • Loading branch information
aikebah committed Jun 22, 2023
2 parents 3f512e0 + 76e0d7c commit 82ea742
Show file tree
Hide file tree
Showing 4 changed files with 316 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,8 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
/**
* Regex to extract product and version information.
*
* Group 1: Product
*
* Group 2: Version
* <p>Group 1: Product</p>
* <p>Group 2: Version</p>
*/
private static final Pattern SET_VERSION = Pattern
.compile("^\\s*set\\s*\\(\\s*(\\w+)_version\\s+\"?([^\")]*)\\s*\"?\\)", REGEX_OPTIONS);
Expand Down Expand Up @@ -349,8 +348,8 @@ protected String getAnalyzerEnabledSettingKey() {
* initialized by other variables and end up forming an unresolvable
* chain.
*
* This method takes the resolved variables map as an input and will return
* a new map, without the keys generate an infinite resolution chain.
* <p>This method takes the resolved variables map as an input and will return
* a new map, without the keys generating an infinite resolution chain.</p>
*
* @param vars variables initialization detected in the CMake build file
*
Expand Down Expand Up @@ -379,6 +378,9 @@ private boolean isVariableSelfReferencing(Map<String, String> vars, String key)
break;
}
nextKey = matcher.group(2);
if (Objects.nonNull(nextKey) && resolutionChain.contains(nextKey)) {
return true;
}
resolutionChain.add(nextKey);
} while (Objects.nonNull(nextKey) && vars.containsKey(nextKey) && !key.equals(nextKey));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,54 @@ public void testRemoveSelfReferences() {
assertEquals(expectedOutput, output);
}

@Test
public void testRemoveSelfReferences2() {
// Given
Map<String, String> input = new HashMap<>();
input.put("FLTK2_DIR", "${FLTK2_INCLUDE_DIR}");
input.put("FLTK2_LIBRARY_SEARCH_PATH", "");
input.put("FLTK2_INCLUDE_DIR", "${FLTK2_DIR}");
input.put("FLTK2_IMAGES_LIBS", "");
input.put("FLTK2_DIR_SEARCH", "");
input.put("FLTK2_WRAP_UI", "1");
input.put("FLTK2_FOUND", "0");
input.put("FLTK2_IMAGES_LIBRARY", "fltk2_images");
input.put("FLTK2_PLATFORM_DEPENDENT_LIBS", "import32");
input.put("FLTK_FLUID_EXECUTABLE", "${FLTK2_FLUID_EXECUTABLE}");
input.put("FLTK2_INCLUDE_SEARCH_PATH", "");
input.put("FLTK2_LIBRARY", "${FLTK2_LIBRARIES}");
input.put("FLTK2_BUILT_WITH_CMAKE", "1");
input.put("FLTK2_INCLUDE_PATH", "${FLTK2_INCLUDE_DIR}");
input.put("FLTK2_GL_LIBRARY", "fltk2_gl");
input.put("FLTK2_FLUID_EXE", "${FLTK2_FLUID_EXECUTABLE}");
input.put("HAS_FLTK2", "${FLTK2_FOUND}");
input.put("FLTK2_BASE_LIBRARY", "fltk2");


Map<String, String> expectedOutput = new HashMap<>();
expectedOutput.put("FLTK2_LIBRARY_SEARCH_PATH", "");
expectedOutput.put("FLTK2_IMAGES_LIBS", "");
expectedOutput.put("FLTK2_DIR_SEARCH", "");
expectedOutput.put("FLTK2_WRAP_UI", "1");
expectedOutput.put("FLTK2_FOUND", "0");
expectedOutput.put("FLTK2_IMAGES_LIBRARY", "fltk2_images");
expectedOutput.put("FLTK2_PLATFORM_DEPENDENT_LIBS", "import32");
expectedOutput.put("FLTK_FLUID_EXECUTABLE", "${FLTK2_FLUID_EXECUTABLE}");
expectedOutput.put("FLTK2_INCLUDE_SEARCH_PATH", "");
expectedOutput.put("FLTK2_LIBRARY", "${FLTK2_LIBRARIES}");
expectedOutput.put("FLTK2_BUILT_WITH_CMAKE", "1");
expectedOutput.put("FLTK2_GL_LIBRARY", "fltk2_gl");
expectedOutput.put("FLTK2_FLUID_EXE", "${FLTK2_FLUID_EXECUTABLE}");
expectedOutput.put("HAS_FLTK2", "${FLTK2_FOUND}");
expectedOutput.put("FLTK2_BASE_LIBRARY", "fltk2");

// When
Map<String, String> output = analyzer.removeSelfReferences(input);

// Then
assertEquals(expectedOutput, output);
}

/**
* Test the analyzer does not end up in an infinite loop when a temp
* variable is used to store old value and then restore it afterwards.
Expand All @@ -235,4 +283,15 @@ public void testAnalyzeCMakeTempVariable() throws AnalysisException {
assertEquals("FindDeflate.cmake", result.getFileName());
}
}

@Test
public void testAnalyzeCMakeInfiniteLoop() throws AnalysisException {
try (Engine engine = new Engine(getSettings())) {
final Dependency result = new Dependency(BaseTest.getResourceAsFile(
this, "cmake/cmake-modules/FindFLTK2.cmake"));
analyzer.analyze(result, engine);

assertEquals("FindFLTK2.cmake", result.getFileName());
}
}
}
5 changes: 5 additions & 0 deletions core/src/test/resources/cmake/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CMakeAnalyzer Test Resources README
===================================

cmake-modules/
--------------

Origin: https://gitlab.kitware.com/cmake/cmake/-/tree/master/Modules

opencv/
-------

Expand Down
245 changes: 245 additions & 0 deletions core/src/test/resources/cmake/cmake-modules/FindFLTK2.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
FindFLTK2
---------

Find the native FLTK 2.0 includes and library

The following settings are defined

::

FLTK2_FLUID_EXECUTABLE, where to find the Fluid tool
FLTK2_WRAP_UI, This enables the FLTK2_WRAP_UI command
FLTK2_INCLUDE_DIR, where to find include files
FLTK2_LIBRARIES, list of fltk2 libraries
FLTK2_FOUND, Don't use FLTK2 if false.

The following settings should not be used in general.

::

FLTK2_BASE_LIBRARY = the full path to fltk2.lib
FLTK2_GL_LIBRARY = the full path to fltk2_gl.lib
FLTK2_IMAGES_LIBRARY = the full path to fltk2_images.lib
#]=======================================================================]

set (FLTK2_DIR $ENV{FLTK2_DIR} )

# Platform dependent libraries required by FLTK2
if(WIN32)
if(NOT CYGWIN)
if(BORLAND)
set( FLTK2_PLATFORM_DEPENDENT_LIBS import32 )
else()
set( FLTK2_PLATFORM_DEPENDENT_LIBS wsock32 comctl32 )
endif()
endif()
endif()

if(UNIX)
include(${CMAKE_ROOT}/Modules/FindX11.cmake)
set( FLTK2_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} -lm)
endif()

if(APPLE)
set( FLTK2_PLATFORM_DEPENDENT_LIBS "-framework Carbon -framework Cocoa -framework ApplicationServices -lz")
endif()

# If FLTK2_INCLUDE_DIR is already defined we assign its value to FLTK2_DIR
if(FLTK2_INCLUDE_DIR)
set(FLTK2_DIR ${FLTK2_INCLUDE_DIR})
else()
set(FLTK2_INCLUDE_DIR ${FLTK2_DIR})
endif()


# If FLTK2 has been built using CMake we try to find everything directly
set(FLTK2_DIR_STRING "directory containing FLTK2Config.cmake. This is either the root of the build tree, or PREFIX/lib/fltk for an installation.")

# Search only if the location is not already known.
if(NOT FLTK2_DIR)
# Get the system search path as a list.
file(TO_CMAKE_PATH "$ENV{PATH}" FLTK2_DIR_SEARCH2)

# Construct a set of paths relative to the system search path.
set(FLTK2_DIR_SEARCH "")
foreach(dir ${FLTK2_DIR_SEARCH2})
set(FLTK2_DIR_SEARCH ${FLTK2_DIR_SEARCH} "${dir}/../lib/fltk")
endforeach()
string(REPLACE "//" "/" FLTK2_DIR_SEARCH "${FLTK2_DIR_SEARCH}")

#
# Look for an installation or build tree.
#
find_path(FLTK2_DIR FLTK2Config.cmake
# Look for an environment variable FLTK2_DIR.
ENV FLTK2_DIR

# Look in places relative to the system executable search path.
${FLTK2_DIR_SEARCH}

PATH_SUFFIXES
fltk2
fltk2/include
lib/fltk2
lib/fltk2/include

# Help the user find it if we cannot.
DOC "The ${FLTK2_DIR_STRING}"
)

if(NOT FLTK2_DIR)
find_path(FLTK2_DIR fltk/run.h ${FLTK2_INCLUDE_SEARCH_PATH})
endif()

endif()


# If FLTK2 was found, load the configuration file to get the rest of the
# settings.
if(FLTK2_DIR)

# Check if FLTK2 was built using CMake
if(EXISTS ${FLTK2_DIR}/FLTK2Config.cmake)
set(FLTK2_BUILT_WITH_CMAKE 1)
endif()

if(FLTK2_BUILT_WITH_CMAKE)
set(FLTK2_FOUND 1)
include(${FLTK2_DIR}/FLTK2Config.cmake)

# Fluid
if(FLUID_COMMAND)
set(FLTK2_FLUID_EXECUTABLE ${FLUID_COMMAND} CACHE FILEPATH "Fluid executable")
else()
find_program(FLTK2_FLUID_EXECUTABLE fluid2 PATHS
${FLTK2_EXECUTABLE_DIRS}
${FLTK2_EXECUTABLE_DIRS}/RelWithDebInfo
${FLTK2_EXECUTABLE_DIRS}/Debug
${FLTK2_EXECUTABLE_DIRS}/Release
NO_SYSTEM_PATH)
endif()

mark_as_advanced(FLTK2_FLUID_EXECUTABLE)
set( FLTK_FLUID_EXECUTABLE ${FLTK2_FLUID_EXECUTABLE} )




set(FLTK2_INCLUDE_DIR ${FLTK2_DIR})
link_directories(${FLTK2_LIBRARY_DIRS})

set(FLTK2_BASE_LIBRARY fltk2)
set(FLTK2_GL_LIBRARY fltk2_gl)
set(FLTK2_IMAGES_LIBRARY fltk2_images)

# Add the extra libraries
load_cache(${FLTK2_DIR}
READ_WITH_PREFIX
FL FLTK2_USE_SYSTEM_JPEG
FL FLTK2_USE_SYSTEM_PNG
FL FLTK2_USE_SYSTEM_ZLIB
)

set(FLTK2_IMAGES_LIBS "")
if(FLFLTK2_USE_SYSTEM_JPEG)
set(FLTK2_IMAGES_LIBS ${FLTK2_IMAGES_LIBS} fltk2_jpeg)
endif()
if(FLFLTK2_USE_SYSTEM_PNG)
set(FLTK2_IMAGES_LIBS ${FLTK2_IMAGES_LIBS} fltk2_png)
endif()
if(FLFLTK2_USE_SYSTEM_ZLIB)
set(FLTK2_IMAGES_LIBS ${FLTK2_IMAGES_LIBS} fltk2_zlib)
endif()
set(FLTK2_IMAGES_LIBS "${FLTK2_IMAGES_LIBS}" CACHE INTERNAL
"Extra libraries for fltk2_images library.")

else()

# if FLTK2 was not built using CMake
# Find fluid executable.
find_program(FLTK2_FLUID_EXECUTABLE fluid2 ${FLTK2_INCLUDE_DIR}/fluid)

# Use location of fluid to help find everything else.
set(FLTK2_INCLUDE_SEARCH_PATH "")
set(FLTK2_LIBRARY_SEARCH_PATH "")
if(FLTK2_FLUID_EXECUTABLE)
set( FLTK_FLUID_EXECUTABLE ${FLTK2_FLUID_EXECUTABLE} )
get_filename_component(FLTK2_BIN_DIR "${FLTK2_FLUID_EXECUTABLE}" PATH)
set(FLTK2_INCLUDE_SEARCH_PATH ${FLTK2_INCLUDE_SEARCH_PATH}
${FLTK2_BIN_DIR}/../include ${FLTK2_BIN_DIR}/..)
set(FLTK2_LIBRARY_SEARCH_PATH ${FLTK2_LIBRARY_SEARCH_PATH}
${FLTK2_BIN_DIR}/../lib)
set(FLTK2_WRAP_UI 1)
endif()

find_path(FLTK2_INCLUDE_DIR fltk/run.h ${FLTK2_INCLUDE_SEARCH_PATH} PATH_SUFFIXES fltk2 fltk2/include)

list(APPEND FLTK2_LIBRARY_SEARCH_PATH ${FLTK2_INCLUDE_DIR}/lib)

find_library(FLTK2_BASE_LIBRARY NAMES fltk2
PATHS ${FLTK2_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk2 fltk2/lib)
find_library(FLTK2_GL_LIBRARY NAMES fltk2_gl
PATHS ${FLTK2_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk2 fltk2/lib)
find_library(FLTK2_IMAGES_LIBRARY NAMES fltk2_images
PATHS ${FLTK2_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk2 fltk2/lib)

# Find the extra libraries needed for the fltk_images library.
if(UNIX)
find_program(FLTK2_CONFIG_SCRIPT fltk2-config PATHS ${FLTK2_BIN_DIR})
if(FLTK2_CONFIG_SCRIPT)
exec_program(${FLTK2_CONFIG_SCRIPT} ARGS --use-images --ldflags
OUTPUT_VARIABLE FLTK2_IMAGES_LDFLAGS)
set(FLTK2_LIBS_EXTRACT_REGEX ".*-lfltk2_images (.*) -lfltk2.*")
if("${FLTK2_IMAGES_LDFLAGS}" MATCHES "${FLTK2_LIBS_EXTRACT_REGEX}")
string(REGEX REPLACE " +" ";" FLTK2_IMAGES_LIBS "${CMAKE_MATCH_1}")
# The EXEC_PROGRAM will not be inherited into subdirectories from
# the file that originally included this module. Save the answer.
set(FLTK2_IMAGES_LIBS "${FLTK2_IMAGES_LIBS}" CACHE INTERNAL
"Extra libraries for fltk_images library.")
endif()
endif()
endif()

endif()
endif()


set(FLTK2_FOUND 1)
foreach(var FLTK2_FLUID_EXECUTABLE FLTK2_INCLUDE_DIR
FLTK2_BASE_LIBRARY FLTK2_GL_LIBRARY
FLTK2_IMAGES_LIBRARY)
if(NOT ${var})
message( STATUS "${var} not found" )
set(FLTK2_FOUND 0)
endif()
endforeach()


if(FLTK2_FOUND)
set(FLTK2_LIBRARIES ${FLTK2_IMAGES_LIBRARY} ${FLTK2_IMAGES_LIBS} ${FLTK2_BASE_LIBRARY} ${FLTK2_GL_LIBRARY} )
if(APPLE)
set(FLTK2_LIBRARIES ${FLTK2_PLATFORM_DEPENDENT_LIBS} ${FLTK2_LIBRARIES})
else()
set(FLTK2_LIBRARIES ${FLTK2_LIBRARIES} ${FLTK2_PLATFORM_DEPENDENT_LIBS})
endif()

# The following deprecated settings are for compatibility with CMake 1.4
set (HAS_FLTK2 ${FLTK2_FOUND})
set (FLTK2_INCLUDE_PATH ${FLTK2_INCLUDE_DIR})
set (FLTK2_FLUID_EXE ${FLTK2_FLUID_EXECUTABLE})
set (FLTK2_LIBRARY ${FLTK2_LIBRARIES})
else()
# make FIND_PACKAGE friendly
if(NOT FLTK2_FIND_QUIETLY)
if(FLTK2_FIND_REQUIRED)
message(FATAL_ERROR
"FLTK2 required, please specify its location with FLTK2_DIR.")
else()
message(STATUS "FLTK2 was not found.")
endif()
endif()
endif()

0 comments on commit 82ea742

Please sign in to comment.