From 768a850c582f4d037b6308333318a1ca6e57e648 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Wed, 22 Jul 2015 12:12:47 -0100 Subject: [PATCH] [infer][clang] fix model of sockets --- infer/models/c/src/libc_basic.c | 8 ++-- .../c/errors/resource_leaks/leak.c | 43 +++++++++++++++++++ infer/tests/endtoend/c/ResourceLeakTest.java | 28 +++++------- 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/infer/models/c/src/libc_basic.c b/infer/models/c/src/libc_basic.c index a623d8e67..69590b7f6 100644 --- a/infer/models/c/src/libc_basic.c +++ b/infer/models/c/src/libc_basic.c @@ -628,7 +628,7 @@ int open(const char *path, int oflag, ...) { if(ret) { __set_file_attribute(ret); INFER_EXCLUDE_CONDITION(ret < (int *)1); // force result to be > 0 - return (long) ret; + return ret; } return -1; } @@ -1877,12 +1877,12 @@ int wctomb(char *s, wchar_t wc) { } // modeled like open -int socket (int namespace, int style, int protocol) { +int socket(int namespace, int style, int protocol) { int *ret = malloc(sizeof(int)); if(ret) { __set_file_attribute(ret); - INFER_EXCLUDE_CONDITION(ret < (int *)1); // force result to be >= 0 - return (long) (ret-1); + INFER_EXCLUDE_CONDITION(ret < (int *)1); // force result to be > 0 + return ret; } return -1; } diff --git a/infer/tests/codetoanalyze/c/errors/resource_leaks/leak.c b/infer/tests/codetoanalyze/c/errors/resource_leaks/leak.c index 9688a452e..95520b08a 100644 --- a/infer/tests/codetoanalyze/c/errors/resource_leaks/leak.c +++ b/infer/tests/codetoanalyze/c/errors/resource_leaks/leak.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -40,3 +41,45 @@ void fileClosed() close(fd); } } + +void socketNotClosed() +{ + int fd = socket(AF_LOCAL, SOCK_RAW, 0); + if (fd != -1) { + char buffer[256]; + // We can easily batch that by separating with space + write(fd, buffer, strlen(buffer)); + } +} + +int socketClosed() +{ + int socketFD = socket(AF_LOCAL, SOCK_RAW, 0); + if (socketFD == -1) { + return -1; + } + + int status; + + status = fcntl(socketFD, F_SETFL, O_NONBLOCK); + if (status == -1) { + close(socketFD); + return -1; + } + + int reuseaddr = 1; + status = setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)); + if (status == -1) { + close(socketFD); + return -1; + } + + int nosigpipe = 1; + status = setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &nosigpipe, sizeof(nosigpipe)); + if (status == -1) { + close(socketFD); + return -1; + } + + return socketFD; +} diff --git a/infer/tests/endtoend/c/ResourceLeakTest.java b/infer/tests/endtoend/c/ResourceLeakTest.java index 6e5b2945c..27e047ace 100644 --- a/infer/tests/endtoend/c/ResourceLeakTest.java +++ b/infer/tests/endtoend/c/ResourceLeakTest.java @@ -10,8 +10,7 @@ package endtoend.c; import static org.hamcrest.MatcherAssert.assertThat; -import static utils.matchers.ResultContainsErrorInMethod.contains; -import static utils.matchers.ResultContainsNoErrorInMethod.doesNotContain; +import static utils.matchers.ResultContainsExactly.containsExactly; import org.junit.BeforeClass; import org.junit.Test; @@ -36,29 +35,22 @@ public class ResourceLeakTest { } @Test - public void whenInferRunsOnFileNotClosedThenLeakFound() + public void mathErrors() throws InterruptedException, IOException, InferException { + String[] functions = { + "fileNotClosed", + "socketNotClosed" + }; + assertThat( - "Results should not contain a resource leak", + "Results should contain " + RESOURCE_LEAK, inferResults, - contains( + containsExactly( RESOURCE_LEAK, SOURCE_FILE, - "fileNotClosed" + functions ) ); } - @Test - public void whenInferRunsOnFileClosedThenLeakNotFound() - throws InterruptedException, IOException, InferException { - assertThat( - "Results should not contain a resource leak", - inferResults, - doesNotContain( - RESOURCE_LEAK, - SOURCE_FILE, - "fileClosed")); - } - }