mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge branch 'main' into del-deps-sep-2024
This commit is contained in:
4
cpp/ql/lib/change-notes/2024-09-03-realloc-data-flow.md
Normal file
4
cpp/ql/lib/change-notes/2024-09-03-realloc-data-flow.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added a data flow model for `realloc`-like functions, which were previously modeled as a taint tracking functions. This change improves the precision of queries where flow through `realloc`-like functions might affect the results.
|
||||
@@ -5,13 +5,13 @@
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.models.interfaces.Allocation
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
|
||||
/**
|
||||
* An allocation function (such as `realloc`) that has an argument for the size
|
||||
* in bytes, and an argument for an existing pointer that is to be reallocated.
|
||||
*/
|
||||
private class ReallocAllocationFunction extends AllocationFunction, TaintFunction {
|
||||
private class ReallocAllocationFunction extends AllocationFunction, DataFlowFunction {
|
||||
int sizeArg;
|
||||
int reallocArg;
|
||||
|
||||
@@ -44,7 +44,7 @@ private class ReallocAllocationFunction extends AllocationFunction, TaintFunctio
|
||||
|
||||
override int getReallocPtrArg() { result = reallocArg }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameterDeref(this.getReallocPtrArg()) and output.isReturnValueDeref()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ argHasPostUpdate
|
||||
| test.cpp:67:29:67:35 | source1 | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:813:19:813:35 | * ... | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:848:23:848:25 | rpx | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:1057:19:1057:21 | * ... | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:1065:19:1065:21 | * ... | ArgumentNode is missing PostUpdateNode. |
|
||||
postWithInFlow
|
||||
| BarrierGuard.cpp:49:6:49:6 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:60:7:60:7 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -167,15 +167,15 @@ postWithInFlow
|
||||
| test.cpp:932:5:932:19 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:932:6:932:19 | global_pointer [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1045:9:1045:11 | ref arg buf | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1051:5:1051:11 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1052:9:1052:9 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1056:5:1056:7 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1056:6:1056:7 | pp [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1062:53:1062:53 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1072:3:1072:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1072:4:1072:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1073:3:1073:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1073:4:1073:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1059:5:1059:11 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1060:9:1060:9 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1064:5:1064:7 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1064:6:1064:7 | pp [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1070:53:1070:53 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1080:3:1080:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1080:4:1080:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1081:3:1081:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1081:4:1081:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
|
||||
@@ -202,12 +202,12 @@
|
||||
| test.cpp:489:23:489:29 | *content | test.cpp:490:8:490:17 | * ... |
|
||||
| test.cpp:489:23:489:29 | content | test.cpp:489:23:489:29 | content |
|
||||
| test.cpp:489:23:489:29 | content | test.cpp:490:9:490:17 | p_content |
|
||||
| test.cpp:1050:12:1050:12 | definition of a | test.cpp:1051:3:1051:3 | *a |
|
||||
| test.cpp:1051:3:1051:3 | *a | test.cpp:1052:8:1052:9 | *& ... |
|
||||
| test.cpp:1051:3:1051:3 | *a [post update] | test.cpp:1052:8:1052:9 | *& ... |
|
||||
| test.cpp:1051:3:1051:3 | a | test.cpp:1052:8:1052:9 | & ... |
|
||||
| test.cpp:1051:3:1051:3 | a [post update] | test.cpp:1052:8:1052:9 | & ... |
|
||||
| test.cpp:1051:15:1051:21 | 0 | test.cpp:1051:3:1051:21 | ... = ... |
|
||||
| test.cpp:1051:15:1051:21 | *0 | test.cpp:1051:3:1051:21 | *... = ... |
|
||||
| test.cpp:1052:9:1052:9 | *a | test.cpp:1052:8:1052:9 | *& ... |
|
||||
| test.cpp:1052:9:1052:9 | a | test.cpp:1052:8:1052:9 | & ... |
|
||||
| test.cpp:1058:12:1058:12 | definition of a | test.cpp:1059:3:1059:3 | *a |
|
||||
| test.cpp:1059:3:1059:3 | *a | test.cpp:1060:8:1060:9 | *& ... |
|
||||
| test.cpp:1059:3:1059:3 | *a [post update] | test.cpp:1060:8:1060:9 | *& ... |
|
||||
| test.cpp:1059:3:1059:3 | a | test.cpp:1060:8:1060:9 | & ... |
|
||||
| test.cpp:1059:3:1059:3 | a [post update] | test.cpp:1060:8:1060:9 | & ... |
|
||||
| test.cpp:1059:15:1059:21 | 0 | test.cpp:1059:3:1059:21 | ... = ... |
|
||||
| test.cpp:1059:15:1059:21 | *0 | test.cpp:1059:3:1059:21 | *... = ... |
|
||||
| test.cpp:1060:9:1060:9 | *a | test.cpp:1060:8:1060:9 | *& ... |
|
||||
| test.cpp:1060:9:1060:9 | a | test.cpp:1060:8:1060:9 | & ... |
|
||||
|
||||
@@ -81,10 +81,10 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (loc
|
||||
| test.cpp:488:21:488:21 | s [post update] | test.cpp:489:20:489:20 | s |
|
||||
| test.cpp:488:24:488:30 | ref arg content | test.cpp:489:23:489:29 | content |
|
||||
| test.cpp:489:23:489:29 | content | test.cpp:490:9:490:17 | p_content |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1051:3:1051:3 | a |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1052:9:1052:9 | a |
|
||||
| test.cpp:1051:3:1051:3 | a [post update] | test.cpp:1052:9:1052:9 | a |
|
||||
| test.cpp:1051:3:1051:21 | ... = ... | test.cpp:1051:5:1051:11 | content [post update] |
|
||||
| test.cpp:1051:15:1051:21 | 0 | test.cpp:1051:3:1051:21 | ... = ... |
|
||||
| test.cpp:1052:8:1052:9 | ref arg & ... | test.cpp:1052:9:1052:9 | a [inner post update] |
|
||||
| test.cpp:1052:9:1052:9 | a | test.cpp:1052:8:1052:9 | & ... |
|
||||
| test.cpp:1058:12:1058:12 | a | test.cpp:1059:3:1059:3 | a |
|
||||
| test.cpp:1058:12:1058:12 | a | test.cpp:1060:9:1060:9 | a |
|
||||
| test.cpp:1059:3:1059:3 | a [post update] | test.cpp:1060:9:1060:9 | a |
|
||||
| test.cpp:1059:3:1059:21 | ... = ... | test.cpp:1059:5:1059:11 | content [post update] |
|
||||
| test.cpp:1059:15:1059:21 | 0 | test.cpp:1059:3:1059:21 | ... = ... |
|
||||
| test.cpp:1060:8:1060:9 | ref arg & ... | test.cpp:1060:9:1060:9 | a [inner post update] |
|
||||
| test.cpp:1060:9:1060:9 | a | test.cpp:1060:8:1060:9 | & ... |
|
||||
|
||||
@@ -127,7 +127,7 @@ astFlow
|
||||
| test.cpp:842:11:842:16 | call to source | test.cpp:844:8:844:8 | y |
|
||||
| test.cpp:846:13:846:27 | call to indirect_source | test.cpp:848:23:848:25 | rpx |
|
||||
| test.cpp:860:54:860:59 | call to source | test.cpp:861:10:861:37 | static_local_pointer_dynamic |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1052:8:1052:9 | & ... |
|
||||
| test.cpp:1058:12:1058:12 | a | test.cpp:1060:8:1060:9 | & ... |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
| true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x |
|
||||
@@ -313,7 +313,8 @@ irFlow
|
||||
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1027:19:1027:28 | *translated |
|
||||
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1031:19:1031:28 | *translated |
|
||||
| test.cpp:1045:14:1045:19 | call to source | test.cpp:1046:7:1046:10 | * ... |
|
||||
| test.cpp:1081:27:1081:34 | call to source | test.cpp:1081:27:1081:34 | call to source |
|
||||
| test.cpp:1052:13:1052:27 | *call to indirect_source | test.cpp:1054:7:1054:11 | * ... |
|
||||
| test.cpp:1089:27:1089:34 | call to source | test.cpp:1089:27:1089:34 | call to source |
|
||||
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
|
||||
@@ -1046,6 +1046,14 @@ void memset_test(char* buf) { // $ ast-def=buf ir-def=*buf
|
||||
sink(*buf); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void *realloc(void *, size_t);
|
||||
|
||||
void test_realloc() {
|
||||
int *src = indirect_source();
|
||||
int *dest = (int*)realloc(src, sizeof(int));
|
||||
sink(*dest); // $ ir, MISSING: ast
|
||||
}
|
||||
|
||||
void flow_out_of_address_with_local_flow() {
|
||||
MyStruct a;
|
||||
a.content = nullptr;
|
||||
|
||||
@@ -51,5 +51,5 @@ incorrectBaseType
|
||||
| test.cpp:848:23:848:25 | rpx | Expected 'Node.getType()' to be int, but it was int * |
|
||||
| test.cpp:854:10:854:36 | * ... | Expected 'Node.getType()' to be const int, but it was int |
|
||||
| test.cpp:867:10:867:30 | * ... | Expected 'Node.getType()' to be const int, but it was int |
|
||||
| test.cpp:1062:52:1062:53 | *& ... | Expected 'Node.getType()' to be char, but it was char * |
|
||||
| test.cpp:1070:52:1070:53 | *& ... | Expected 'Node.getType()' to be char, but it was char * |
|
||||
failures
|
||||
|
||||
@@ -54,5 +54,5 @@
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:797:20:797:20 | a |
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:797:31:797:31 | a |
|
||||
| test.cpp:796:12:796:12 | a | test.cpp:798:17:798:17 | a |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1051:3:1051:3 | a |
|
||||
| test.cpp:1050:12:1050:12 | a | test.cpp:1052:9:1052:9 | a |
|
||||
| test.cpp:1058:12:1058:12 | a | test.cpp:1059:3:1059:3 | a |
|
||||
| test.cpp:1058:12:1058:12 | a | test.cpp:1060:9:1060:9 | a |
|
||||
|
||||
@@ -6597,38 +6597,45 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| taint.cpp:729:27:729:32 | endptr | taint.cpp:729:26:729:32 | & ... | |
|
||||
| taint.cpp:731:7:731:12 | ref arg endptr | taint.cpp:732:8:732:13 | endptr | |
|
||||
| taint.cpp:732:8:732:13 | endptr | taint.cpp:732:7:732:13 | * ... | TAINT |
|
||||
| taint.cpp:738:17:738:31 | call to indirect_source | taint.cpp:739:30:739:35 | source | |
|
||||
| taint.cpp:739:22:739:28 | call to realloc | taint.cpp:740:7:740:10 | dest | |
|
||||
| taint.cpp:739:30:739:35 | source | taint.cpp:739:22:739:28 | call to realloc | TAINT |
|
||||
| taint.cpp:743:40:743:45 | buffer | taint.cpp:744:5:744:10 | buffer | |
|
||||
| taint.cpp:743:40:743:45 | buffer | taint.cpp:745:27:745:32 | buffer | |
|
||||
| taint.cpp:744:4:744:10 | * ... | taint.cpp:744:3:744:10 | * ... | TAINT |
|
||||
| taint.cpp:744:5:744:10 | buffer | taint.cpp:744:4:744:10 | * ... | TAINT |
|
||||
| taint.cpp:744:14:744:19 | call to source | taint.cpp:744:3:744:21 | ... = ... | |
|
||||
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:743:40:743:45 | buffer | |
|
||||
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:745:3:745:37 | ... = ... | |
|
||||
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:746:10:746:15 | buffer | |
|
||||
| taint.cpp:745:27:745:32 | buffer | taint.cpp:745:19:745:25 | call to realloc | TAINT |
|
||||
| taint.cpp:746:9:746:15 | * ... | taint.cpp:746:8:746:15 | * ... | TAINT |
|
||||
| taint.cpp:746:10:746:15 | buffer | taint.cpp:746:9:746:15 | * ... | TAINT |
|
||||
| taint.cpp:751:31:751:34 | path | taint.cpp:751:31:751:34 | path | |
|
||||
| taint.cpp:751:31:751:34 | path | taint.cpp:752:10:752:13 | path | |
|
||||
| taint.cpp:751:31:751:34 | path | taint.cpp:753:10:753:13 | path | |
|
||||
| taint.cpp:751:43:751:46 | data | taint.cpp:751:43:751:46 | data | |
|
||||
| taint.cpp:751:43:751:46 | data | taint.cpp:753:22:753:25 | data | |
|
||||
| taint.cpp:752:10:752:13 | ref arg path | taint.cpp:751:31:751:34 | path | |
|
||||
| taint.cpp:752:10:752:13 | ref arg path | taint.cpp:753:10:753:13 | path | |
|
||||
| taint.cpp:752:16:752:19 | %s | taint.cpp:752:10:752:13 | ref arg path | TAINT |
|
||||
| taint.cpp:752:22:752:26 | abc | taint.cpp:752:10:752:13 | ref arg path | TAINT |
|
||||
| taint.cpp:753:10:753:13 | ref arg path | taint.cpp:751:31:751:34 | path | |
|
||||
| taint.cpp:753:16:753:19 | %s | taint.cpp:753:10:753:13 | ref arg path | TAINT |
|
||||
| taint.cpp:753:22:753:25 | data | taint.cpp:753:10:753:13 | ref arg path | TAINT |
|
||||
| taint.cpp:753:22:753:25 | ref arg data | taint.cpp:751:43:751:46 | data | |
|
||||
| taint.cpp:757:7:757:10 | path | taint.cpp:758:21:758:24 | path | |
|
||||
| taint.cpp:757:7:757:10 | path | taint.cpp:759:8:759:11 | path | |
|
||||
| taint.cpp:758:21:758:24 | ref arg path | taint.cpp:759:8:759:11 | path | |
|
||||
| taint.cpp:759:8:759:11 | path | taint.cpp:759:7:759:11 | * ... | |
|
||||
| taint.cpp:769:37:769:42 | call to source | taint.cpp:770:7:770:9 | obj | |
|
||||
| taint.cpp:739:17:739:31 | call to indirect_source | taint.cpp:740:30:740:35 | source | |
|
||||
| taint.cpp:740:22:740:28 | call to realloc | taint.cpp:741:7:741:10 | dest | |
|
||||
| taint.cpp:740:30:740:35 | source | taint.cpp:740:22:740:28 | call to realloc | TAINT |
|
||||
| taint.cpp:744:40:744:45 | buffer | taint.cpp:745:5:745:10 | buffer | |
|
||||
| taint.cpp:744:40:744:45 | buffer | taint.cpp:746:27:746:32 | buffer | |
|
||||
| taint.cpp:745:4:745:10 | * ... | taint.cpp:745:3:745:10 | * ... | TAINT |
|
||||
| taint.cpp:745:5:745:10 | buffer | taint.cpp:745:4:745:10 | * ... | TAINT |
|
||||
| taint.cpp:745:14:745:19 | call to source | taint.cpp:745:3:745:21 | ... = ... | |
|
||||
| taint.cpp:746:19:746:25 | call to realloc | taint.cpp:744:40:744:45 | buffer | |
|
||||
| taint.cpp:746:19:746:25 | call to realloc | taint.cpp:746:3:746:37 | ... = ... | |
|
||||
| taint.cpp:746:19:746:25 | call to realloc | taint.cpp:747:10:747:15 | buffer | |
|
||||
| taint.cpp:746:27:746:32 | buffer | taint.cpp:746:19:746:25 | call to realloc | TAINT |
|
||||
| taint.cpp:747:9:747:15 | * ... | taint.cpp:747:8:747:15 | * ... | TAINT |
|
||||
| taint.cpp:747:10:747:15 | buffer | taint.cpp:747:9:747:15 | * ... | TAINT |
|
||||
| taint.cpp:752:13:752:18 | call to malloc | taint.cpp:753:2:753:2 | a | |
|
||||
| taint.cpp:752:13:752:18 | call to malloc | taint.cpp:754:22:754:22 | a | |
|
||||
| taint.cpp:753:2:753:2 | a [post update] | taint.cpp:754:22:754:22 | a | |
|
||||
| taint.cpp:753:2:753:16 | ... = ... | taint.cpp:753:5:753:5 | x [post update] | |
|
||||
| taint.cpp:753:9:753:14 | call to source | taint.cpp:753:2:753:16 | ... = ... | |
|
||||
| taint.cpp:754:14:754:20 | call to realloc | taint.cpp:755:7:755:8 | a2 | |
|
||||
| taint.cpp:754:22:754:22 | a | taint.cpp:754:14:754:20 | call to realloc | TAINT |
|
||||
| taint.cpp:760:31:760:34 | path | taint.cpp:760:31:760:34 | path | |
|
||||
| taint.cpp:760:31:760:34 | path | taint.cpp:761:10:761:13 | path | |
|
||||
| taint.cpp:760:31:760:34 | path | taint.cpp:762:10:762:13 | path | |
|
||||
| taint.cpp:760:43:760:46 | data | taint.cpp:760:43:760:46 | data | |
|
||||
| taint.cpp:760:43:760:46 | data | taint.cpp:762:22:762:25 | data | |
|
||||
| taint.cpp:761:10:761:13 | ref arg path | taint.cpp:760:31:760:34 | path | |
|
||||
| taint.cpp:761:10:761:13 | ref arg path | taint.cpp:762:10:762:13 | path | |
|
||||
| taint.cpp:761:16:761:19 | %s | taint.cpp:761:10:761:13 | ref arg path | TAINT |
|
||||
| taint.cpp:761:22:761:26 | abc | taint.cpp:761:10:761:13 | ref arg path | TAINT |
|
||||
| taint.cpp:762:10:762:13 | ref arg path | taint.cpp:760:31:760:34 | path | |
|
||||
| taint.cpp:762:16:762:19 | %s | taint.cpp:762:10:762:13 | ref arg path | TAINT |
|
||||
| taint.cpp:762:22:762:25 | data | taint.cpp:762:10:762:13 | ref arg path | TAINT |
|
||||
| taint.cpp:762:22:762:25 | ref arg data | taint.cpp:760:43:760:46 | data | |
|
||||
| taint.cpp:766:7:766:10 | path | taint.cpp:767:21:767:24 | path | |
|
||||
| taint.cpp:766:7:766:10 | path | taint.cpp:768:8:768:11 | path | |
|
||||
| taint.cpp:767:21:767:24 | ref arg path | taint.cpp:768:8:768:11 | path | |
|
||||
| taint.cpp:768:8:768:11 | path | taint.cpp:768:7:768:11 | * ... | |
|
||||
| taint.cpp:778:37:778:42 | call to source | taint.cpp:779:7:779:9 | obj | |
|
||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
|
||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
|
||||
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |
|
||||
|
||||
@@ -732,6 +732,7 @@ void test_strtol(char *source) {
|
||||
sink(*endptr); // $ ast,ir
|
||||
}
|
||||
|
||||
void *malloc(size_t);
|
||||
void *realloc(void *, size_t);
|
||||
|
||||
void test_realloc() {
|
||||
@@ -746,6 +747,14 @@ void test_realloc_2_indirections(int **buffer) {
|
||||
sink(**buffer); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void test_realloc_struct_field() {
|
||||
struct A { int x; };
|
||||
A* a = (A*)malloc(sizeof(A));
|
||||
a->x = source();
|
||||
A* a2 = (A*)realloc(a, sizeof(A));
|
||||
sink(a2->x); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
int sprintf(char *, const char *, ...);
|
||||
|
||||
void call_sprintf_twice(char* path, char* data) {
|
||||
|
||||
Reference in New Issue
Block a user