Merge branch 'main' into henrymercer/polish-diagnostics

This commit is contained in:
Arthur Baars
2023-03-14 23:42:33 +01:00
committed by GitHub
824 changed files with 32300 additions and 2361 deletions

View File

@@ -55,12 +55,12 @@ jobs:
id: cache-extractor
with:
path: |
ruby/target/release/ruby-autobuilder
ruby/target/release/ruby-autobuilder.exe
ruby/target/release/ruby-extractor
ruby/target/release/ruby-extractor.exe
ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }}--${{ hashFiles('ruby/**/*.rs') }}
ruby/extractor/target/release/autobuilder
ruby/extractor/target/release/autobuilder.exe
ruby/extractor/target/release/extractor
ruby/extractor/target/release/extractor.exe
ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}--${{ hashFiles('ruby/extractor/**/*.rs') }}
- uses: actions/cache@v3
if: steps.cache-extractor.outputs.cache-hit != 'true'
with:
@@ -68,22 +68,22 @@ jobs:
~/.cargo/registry
~/.cargo/git
ruby/target
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-rust-cargo-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }}
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-rust-cargo-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/**/Cargo.lock') }}
- name: Check formatting
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cargo fmt --all -- --check
run: cd extractor && cargo fmt --all -- --check
- name: Build
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cargo build --verbose
run: cd extractor && cargo build --verbose
- name: Run tests
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cargo test --verbose
run: cd extractor && cargo test --verbose
- name: Release build
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cargo build --release
run: cd extractor && cargo build --release
- name: Generate dbscheme
if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}}
run: target/release/ruby-generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
run: extractor/target/release/generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
- uses: actions/upload-artifact@v3
if: ${{ matrix.os == 'ubuntu-latest' }}
with:
@@ -98,10 +98,10 @@ jobs:
with:
name: extractor-${{ matrix.os }}
path: |
ruby/target/release/ruby-autobuilder
ruby/target/release/ruby-autobuilder.exe
ruby/target/release/ruby-extractor
ruby/target/release/ruby-extractor.exe
ruby/extractor/target/release/autobuilder
ruby/extractor/target/release/autobuilder.exe
ruby/extractor/target/release/extractor
ruby/extractor/target/release/extractor.exe
retention-days: 1
compile-queries:
runs-on: ubuntu-latest-xl
@@ -116,21 +116,22 @@ jobs:
key: ruby-build
- name: Build Query Pack
run: |
rm -rf target/packs
codeql pack create ../misc/suite-helpers --output target/packs
codeql pack create ../shared/regex --output target/packs
codeql pack create ../shared/ssa --output target/packs
codeql pack create ../shared/tutorial --output target/packs
codeql pack create ql/lib --output target/packs
codeql pack create -j0 ql/src --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
PACKS=${{ runner.temp }}/query-packs
rm -rf $PACKS
codeql pack create ../misc/suite-helpers --output "$PACKS"
codeql pack create ../shared/regex --output "$PACKS"
codeql pack create ../shared/ssa --output "$PACKS"
codeql pack create ../shared/tutorial --output "$PACKS"
codeql pack create ql/lib --output "$PACKS"
codeql pack create -j0 ql/src --output "$PACKS" --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
PACK_FOLDER=$(readlink -f "$PACKS"/codeql/ruby-queries/*)
codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
(cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)
- uses: actions/upload-artifact@v3
with:
name: codeql-ruby-queries
path: |
ruby/target/packs/*
${{ runner.temp }}/query-packs/*
retention-days: 1
package:
@@ -158,12 +159,12 @@ jobs:
mkdir -p ruby
cp -r codeql-extractor.yml tools ql/lib/ruby.dbscheme.stats ruby/
mkdir -p ruby/tools/{linux64,osx64,win64}
cp linux64/ruby-autobuilder ruby/tools/linux64/autobuilder
cp osx64/ruby-autobuilder ruby/tools/osx64/autobuilder
cp win64/ruby-autobuilder.exe ruby/tools/win64/autobuilder.exe
cp linux64/ruby-extractor ruby/tools/linux64/extractor
cp osx64/ruby-extractor ruby/tools/osx64/extractor
cp win64/ruby-extractor.exe ruby/tools/win64/extractor.exe
cp linux64/autobuilder ruby/tools/linux64/autobuilder
cp osx64/autobuilder ruby/tools/osx64/autobuilder
cp win64/autobuilder.exe ruby/tools/win64/autobuilder.exe
cp linux64/extractor ruby/tools/linux64/extractor
cp osx64/extractor ruby/tools/osx64/extractor
cp win64/extractor.exe ruby/tools/win64/extractor.exe
chmod +x ruby/tools/{linux64,osx64}/{autobuilder,extractor}
zip -rq codeql-ruby.zip ruby
- uses: actions/upload-artifact@v3

View File

@@ -0,0 +1,12 @@
---
category: minorAnalysis
---
* Deleted the deprecated `hasGeneratedCopyConstructor` and `hasGeneratedCopyAssignmentOperator` predicates from the `Folder` class.
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getMustlockFunction`, `getTrylockFunction`, `getLockFunction`, and `getUnlockFunction` predicates from the `MutexType` class.
* Deleted the deprecated `getPosInBasicBlock` predicate from the `SubBasicBlock` class.
* Deleted the deprecated `getExpr` predicate from the `PointerDereferenceExpr` class.
* Deleted the deprecated `getUseInstruction` and `getDefinitionInstruction` predicates from the `Operand` class.
* Deleted the deprecated `isInParameter`, `isInParameterPointer`, and `isInQualifier` predicates from the `FunctionInput` class.
* Deleted the deprecated `isOutParameterPointer`, `isOutQualifier`, `isOutReturnValue`, and `isOutReturnPointer` predicate from the `FunctionOutput` class.
* Deleted the deprecated 3-argument `isGuardPhi` predicate from the `RangeSsaDefinition` class.

View File

@@ -182,6 +182,7 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
not expectsContent(node, _) and
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeDataFlowType(node))
else any()

View File

@@ -936,6 +936,15 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
bounded(cast.getOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
}
/**
* Computes a normal form of `x` where -0.0 has changed to +0.0. This can be
* needed on the lesser side of a floating-point comparison or on both sides of
* a floating point equality because QL does not follow IEEE in floating-point
* comparisons but instead defines -0.0 to be less than and distinct from 0.0.
*/
bindingset[x]
private float normalizeFloatUp(float x) { result = x + 0.0 }
/**
* Holds if `b + delta` is a valid bound for `e`.
* - `upper = true` : `e <= b + delta`
@@ -1020,6 +1029,15 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
or
upper = false and delta = D::fromFloat(D::toFloat(d1).minimum(D::toFloat(d2)))
)
or
exists(SemExpr mid, D::Delta d, float f |
e.(SemNegateExpr).getOperand() = mid and
b instanceof SemZeroBound and
bounded(mid, b, d, upper.booleanNot(), fromBackEdge, origdelta, reason) and
f = normalizeFloatUp(-D::toFloat(d)) and
delta = D::fromFloat(f) and
if semPositive(e) then f >= 0 else any()
)
)
}

View File

@@ -227,18 +227,6 @@ class Class extends UserType {
result = this.accessOfBaseMember(member.getDeclaringType(), member.getASpecifier())
}
/**
* DEPRECATED: name changed to `hasImplicitCopyConstructor` to reflect that
* `= default` members are no longer included.
*/
deprecated predicate hasGeneratedCopyConstructor() { this.hasImplicitCopyConstructor() }
/**
* DEPRECATED: name changed to `hasImplicitCopyAssignmentOperator` to
* reflect that `= default` members are no longer included.
*/
deprecated predicate hasGeneratedCopyAssignmentOperator() { this.hasImplicitCopyConstructor() }
/**
* Holds if this class, struct or union has an implicitly-declared copy
* constructor that is not _deleted_. This predicate is more accurate than

View File

@@ -108,20 +108,6 @@ class XmlFile extends XmlParent, File {
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
/**
* DEPRECATED: Use `getAbsolutePath()` instead.
*
* Gets the path of this XML file.
*/
deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }

View File

@@ -59,26 +59,6 @@ abstract class MutexType extends Type {
* Gets a call that unlocks any mutex of this type.
*/
FunctionCall getUnlockAccess() { this.unlockAccess(result, _) }
/**
* DEPRECATED: use mustlockAccess(fc, arg) instead.
*/
deprecated Function getMustlockFunction() { result = this.getMustlockAccess().getTarget() }
/**
* DEPRECATED: use trylockAccess(fc, arg) instead.
*/
deprecated Function getTrylockFunction() { result = this.getTrylockAccess().getTarget() }
/**
* DEPRECATED: use lockAccess(fc, arg) instead.
*/
deprecated Function getLockFunction() { result = this.getLockAccess().getTarget() }
/**
* DEPRECATED: use unlockAccess(fc, arg) instead.
*/
deprecated Function getUnlockFunction() { result = this.getUnlockAccess().getTarget() }
}
/**

View File

@@ -75,13 +75,6 @@ class SubBasicBlock extends ControlFlowNodeBase {
)
}
/**
* DEPRECATED: use `getRankInBasicBlock` instead. Note that this predicate
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
* position.
*/
deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
pragma[noinline]
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }

View File

@@ -182,6 +182,7 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
not expectsContent(node, _) and
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeDataFlowType(node))
else any()

View File

@@ -75,13 +75,6 @@ class SubBasicBlock extends ControlFlowNodeBase {
)
}
/**
* DEPRECATED: use `getRankInBasicBlock` instead. Note that this predicate
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
* position.
*/
deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
pragma[noinline]
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }

View File

@@ -719,13 +719,6 @@ class ReferenceToExpr extends Conversion, @reference_to {
class PointerDereferenceExpr extends UnaryOperation, @indirect {
override string getAPrimaryQlClass() { result = "PointerDereferenceExpr" }
/**
* DEPRECATED: Use getOperand() instead.
*
* Gets the expression that is being dereferenced.
*/
deprecated Expr getExpr() { result = this.getOperand() }
override string getOperator() { result = "*" }
override int getPrecedence() { result = 16 }

View File

@@ -182,6 +182,7 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
not expectsContent(node, _) and
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeDataFlowType(node))
else any()

View File

@@ -87,22 +87,6 @@ class Operand extends TStageOperand {
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* DEPRECATED: renamed to `getUse`.
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
* predicate is `getAnyDef`, but most uses of this predicate should probably
* be replaced with `getDef`.
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
*/

View File

@@ -87,22 +87,6 @@ class Operand extends TStageOperand {
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* DEPRECATED: renamed to `getUse`.
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
* predicate is `getAnyDef`, but most uses of this predicate should probably
* be replaced with `getDef`.
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
*/

View File

@@ -87,22 +87,6 @@ class Operand extends TStageOperand {
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* DEPRECATED: renamed to `getUse`.
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
* predicate is `getAnyDef`, but most uses of this predicate should probably
* be replaced with `getDef`.
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
*/

View File

@@ -40,12 +40,6 @@ class FunctionInput extends TFunctionInput {
*/
predicate isParameter(ParameterIndex index) { none() }
/**
* Holds if this is the input value of the parameter with index `index`.
* DEPRECATED: Use `isParameter(index)` instead.
*/
deprecated final predicate isInParameter(ParameterIndex index) { this.isParameter(index) }
/**
* Holds if this is the input value pointed to (through `ind` number of indirections) by a
* pointer parameter to a function, or the input value referred to by a reference parameter
@@ -84,16 +78,6 @@ class FunctionInput extends TFunctionInput {
*/
predicate isParameterDeref(ParameterIndex index) { this.isParameterDeref(index, 1) }
/**
* Holds if this is the input value pointed to by a pointer parameter to a function, or the input
* value referred to by a reference parameter to a function, where the parameter has index
* `index`.
* DEPRECATED: Use `isParameterDeref(index)` instead.
*/
deprecated final predicate isInParameterPointer(ParameterIndex index) {
this.isParameterDeref(index)
}
/**
* Holds if this is the input value pointed to by the `this` pointer of an instance member
* function.
@@ -124,13 +108,6 @@ class FunctionInput extends TFunctionInput {
*/
predicate isQualifierObject() { this.isQualifierObject(1) }
/**
* Holds if this is the input value pointed to by the `this` pointer of an instance member
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
deprecated final predicate isInQualifier() { this.isQualifierObject() }
/**
* Holds if this is the input value of the `this` pointer of an instance member function.
*
@@ -396,16 +373,6 @@ class FunctionOutput extends TFunctionOutput {
*/
predicate isParameterDeref(ParameterIndex i, int ind) { ind = 1 and this.isParameterDeref(i) }
/**
* Holds if this is the output value pointed to by a pointer parameter to a function, or the
* output value referred to by a reference parameter to a function, where the parameter has
* index `index`.
* DEPRECATED: Use `isParameterDeref(index)` instead.
*/
deprecated final predicate isOutParameterPointer(ParameterIndex index) {
this.isParameterDeref(index)
}
/**
* Holds if this is the output value pointed to by the `this` pointer of an instance member
* function.
@@ -436,13 +403,6 @@ class FunctionOutput extends TFunctionOutput {
*/
predicate isQualifierObject(int ind) { ind = 1 and this.isQualifierObject() }
/**
* Holds if this is the output value pointed to by the `this` pointer of an instance member
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
deprecated final predicate isOutQualifier() { this.isQualifierObject() }
/**
* Holds if this is the value returned by a function.
*
@@ -462,12 +422,6 @@ class FunctionOutput extends TFunctionOutput {
*/
predicate isReturnValue() { none() }
/**
* Holds if this is the value returned by a function.
* DEPRECATED: Use `isReturnValue()` instead.
*/
deprecated final predicate isOutReturnValue() { this.isReturnValue() }
/**
* Holds if this is the output value pointed to by the return value of a function, if the function
* returns a pointer, or the output value referred to by the return value of a function, if the
@@ -508,14 +462,6 @@ class FunctionOutput extends TFunctionOutput {
*/
predicate isReturnValueDeref(int ind) { ind = 1 and this.isReturnValueDeref() }
/**
* Holds if this is the output value pointed to by the return value of a function, if the function
* returns a pointer, or the output value referred to by the return value of a function, if the
* function returns a reference.
* DEPRECATED: Use `isReturnValueDeref()` instead.
*/
deprecated final predicate isOutReturnPointer() { this.isReturnValueDeref() }
/**
* Holds if `i >= 0` and `isParameterDeref(i, ind)` holds for this is the value, or
* if `i = -1` and `isQualifierObject(ind)` holds for this value.

View File

@@ -96,15 +96,6 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
/** Whether this definition is a phi node for variable `v`. */
predicate isPhiNode(StackVariable v) { exists(RangeSsa x | x.phi_node(v, this)) }
/**
* DEPRECATED: Use isGuardPhi/4 instead
* If this definition is a phi node corresponding to a guard,
* then return the variable access and the guard.
*/
deprecated predicate isGuardPhi(VariableAccess va, Expr guard, boolean branch) {
guard_defn(va, guard, this, branch)
}
/**
* If this definition is a phi node corresponding to a guard,
* then return the variable guarded, the variable access and the guard.

View File

@@ -231,8 +231,8 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=11 range=>=3
int c = -a;
range(c);
range(b+c); // $ range=<=10 range="<=+ ...:a-1" range=">=- ...+1"
range(c); // $ range=<=-3 range=>=-11
range(b+c); // $ range=<=10 range="<=+ ...:a-1" range=">=- ...+1" range=>=-10
total += b+c;
range(total);
}
@@ -241,8 +241,8 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=11 range=>=0
int c = -a;
range(c);
range(b+c); // $ range=<=11 range="<=+ ...:a+0" range=">=- ...+0"
range(c); // $ range=<=0 range=>=-11
range(b+c); // $ range=<=11 range="<=+ ...:a+0" range=">=- ...+0" range=>=-11
total += b+c;
range(total);
}
@@ -251,7 +251,7 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=11 range=>=-7
int c = -a;
range(c);
range(c); // $ range=<=7 range=>=-11
range(b+c);
total += b+c;
range(total);
@@ -261,7 +261,7 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=1 range=>=-7
int c = -a;
range(c);
range(c); // $ range=<=7 range=>=-1
range(b+c);
total += b+c;
range(total);
@@ -271,8 +271,8 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=0 range=>=-7
int c = -a;
range(c);
range(b+c); // $ range="<=- ...+0" range=">=+ ...:a+0" range=>=-7
range(c); // $ range=<=7 range=>=0
range(b+c); // $ range="<=- ...+0" range=">=+ ...:a+0" range=>=-7 range=<=7
total += b+c;
range(total);
}
@@ -281,8 +281,8 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=-2 range=>=-7
int c = -a;
range(c);
range(b+c); // $ range="<=- ...-1" range=">=+ ...:a+1" range=>=-6
range(c); // $ range=<=7 range=>=2
range(b+c); // $ range="<=- ...-1" range=">=+ ...:a+1" range=>=-6 range=<=6
total += b+c;
range(total);
}
@@ -552,7 +552,7 @@ int test16(int x) {
range(x); // $ range=<=-1 range=>=0
return 1;
}
range(d); // $ range===3
range(d); // $ range=<=0 range=>=3 // Unreachable code
range(x); // $ range=<=-1 range=>=0
}
range(x); // $ range=>=0
@@ -997,3 +997,15 @@ void test_overflow() {
range(x + y); // $ range===-2147483393
}
}
void test_negate_unsigned(unsigned u) {
if(10 < u && u < 20) {
range<unsigned>(-u); // underflows
}
}
void test_negate_signed(int s) {
if(10 < s && s < 20) {
range<int>(-s); // $ range=<=-11 range=>=-19
}
}

View File

@@ -0,0 +1,6 @@
---
category: minorAnalysis
---
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getAssertionIndex`, and `getAssertedParameter` predicates from the `AssertMethod` class.
* Deleted the deprecated `OverridableMethod` and `OverridableAccessor` classes.

View File

@@ -108,20 +108,6 @@ class XmlFile extends XmlParent, File {
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
/**
* DEPRECATED: Use `getAbsolutePath()` instead.
*
* Gets the path of this XML file.
*/
deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }

View File

@@ -37,26 +37,6 @@ abstract class AssertMethod extends Method {
/** Gets the index of a parameter being asserted. */
abstract int getAnAssertionIndex();
/**
* DEPRECATED: Use `getAnAssertionIndex()` instead.
*
* Gets the index of a parameter being asserted.
*/
deprecated final int getAssertionIndex() { result = this.getAnAssertionIndex() }
/** Gets the parameter at position `i` being asserted. */
final Parameter getAssertedParameter(int i) {
result = this.getParameter(i) and
i = this.getAnAssertionIndex()
}
/**
* DEPRECATED: Use `getAssertedParameter(_)` instead.
*
* Gets a parameter being asserted.
*/
deprecated final Parameter getAssertedParameter() { result = this.getAssertedParameter(_) }
/** Gets the failure type if the assertion fails for argument `i`, if any. */
abstract AssertionFailure getAssertionFailure(int i);
}

View File

@@ -182,6 +182,7 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
not expectsContent(node, _) and
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeDataFlowType(node))
else any()

View File

@@ -301,8 +301,8 @@ module Private {
TWithoutContentSummaryComponent(ContentSet c) or
TWithContentSummaryComponent(ContentSet c)
private TParameterSummaryComponent thisParam() {
result = TParameterSummaryComponent(instanceParameterPosition())
private TParameterSummaryComponent callbackSelfParam() {
result = TParameterSummaryComponent(callbackSelfParameterPosition())
}
newtype TSummaryComponentStack =
@@ -311,7 +311,7 @@ module Private {
any(RequiredSummaryComponentStack x).required(head, tail)
or
any(RequiredSummaryComponentStack x).required(TParameterSummaryComponent(_), tail) and
head = thisParam()
head = callbackSelfParam()
or
derivedFluentFlowPush(_, _, _, head, tail, _)
}
@@ -336,7 +336,7 @@ module Private {
callbackRef = s.drop(_) and
(isCallbackParameter(callbackRef) or callbackRef.head() = TReturnSummaryComponent(_)) and
input = callbackRef.tail() and
output = TConsSummaryComponentStack(thisParam(), input) and
output = TConsSummaryComponentStack(callbackSelfParam(), input) and
preservesValue = true
)
or
@@ -439,6 +439,9 @@ module Private {
out.head() = TParameterSummaryComponent(_) and
s = out.tail()
)
or
// Add the post-update node corresponding to the requested argument node
outputState(c, s) and isCallbackParameter(s)
}
private newtype TSummaryNodeState =
@@ -1012,7 +1015,7 @@ module Private {
private predicate relevantSummaryElementGenerated(
AccessPath inSpec, AccessPath outSpec, string kind
) {
summaryElement(this, inSpec, outSpec, kind, "generated") and
summaryElement(this, inSpec, outSpec, kind, ["generated", "ai-generated"]) and
not summaryElement(this, _, _, _, "manual")
}

View File

@@ -22,7 +22,7 @@ class SummarizedCallableBase extends Callable {
DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c }
/** Gets the parameter position of the instance parameter. */
ArgumentPosition instanceParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks
ArgumentPosition callbackSelfParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks
/** Gets the synthesized summary data-flow node for the given values. */
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) }

View File

@@ -162,12 +162,6 @@ class OverridableCallable extends Callable, Overridable {
}
}
/** An overridable method. */
deprecated class OverridableMethod extends Method, OverridableCallable { }
/** An overridable accessor. */
deprecated class OverridableAccessor extends Accessor, OverridableCallable { }
/** An unbound type. */
class UnboundDeclarationType extends Type {
UnboundDeclarationType() { this.isUnboundDeclaration() }

View File

@@ -87,22 +87,6 @@ class Operand extends TStageOperand {
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* DEPRECATED: renamed to `getUse`.
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
* predicate is `getAnyDef`, but most uses of this predicate should probably
* be replaced with `getDef`.
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
*/

View File

@@ -87,22 +87,6 @@ class Operand extends TStageOperand {
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* DEPRECATED: renamed to `getUse`.
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
* predicate is `getAnyDef`, but most uses of this predicate should probably
* be replaced with `getDef`.
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
*/

View File

@@ -32,12 +32,6 @@ module AliasModels {
*/
predicate isParameter(ParameterIndex index) { none() }
/**
* Holds if this is the input value of the parameter with index `index`.
* DEPRECATED: Use `isParameter(index)` instead.
*/
deprecated final predicate isInParameter(ParameterIndex index) { this.isParameter(index) }
/**
* Holds if this is the input value pointed to by a pointer parameter to a function, or the input
* value referred to by a reference parameter to a function, where the parameter has index
@@ -71,13 +65,6 @@ module AliasModels {
*/
predicate isQualifierObject() { none() }
/**
* Holds if this is the input value pointed to by the `this` pointer of an instance member
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
deprecated final predicate isInQualifier() { this.isQualifierObject() }
/**
* Holds if this is the input value of the `this` pointer of an instance member function.
*
@@ -182,13 +169,6 @@ module AliasModels {
*/
predicate isQualifierObject() { none() }
/**
* Holds if this is the output value pointed to by the `this` pointer of an instance member
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
deprecated final predicate isOutQualifier() { this.isQualifierObject() }
/**
* Holds if this is the value returned by a function.
*
@@ -208,12 +188,6 @@ module AliasModels {
*/
predicate isReturnValue() { none() }
/**
* Holds if this is the value returned by a function.
* DEPRECATED: Use `isReturnValue()` instead.
*/
deprecated final predicate isOutReturnValue() { this.isReturnValue() }
/**
* Holds if this is the output value pointed to by the return value of a function, if the function
* returns a pointer, or the output value referred to by the return value of a function, if the
@@ -234,14 +208,6 @@ module AliasModels {
*/
predicate isReturnValueDeref() { none() }
/**
* Holds if this is the output value pointed to by the return value of a function, if the function
* returns a pointer, or the output value referred to by the return value of a function, if the
* function returns a reference.
* DEPRECATED: Use `isReturnValueDeref()` instead.
*/
deprecated final predicate isOutReturnPointer() { this.isReturnValueDeref() }
/**
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this is the value, or
* if `i = -1` and `isQualifierObject()` holds for this value.

View File

@@ -182,6 +182,7 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
not expectsContent(node, _) and
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeDataFlowType(node))
else any()

View File

@@ -301,8 +301,8 @@ module Private {
TWithoutContentSummaryComponent(ContentSet c) or
TWithContentSummaryComponent(ContentSet c)
private TParameterSummaryComponent thisParam() {
result = TParameterSummaryComponent(instanceParameterPosition())
private TParameterSummaryComponent callbackSelfParam() {
result = TParameterSummaryComponent(callbackSelfParameterPosition())
}
newtype TSummaryComponentStack =
@@ -311,7 +311,7 @@ module Private {
any(RequiredSummaryComponentStack x).required(head, tail)
or
any(RequiredSummaryComponentStack x).required(TParameterSummaryComponent(_), tail) and
head = thisParam()
head = callbackSelfParam()
or
derivedFluentFlowPush(_, _, _, head, tail, _)
}
@@ -336,7 +336,7 @@ module Private {
callbackRef = s.drop(_) and
(isCallbackParameter(callbackRef) or callbackRef.head() = TReturnSummaryComponent(_)) and
input = callbackRef.tail() and
output = TConsSummaryComponentStack(thisParam(), input) and
output = TConsSummaryComponentStack(callbackSelfParam(), input) and
preservesValue = true
)
or
@@ -439,6 +439,9 @@ module Private {
out.head() = TParameterSummaryComponent(_) and
s = out.tail()
)
or
// Add the post-update node corresponding to the requested argument node
outputState(c, s) and isCallbackParameter(s)
}
private newtype TSummaryNodeState =
@@ -1012,7 +1015,7 @@ module Private {
private predicate relevantSummaryElementGenerated(
AccessPath inSpec, AccessPath outSpec, string kind
) {
summaryElement(this, inSpec, outSpec, kind, "generated") and
summaryElement(this, inSpec, outSpec, kind, ["generated", "ai-generated"]) and
not summaryElement(this, _, _, _, "manual")
}

View File

@@ -20,7 +20,7 @@ class SummarizedCallableBase = Callable;
DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c }
/** Gets the parameter position of the instance parameter. */
ArgumentPosition instanceParameterPosition() { result = -1 }
ArgumentPosition callbackSelfParameterPosition() { result = -1 }
/** Gets the textual representation of a parameter position in the format used for flow summaries. */
string getParameterPosition(ParameterPosition pos) { result = pos.toString() }

View File

@@ -38,12 +38,13 @@ jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,
jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55
java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
java.io,37,,42,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,41,1
java.lang,14,,76,,,,,,,,,,,,8,,,,,1,,4,,,1,,,,,,,,,,,,,,,,53,23
java.io,42,,42,,17,,,,,,,,,,,,,,,3,,,,,,,,,,,,,22,,,,,,,,41,1
java.lang,16,,76,,,,,,,,,,,,8,,,,,3,,4,,,1,,,,,,,,,,,,,,,,53,23
java.net,10,3,9,,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,,,3,9,
java.nio,16,,16,,13,,,,,,,,,,,,,,,1,,,,,,,,,,,,,2,,,,,,,,16,
java.sql,11,,2,,,,,,,,4,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,1,1
java.sql,13,,2,,,,,,,,4,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,1,1
java.util,44,,465,,,,,,,,,,,,34,,,,,,,,5,2,,1,2,,,,,,,,,,,,,,38,427
javafx.scene.web,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,,
javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57,
javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
@@ -66,6 +67,7 @@ okhttp3,2,,47,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,22,25
org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
org.apache.commons.compress.archivers.tar,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,
org.apache.commons.io,106,,560,,91,,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,546,14
org.apache.commons.jexl2,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
org.apache.commons.jexl3,15,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
@@ -80,7 +82,7 @@ org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39,
org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,
org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6
org.apache.hive.hcatalog.templeton,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,
org.apache.http,27,3,70,,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,,,2,,,,3,62,8
org.apache.http,27,3,77,,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,,,2,,,,3,69,8
org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,57,
org.apache.log4j,11,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,
org.apache.logging.log4j,359,,8,,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,,,,4,4
@@ -88,6 +90,7 @@ org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
org.apache.shiro.jndi,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
org.apache.velocity.app,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,,
org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,,
org.codehaus.cargo.container.installer,3,,,,2,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,
org.codehaus.groovy.control,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,,
org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,,
1 package sink source summary sink:bean-validation sink:create-file sink:fragment-injection sink:groovy sink:header-splitting sink:information-leak sink:intent-start sink:jdbc-url sink:jexl sink:jndi-injection sink:ldap sink:logging sink:mvel sink:ognl-injection sink:open-url sink:pending-intent-sent sink:read-file sink:regex-use sink:regex-use[-1] sink:regex-use[0] sink:regex-use[] sink:regex-use[f-1] sink:regex-use[f1] sink:regex-use[f] sink:set-hostname-verifier sink:sql sink:ssti sink:url-open-stream sink:url-redirect sink:write-file sink:xpath sink:xslt sink:xss source:android-external-storage-dir source:android-widget source:contentprovider source:remote summary:taint summary:value
38 jakarta.ws.rs.container 9 9
39 jakarta.ws.rs.core 2 149 2 94 55
40 java.beans 1 1
41 java.io 37 42 42 15 17 3 22 41 1
42 java.lang 14 16 76 8 1 3 4 1 53 23
43 java.net 10 3 9 10 3 9
44 java.nio 16 16 13 1 2 16
45 java.sql 11 13 2 4 7 9 1 1
46 java.util 44 465 34 5 2 1 2 38 427
47 javafx.scene.web 1 1
48 javax.faces.context 2 7 2 7
49 javax.jms 9 57 9 57
50 javax.json 123 100 23
67 org.apache.commons.codec 6 6
68 org.apache.commons.collections 800 17 783
69 org.apache.commons.collections4 800 17 783
70 org.apache.commons.compress.archivers.tar 2 2
71 org.apache.commons.io 106 560 91 15 546 14
72 org.apache.commons.jexl2 15 15
73 org.apache.commons.jexl3 15 15
82 org.apache.hc.core5.net 2 2
83 org.apache.hc.core5.util 24 18 6
84 org.apache.hive.hcatalog.templeton 1 1
85 org.apache.http 27 3 70 77 25 2 3 62 69 8
86 org.apache.ibatis.jdbc 6 57 6 57
87 org.apache.log4j 11 11
88 org.apache.logging.log4j 359 8 359 4 4
90 org.apache.shiro.jndi 1 1
91 org.apache.velocity.app 4 4
92 org.apache.velocity.runtime 4 4
93 org.codehaus.cargo.container.installer 3 2 1
94 org.codehaus.groovy.control 1 1
95 org.dom4j 20 20
96 org.hibernate 7 7

View File

@@ -13,15 +13,15 @@ Java framework & library support
`Apache Commons IO <https://commons.apache.org/proper/commons-io/>`_,``org.apache.commons.io``,,560,106,91,,,,,,15
`Apache Commons Lang <https://commons.apache.org/proper/commons-lang/>`_,``org.apache.commons.lang3``,,424,6,,,,,,,
`Apache Commons Text <https://commons.apache.org/proper/commons-text/>`_,``org.apache.commons.text``,,272,,,,,,,,
`Apache HttpComponents <https://hc.apache.org/>`_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25
`Apache HttpComponents <https://hc.apache.org/>`_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,143,28,,,3,,,,25
`Apache Log4j 2 <https://logging.apache.org/log4j/2.0/>`_,``org.apache.logging.log4j``,,8,359,,,,,,,
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,728,39,,6,,,,,
JBoss Logging,``org.jboss.logging``,,,324,,,,,,,
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,,
Java Standard Library,``java.*``,3,611,132,28,,,7,,,10
Java Standard Library,``java.*``,3,611,141,30,,,9,,,10
Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2
Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2
`Spring <https://spring.io/>`_,``org.springframework.*``,29,477,101,,,,19,14,,29
Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",60,300,273,,,,18,18,,3
Totals,,217,8458,1569,129,6,10,111,33,1,86
Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",60,302,277,2,,,18,18,,5
Totals,,217,8467,1582,133,6,10,113,33,1,88

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env python3
import glob
import os
import re
from create_database_utils import *
def say(s):
print(s)
sys.stdout.flush()
say('Doing normal compilation')
# This is a normal intercepted compilation
runSuccessfully([get_cmd('kotlinc'), 'normal.kt'])
say('Identifying extractor jar')
# Find the extractor jar that is being used
trapDir = os.environ['CODEQL_EXTRACTOR_JAVA_TRAP_DIR']
invocationTrapDir = os.path.join(trapDir, 'invocations')
invocationTraps = os.listdir(invocationTrapDir)
if len(invocationTraps) != 1:
raise Exception('Expected to find 1 invocation TRAP, but found ' + str(invocationTraps))
invocationTrap = os.path.join(invocationTrapDir, invocationTraps[0])
with open(invocationTrap, 'r') as f:
content = f.read()
m = re.search('^// Using extractor: (.*)$', content, flags = re.MULTILINE)
extractorJar = m.group(1)
def getManualFlags(invocationTrapName):
return ['-Xplugin=' + extractorJar, '-P', 'plugin:kotlin-extractor:invocationTrapFile=' + os.path.join(trapDir, 'invocations', invocationTrapName + '.trap')]
# This is both normally intercepted, and it has the extractor flags manually added
say('Doing double-interception compilation')
runSuccessfully([get_cmd('kotlinc'), 'doubleIntercepted.kt'] + getManualFlags('doubleIntercepted'))
os.environ['CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN'] = 'true'
# We don't see this compilation at all
say('Doing unseen compilation')
runSuccessfully([get_cmd('kotlinc'), 'notSeen.kt'])
# This is extracted as it has the extractor flags manually added
say('Doing manual compilation')
runSuccessfully([get_cmd('kotlinc'), 'manual.kt'] + getManualFlags('manual'))

View File

@@ -0,0 +1,3 @@
| code/doubleIntercepted.kt:0:0:0:0 | doubleIntercepted |
| code/manual.kt:0:0:0:0 | manual |
| code/normal.kt:0:0:0:0 | normal |

View File

@@ -0,0 +1,4 @@
import java
from File f
select f

View File

@@ -0,0 +1,7 @@
import sys
from create_database_utils import *
run_codeql_database_create(
['"%s" build.py' % sys.executable],
source="code", lang="java")

View File

@@ -0,0 +1,7 @@
---
category: minorAnalysis
---
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getRepresentedString` predicate from the `StringLiteral` class.
* Deleted the deprecated `ServletWriterSource` class.
* Deleted the deprecated `getGroupID`, `getArtefactID`, and `artefactMatches` predicates from the `MavenRepoJar` class.

View File

@@ -0,0 +1,11 @@
---
category: majorAnalysis
---
* Added more sink and summary dataflow models for the following packages:
* `java.io`
* `java.lang`
* `java.sql`
* `javafx.scene.web`
* `org.apache.commons.compress.archivers.tar`
* `org.apache.http.client.utils`
* `org.codehaus.cargo.container.installer`

View File

@@ -0,0 +1,4 @@
---
category: majorAnalysis
---
* Removed low-confidence call edges to known neutral call targets from the call graph used in data flow analysis. This includes, for example, custom `List.contains` implementations when the best inferrable type at the call site is simply `List`.

View File

@@ -3,8 +3,13 @@ extensions:
pack: codeql/java-all
extensible: sinkModel
data:
- ["java.io", "File", True, "createTempFile", "(String,String,File)", "", "Argument[2]", "create-file", "ai-generated"]
- ["java.io", "File", True, "renameTo", "(File)", "", "Argument[0]", "create-file", "ai-generated"]
- ["java.io", "FileInputStream", True, "FileInputStream", "(File)", "", "Argument[0]", "read-file", "ai-generated"]
- ["java.io", "FileOutputStream", False, "FileOutputStream", "", "", "Argument[0]", "create-file", "manual"]
- ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "write-file", "manual"]
- ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "read-file", "ai-generated"]
- ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "read-file", "ai-generated"]
- ["java.io", "FileWriter", False, "FileWriter", "", "", "Argument[0]", "create-file", "manual"]
- ["java.io", "PrintStream", False, "PrintStream", "(File)", "", "Argument[0]", "create-file", "manual"]
- ["java.io", "PrintStream", False, "PrintStream", "(File,Charset)", "", "Argument[0]", "create-file", "manual"]
@@ -86,7 +91,6 @@ extensions:
- ["java.io", "StringReader", False, "StringReader", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
- ["java.io", "Writer", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
- ["java.io", "Writer", True, "write", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
- addsTo:
pack: codeql/java-all
extensible: neutralModel

View File

@@ -3,13 +3,25 @@ extensions:
pack: codeql/java-all
extensible: sinkModel
data:
- ["java.lang", "Class", False, "getResource", "(String)", "", "Argument[0]", "read-file", "ai-generated"]
- ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "read-file", "ai-generated"]
- ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "read-file", "ai-generated"]
# suggested label is not supported: - ["java.lang", "ProcessBuilder", True, "ProcessBuilder", "(String[])", "", "Argument[0]", "command-injection", "ai-generated"]
# These are modeled in plain CodeQL. TODO: migrate them.
# - ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-generated"]
# - ["java.lang", "ProcessBuilder", True, "ProcessBuilder", "(String[])", "", "Argument[0]", "command-injection", "ai-generated"]
# - ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[2]", "command-injection", "ai-generated"]
# - ["java.lang", "Runtime", True, "exec", "(String)", "", "Argument[0]", "command-injection", "ai-generated"]
# - ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[0]", "command-injection", "ai-generated"]
# - ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[2]", "command-injection", "ai-generated"]
# - ["java.lang", "Runtime", True, "exec", "(String[])", "", "Argument[0]", "command-injection", "ai-generated"]
- ["java.lang", "String", False, "matches", "(String)", "", "Argument[0]", "regex-use[f-1]", "manual"]
- ["java.lang", "String", False, "replaceAll", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"]
- ["java.lang", "String", False, "replaceFirst", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"]
- ["java.lang", "String", False, "split", "(String)", "", "Argument[0]", "regex-use[-1]", "manual"]
- ["java.lang", "String", False, "split", "(String,int)", "", "Argument[0]", "regex-use[-1]", "manual"]
# These are modeled in plain CodeQL. TODO: migrate them.
# - ["java.lang", "System", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-generated"] # This is actually injecting a library.
# - ["java.lang", "System", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-generated"] # This is actually injecting a library.
- ["java.lang", "System$Logger", True, "log", "(Level,Object)", "", "Argument[1]", "logging", "manual"]
- ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Object[])", "", "Argument[2..3]", "logging", "manual"]
- ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Throwable)", "", "Argument[2]", "logging", "manual"]
@@ -98,7 +110,6 @@ extensions:
- ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
- ["java.lang", "Throwable", True, "getCause", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "ReturnValue", "value", "manual"]
- ["java.lang", "Throwable", True, "getMessage", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"]
- addsTo:
pack: codeql/java-all
extensible: neutralModel
@@ -131,7 +142,6 @@ extensions:
- ["java.lang", "System", "nanoTime", "()", "manual"]
- ["java.lang", "Thread", "currentThread", "()", "manual"]
- ["java.lang", "Thread", "sleep", "(long)", "manual"]
# The below APIs have numeric flow and are currently being stored as neutral models.
# These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future.
- ["java.lang", "Integer", "intValue", "()", "manual"] # taint-numeric

View File

@@ -5,6 +5,8 @@ extensions:
data:
- ["java.sql", "Connection", True, "prepareCall", "", "", "Argument[0]", "sql", "manual"]
- ["java.sql", "Connection", True, "prepareStatement", "", "", "Argument[0]", "sql", "manual"]
- ["java.sql", "DatabaseMetaData", True, "getColumns", "(String,String,String,String)", "", "Argument[2]", "sql", "ai-generated"]
- ["java.sql", "DatabaseMetaData", True, "getPrimaryKeys", "(String,String,String)", "", "Argument[2]", "sql", "ai-generated"]
- ["java.sql", "Driver", False, "connect", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"]
- ["java.sql", "DriverManager", False, "getConnection", "(String)", "", "Argument[0]", "jdbc-url", "manual"]
- ["java.sql", "DriverManager", False, "getConnection", "(String,Properties)", "", "Argument[0]", "jdbc-url", "manual"]
@@ -14,20 +16,17 @@ extensions:
- ["java.sql", "Statement", True, "executeLargeUpdate", "", "", "Argument[0]", "sql", "manual"]
- ["java.sql", "Statement", True, "executeQuery", "", "", "Argument[0]", "sql", "manual"]
- ["java.sql", "Statement", True, "executeUpdate", "", "", "Argument[0]", "sql", "manual"]
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data:
- ["java.sql", "PreparedStatement", True, "setString", "(int,String)", "", "Argument[1]", "Argument[-1]", "value", "manual"]
- ["java.sql", "ResultSet", True, "getString", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
- addsTo:
pack: codeql/java-all
extensible: neutralModel
data:
- ["java.sql", "ResultSet", "next", "()", "manual"]
# The below APIs have numeric flow and are currently being stored as neutral models.
# These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future.
- ["java.sql", "PreparedStatement", "setInt", "(int,int)", "manual"] # value-numeric

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: sinkModel
data:
- ["javafx.scene.web", "WebEngine", False, "load", "(String)", "", "Argument[0]", "open-url", "ai-generated"]

View File

@@ -0,0 +1,7 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data:
- ["org.apache.commons.compress.archivers.tar", "TarArchiveEntry", True, "TarArchiveEntry", "(String,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "ai-generated"]
- ["org.apache.commons.compress.archivers.tar", "TarArchiveEntry", True, "TarArchiveEntry", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "ai-generated"]

View File

@@ -0,0 +1,12 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data:
- ["org.apache.http.client.utils", "URIBuilder", True, "setHost", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "ai-generated"]
- ["org.apache.http.client.utils", "URIBuilder", True, "setHost", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"]
- ["org.apache.http.client.utils", "URIBuilder", True, "setPath", "(String)", "", "Argument[0]", "Argument[-1].SyntheticField[org.apache.http.client.utils.URIBuilder.path]", "taint", "ai-generated"]
- ["org.apache.http.client.utils", "URIBuilder", True, "setPathSegments", "(List)", "", "Argument[0]", "Argument[-1].SyntheticField[org.apache.http.client.utils.URIBuilder.path]", "taint", "ai-generated"]
- ["org.apache.http.client.utils", "URIBuilder", True, "URIBuilder", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "ai-generated"]
- ["org.apache.http.client.utils", "URIBuilder", True, "URIBuilder", "(URI)", "", "Argument[0]", "Argument[-1]", "taint", "ai-generated"]
- ["org.apache.http.client.utils", "URLEncodedUtils", True, "parse", "(URI,String)", "", "Argument[0]", "ReturnValue.Element", "taint", "ai-generated"]

View File

@@ -0,0 +1,8 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: sinkModel
data:
- ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[0]", "open-url", "ai-generated"]
- ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[1]", "create-file", "ai-generated"]
- ["org.codehaus.cargo.container.installer", "ZipURLInstaller", True, "ZipURLInstaller", "(URL,String,String)", "", "Argument[2]", "create-file", "ai-generated"]

View File

@@ -701,14 +701,6 @@ class StringLiteral extends Literal, @stringliteral {
*/
override string getValue() { result = super.getValue() }
/**
* DEPRECATED: This predicate will be removed in a future version because
* it is just an alias for `getValue()`; that predicate should be used instead.
*
* Gets the literal string without the quotes.
*/
deprecated string getRepresentedString() { result = this.getValue() }
/** Holds if this string literal is a text block (`""" ... """`). */
predicate isTextBlock() { this.getLiteral().matches("\"\"\"%") }

View File

@@ -132,9 +132,9 @@ private newtype TPrintAstNode =
TGenericTypeNode(GenericType ty) { shouldPrint(ty, _) } or
TGenericCallableNode(GenericCallable c) { shouldPrint(c, _) } or
TDocumentableNode(Documentable d) { shouldPrint(d, _) and exists(d.getJavadoc()) } or
TJavadocNode(Javadoc jd) { exists(Documentable d | d.getJavadoc() = jd | shouldPrint(d, _)) } or
TJavadocElementNode(JavadocElement jd) {
exists(Documentable d | d.getJavadoc() = jd.getParent*() | shouldPrint(d, _))
TJavadocNode(Javadoc jd, Documentable d) { d.getJavadoc() = jd and shouldPrint(d, _) } or
TJavadocElementNode(JavadocElement jd, Documentable d) {
d.getJavadoc() = jd.getParent*() and shouldPrint(d, _)
} or
TImportsNode(CompilationUnit cu) {
shouldPrint(cu, _) and exists(Import i | i.getCompilationUnit() = cu)
@@ -794,6 +794,7 @@ final class DocumentableNode extends PrintAstNode, TDocumentableNode {
override Location getLocation() { none() }
override JavadocNode getChild(int childIndex) {
result.getDocumentable() = d and
result.getJavadoc() =
rank[childIndex](Javadoc jd, string file, int line, int column |
jd.getCommentedElement() = d and jd.getLocation().hasLocationInfo(file, line, column, _, _)
@@ -814,14 +815,16 @@ final class DocumentableNode extends PrintAstNode, TDocumentableNode {
*/
final class JavadocNode extends PrintAstNode, TJavadocNode {
Javadoc jd;
Documentable d;
JavadocNode() { this = TJavadocNode(jd) }
JavadocNode() { this = TJavadocNode(jd, d) and not duplicateMetadata(d) }
override string toString() { result = getQlClass(jd) + jd.toString() }
override Location getLocation() { result = jd.getLocation() }
override JavadocElementNode getChild(int childIndex) {
result.getDocumentable() = d and
result.getJavadocElement() = jd.getChild(childIndex)
}
@@ -829,6 +832,11 @@ final class JavadocNode extends PrintAstNode, TJavadocNode {
* Gets the `Javadoc` represented by this node.
*/
Javadoc getJavadoc() { result = jd }
/**
* Gets the `Documentable` whose `Javadoc` is represented by this node.
*/
Documentable getDocumentable() { result = d }
}
/**
@@ -837,14 +845,16 @@ final class JavadocNode extends PrintAstNode, TJavadocNode {
*/
final class JavadocElementNode extends PrintAstNode, TJavadocElementNode {
JavadocElement jd;
Documentable d;
JavadocElementNode() { this = TJavadocElementNode(jd) }
JavadocElementNode() { this = TJavadocElementNode(jd, d) and not duplicateMetadata(d) }
override string toString() { result = getQlClass(jd) + jd.toString() }
override Location getLocation() { result = jd.getLocation() }
override JavadocElementNode getChild(int childIndex) {
result.getDocumentable() = d and
result.getJavadocElement() = jd.(JavadocParent).getChild(childIndex)
}
@@ -852,6 +862,11 @@ final class JavadocElementNode extends PrintAstNode, TJavadocElementNode {
* Gets the `JavadocElement` represented by this node.
*/
JavadocElement getJavadocElement() { result = jd }
/**
* Gets the `Documentable` whose `JavadocElement` is represented by this node.
*/
Documentable getDocumentable() { result = d }
}
/**

View File

@@ -171,6 +171,8 @@ class SummarizedCallableBase extends TSummarizedCallableBase {
class SummarizedCallable = Impl::Public::SummarizedCallable;
class NeutralCallable = Impl::Public::NeutralCallable;
/**
* An adapter class to add the flow summaries specified on `SyntheticCallable`
* to `SummarizedCallable`.

View File

@@ -11,6 +11,8 @@ private module DispatchImpl {
private predicate hasHighConfidenceTarget(Call c) {
exists(SummarizedCallable sc | sc.getACall() = c and not sc.isAutoGenerated())
or
exists(NeutralCallable nc | nc.getACall() = c and nc.isManual())
or
exists(Callable srcTgt |
srcTgt = VirtualDispatch::viableCallable(c) and
not VirtualDispatch::lowConfidenceDispatchTarget(c, srcTgt)

View File

@@ -182,6 +182,7 @@ private module LambdaFlow {
boolean toJump, DataFlowCallOption lastCall
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
not expectsContent(node, _) and
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypes(t, getNodeDataFlowType(node))
else any()

View File

@@ -301,8 +301,8 @@ module Private {
TWithoutContentSummaryComponent(ContentSet c) or
TWithContentSummaryComponent(ContentSet c)
private TParameterSummaryComponent thisParam() {
result = TParameterSummaryComponent(instanceParameterPosition())
private TParameterSummaryComponent callbackSelfParam() {
result = TParameterSummaryComponent(callbackSelfParameterPosition())
}
newtype TSummaryComponentStack =
@@ -311,7 +311,7 @@ module Private {
any(RequiredSummaryComponentStack x).required(head, tail)
or
any(RequiredSummaryComponentStack x).required(TParameterSummaryComponent(_), tail) and
head = thisParam()
head = callbackSelfParam()
or
derivedFluentFlowPush(_, _, _, head, tail, _)
}
@@ -336,7 +336,7 @@ module Private {
callbackRef = s.drop(_) and
(isCallbackParameter(callbackRef) or callbackRef.head() = TReturnSummaryComponent(_)) and
input = callbackRef.tail() and
output = TConsSummaryComponentStack(thisParam(), input) and
output = TConsSummaryComponentStack(callbackSelfParam(), input) and
preservesValue = true
)
or
@@ -439,6 +439,9 @@ module Private {
out.head() = TParameterSummaryComponent(_) and
s = out.tail()
)
or
// Add the post-update node corresponding to the requested argument node
outputState(c, s) and isCallbackParameter(s)
}
private newtype TSummaryNodeState =
@@ -1012,7 +1015,7 @@ module Private {
private predicate relevantSummaryElementGenerated(
AccessPath inSpec, AccessPath outSpec, string kind
) {
summaryElement(this, inSpec, outSpec, kind, "generated") and
summaryElement(this, inSpec, outSpec, kind, ["generated", "ai-generated"]) and
not summaryElement(this, _, _, _, "manual")
}

View File

@@ -24,7 +24,7 @@ private module SyntheticGlobals {
DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c }
/** Gets the parameter position of the instance parameter. */
ArgumentPosition instanceParameterPosition() { result = -1 }
ArgumentPosition callbackSelfParameterPosition() { result = -1 }
/** Gets the synthesized summary data-flow node for the given values. */
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSummaryNode(c, state) }

View File

@@ -236,6 +236,12 @@ private VirtualMethodAccess objectToString(ObjNode n) {
result.getQualifier() = n.asExpr() and sink(n)
}
/**
* Holds if `ma` is an `Object.toString()` call taking possibly improved type
* bounds into account.
*/
predicate objectToStringCall(VirtualMethodAccess ma) { ma = objectToString(_) }
/**
* Holds if the qualifier of the `Object.toString()` call `ma` might have type `t`.
*/

View File

@@ -93,7 +93,8 @@ private module Dispatch {
exists(RefType t | qualUnionType(ma, t, false) |
lowConfidenceDispatchType(t.getSourceDeclaration())
)
)
) and
not ObjFlow::objectToStringCall(ma)
}
private predicate lowConfidenceDispatchType(SrcRefType t) {

View File

@@ -0,0 +1,87 @@
/** Provide classes to reason about Android Intents that can install APKs. */
import java
import semmle.code.java.frameworks.android.Intent
import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSources
/** A string literal that represents the MIME type for Android APKs. */
class PackageArchiveMimeTypeLiteral extends StringLiteral {
PackageArchiveMimeTypeLiteral() { this.getValue() = "application/vnd.android.package-archive" }
}
/** The `android.content.Intent.ACTION_INSTALL_PACKAGE` constant. */
class InstallPackageAction extends Expr {
InstallPackageAction() {
this.(StringLiteral).getValue() = "android.intent.action.INSTALL_PACKAGE"
or
exists(VarAccess va |
va.getVariable().hasName("ACTION_INSTALL_PACKAGE") and
va.getQualifier().getType() instanceof TypeIntent
)
}
}
/** A method that sets the MIME type of an intent. */
class SetTypeMethod extends Method {
SetTypeMethod() {
this.hasName(["setType", "setTypeAndNormalize"]) and
this.getDeclaringType() instanceof TypeIntent
}
}
/** A method that sets the data URI and the MIME type of an intent. */
class SetDataAndTypeMethod extends Method {
SetDataAndTypeMethod() {
this.hasName(["setDataAndType", "setDataAndTypeAndNormalize"]) and
this.getDeclaringType() instanceof TypeIntent
}
}
/** A method that sets the data URI of an intent. */
class SetDataMethod extends Method {
SetDataMethod() {
this.hasName(["setData", "setDataAndNormalize", "setDataAndType", "setDataAndTypeAndNormalize"]) and
this.getDeclaringType() instanceof TypeIntent
}
}
/** A dataflow sink for the URI of an intent. */
class SetDataSink extends DataFlow::ExprNode {
SetDataSink() {
exists(MethodAccess ma |
this.getExpr() = ma.getQualifier() and
ma.getMethod() instanceof SetDataMethod
)
}
}
/** A method that generates a URI. */
class UriConstructorMethod extends Method {
UriConstructorMethod() {
this.hasQualifiedName("android.net", "Uri", ["fromFile", "fromParts"]) or
this.hasQualifiedName("androidx.core.content", "FileProvider", "getUriForFile")
}
}
/**
* A dataflow source representing the URIs which an APK not controlled by the
* application may come from. Including external storage and web URLs.
*/
class ExternalApkSource extends DataFlow::Node {
ExternalApkSource() {
sourceNode(this, "android-external-storage-dir") or
this.asExpr().(MethodAccess).getMethod() instanceof UriConstructorMethod or
this.asExpr().(StringLiteral).getValue().matches("file://%") or
this instanceof RemoteFlowSource
}
}
/** The `setAction` method of the `android.content.Intent` class. */
class SetActionMethod extends Method {
SetActionMethod() {
this.hasName("setAction") and
this.getDeclaringType() instanceof TypeIntent
}
}

View File

@@ -0,0 +1,121 @@
/** Provides dataflow configurations to reason about installation of arbitrary Android APKs. */
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.security.ArbitraryApkInstallation
/**
* A dataflow configuration for flow from an external source of an APK to the
* `setData[AndType][AndNormalize]` method of an intent.
*/
private module ApkInstallationConfiguration implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof ExternalApkSource }
predicate isSink(DataFlow::Node node) {
exists(MethodAccess ma |
ma.getMethod() instanceof SetDataMethod and
ma.getArgument(0) = node.asExpr() and
(
PackageArchiveMimeTypeFlow::hasFlowToExpr(ma.getQualifier())
or
InstallPackageActionFlow::hasFlowToExpr(ma.getQualifier())
)
)
}
}
module ApkInstallationFlow = DataFlow::Make<ApkInstallationConfiguration>;
private newtype ActionState =
ActionUnset() or
HasInstallPackageAction()
/**
* A dataflow configuration tracking the flow from the `android.content.Intent.ACTION_INSTALL_PACKAGE`
* constant to either the constructor of an intent or the `setAction` method of an intent.
*
* This is used to track if an intent is used to install an APK.
*/
private module InstallPackageActionConfiguration implements DataFlow::StateConfigSig {
class FlowState = ActionState;
predicate isSource(DataFlow::Node source, FlowState state) {
source.asExpr() instanceof InstallPackageAction and state instanceof ActionUnset
}
predicate isAdditionalFlowStep(
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
) {
state1 instanceof ActionUnset and
state2 instanceof HasInstallPackageAction and
(
exists(ConstructorCall cc |
cc.getConstructedType() instanceof TypeIntent and
node1.asExpr() = cc.getArgument(0) and
node1.asExpr().getType() instanceof TypeString and
node2.asExpr() = cc
)
or
exists(MethodAccess ma |
ma.getMethod() instanceof SetActionMethod and
node1.asExpr() = ma.getArgument(0) and
node2.asExpr() = ma.getQualifier()
)
)
}
predicate isSink(DataFlow::Node node, FlowState state) {
state instanceof HasInstallPackageAction and node.asExpr().getType() instanceof TypeIntent
}
predicate isBarrier(DataFlow::Node node, FlowState state) { none() }
}
private module InstallPackageActionFlow =
TaintTracking::MakeWithState<InstallPackageActionConfiguration>;
private newtype MimeTypeState =
MimeTypeUnset() or
HasPackageArchiveMimeType()
/**
* A dataflow configuration tracking the flow of the Android APK MIME type to
* the `setType` or `setTypeAndNormalize` method of an intent, followed by a call
* to `setData[AndType][AndNormalize]`.
*/
private module PackageArchiveMimeTypeConfiguration implements DataFlow::StateConfigSig {
class FlowState = MimeTypeState;
predicate isSource(DataFlow::Node node, FlowState state) {
node.asExpr() instanceof PackageArchiveMimeTypeLiteral and
state instanceof MimeTypeUnset
}
predicate isAdditionalFlowStep(
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
) {
state1 instanceof MimeTypeUnset and
state2 instanceof HasPackageArchiveMimeType and
exists(MethodAccess ma |
ma.getQualifier() = node2.asExpr() and
(
ma.getMethod() instanceof SetTypeMethod and
ma.getArgument(0) = node1.asExpr()
or
ma.getMethod() instanceof SetDataAndTypeMethod and
ma.getArgument(1) = node1.asExpr()
)
)
}
predicate isSink(DataFlow::Node node, FlowState state) {
state instanceof HasPackageArchiveMimeType and
node instanceof SetDataSink
}
predicate isBarrier(DataFlow::Node node, FlowState state) { none() }
}
private module PackageArchiveMimeTypeFlow =
TaintTracking::MakeWithState<PackageArchiveMimeTypeConfiguration>;

View File

@@ -104,11 +104,6 @@ class XssVulnerableWriterSource extends MethodAccess {
}
}
/**
* DEPRECATED: Use `XssVulnerableWriterSource` instead.
*/
deprecated class ServletWriterSource = XssVulnerableWriterSource;
/**
* Holds if `s` is an HTTP Content-Type vulnerable to XSS.
*/

View File

@@ -454,21 +454,11 @@ class MavenRepoJar extends File {
)
}
/**
* DEPRECATED: name changed to `getGroupId` for consistent use of camel-case.
*/
deprecated string getGroupID() { result = this.getGroupId() }
/**
* Gets the `artifactId` of this jar.
*/
string getArtifactId() { result = this.getParentContainer().getParentContainer().getBaseName() }
/**
* DEPRECATED: name changed to `getArtifactId` for consistent casing and consistent spelling with Maven.
*/
deprecated string getArtefactID() { result = this.getArtifactId() }
/**
* Gets the artifact version string of this jar.
*/
@@ -482,11 +472,6 @@ class MavenRepoJar extends File {
pom.getArtifact().getValue() = this.getArtifactId()
}
/**
* DEPRECATED: name changed to `artifactMatches` for consistent spelling with Maven.
*/
deprecated predicate artefactMatches(ProtoPom pom) { this.artifactMatches(pom) }
/**
* Holds if this jar is both an artifact for the POM, and has a version string that matches the POM
* version string. Only soft and hard version matches are supported.

View File

@@ -108,20 +108,6 @@ class XmlFile extends XmlParent, File {
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
/**
* DEPRECATED: Use `getAbsolutePath()` instead.
*
* Gets the path of this XML file.
*/
deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }

View File

@@ -0,0 +1,72 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Android allows an application to install an Android Package Kit (APK)
using an <code>Intent</code> with
the <code>"application/vnd.android.package-archive"</code> MIME type. If
the file used in the <code>Intent</code> is from a location that is not
controlled by the application (for example, an SD card that is
universally writable), this can result in the unintended installation of untrusted applications.
</p>
</overview>
<recommendation>
<p>
You should install packages using
the <code>PackageInstaller</code> class.
</p>
<p>
If you need to install from a file, you should use
a <code>FileProvider</code>. Content providers can provide more specific
permissions than file system permissions can.
</p>
<p>
When your application does not require package installations, do not add
the <code>REQUEST_INSTALL_PACKAGES</code> permission in the manifest file.
</p>
</recommendation>
<example>
<p>
In the following (bad) example, the package is installed from a file which
may be altered by another application:
</p>
<sample src="InstallApkWithFile.java"/>
<p>
In the following (good) example, the package is installed by using
a <code>FileProvider</code>:
</p>
<sample src="InstallApkWithFileProvider.java"/>
<p>
In the following (good) example, the package is installed using an
instance of the <code>android.content.pm.PackageInstaller</code> class:
</p>
<sample src="InstallApkWithPackageInstaller.java"/>
</example>
<references>
<li>
Android Developers: <a href="https://developer.android.com/reference/android/content/Intent#ACTION_INSTALL_PACKAGE">Intent.ACTION_INSTALL_PACKAGE</a>.
</li>
<li>
Android Developers: <a href="https://developer.android.com/reference/android/Manifest.permission#REQUEST_INSTALL_PACKAGES">Manifest.permission.REQUEST_INSTALL_PACKAGES</a>.
</li>
<li>
Android Developers: <a href="https://developer.android.com/reference/android/content/pm/PackageInstaller">PackageInstaller</a>.
</li>
<li>
Android Developers: <a href="https://developer.android.com/reference/androidx/core/content/FileProvider">FileProvider</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,19 @@
/**
* @id java/android/arbitrary-apk-installation
* @name Android APK installation
* @description Creating an intent with a URI pointing to a untrusted file can lead to the installation of an untrusted application.
* @kind path-problem
* @security-severity 9.3
* @problem.severity error
* @precision medium
* @tags security
* external/cwe/cwe-094
*/
import java
import semmle.code.java.security.ArbitraryApkInstallationQuery
import ApkInstallationFlow::PathGraph
from ApkInstallationFlow::PathNode source, ApkInstallationFlow::PathNode sink
where ApkInstallationFlow::hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Arbitrary Android APK installation."

View File

@@ -0,0 +1,14 @@
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import java.io.File;
/* Get a file from external storage */
File file = new File(Environment.getExternalStorageDirectory(), "myapp.apk");
Intent intent = new Intent(Intent.ACTION_VIEW);
/* Set the mimetype to APK */
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);

View File

@@ -0,0 +1,31 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import androidx.core.content.FileProvider;
import java.io.File;
import java.io.FileOutputStream;
String tempFilename = "temporary.apk";
byte[] buffer = new byte[16384];
/* Copy application asset into temporary file */
try (InputStream is = getAssets().open(assetName);
FileOutputStream fout = openFileOutput(tempFilename, Context.MODE_PRIVATE)) {
int n;
while ((n=is.read(buffer)) >= 0) {
fout.write(buffer, 0, n);
}
}
/* Expose temporary file with FileProvider */
File toInstall = new File(this.getFilesDir(), tempFilename);
Uri applicationUri = FileProvider.getUriForFile(this, "com.example.apkprovider", toInstall);
/* Create Intent and set data to APK file. */
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(applicationUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

View File

@@ -0,0 +1,32 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInstaller;
private static final String PACKAGE_INSTALLED_ACTION =
"com.example.SESSION_API_PACKAGE_INSTALLED";
/* Create the package installer and session */
PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params =
new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(params);
session = packageInstaller.openSession(sessionId);
/* Load asset into session */
try (OutputStream packageInSession = session.openWrite("package", 0, -1);
InputStream is = getAssets().open(assetName)) {
byte[] buffer = new byte[16384];
int n;
while ((n = is.read(buffer)) >= 0) {
packageInSession.write(buffer, 0, n);
}
}
/* Create status receiver */
Intent intent = new Intent(this, InstallApkSessionApi.class);
intent.setAction(PACKAGE_INSTALLED_ACTION);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.getIntentSender();
/* Commit the session */
session.commit(statusReceiver);

View File

@@ -0,0 +1,5 @@
---
category: newQuery
---
* Added a new query, `java/android/arbitrary-apk-installation`, to detect installation of APKs from untrusted sources.

View File

@@ -182,4 +182,18 @@ public class A {
public Object field1;
public Object field2;
void foo4() {
Producer1Consumer3<Integer> pc = new Producer1Consumer3<Integer>() {
int cfield = 0;
@Override public Integer[] make() {
return new Integer[] { cfield };
}
@Override public void eat(Integer[] xs) {
cfield = xs[0];
}
};
applyConsumer3(new Integer[] { (Integer)source(21) }, pc);
sink(applyProducer1(pc)[0]); // $ flow=21
}
}

View File

@@ -0,0 +1,32 @@
package generatedtest;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
// Test case generated by GenerateFlowTestCase.ql
public class Test {
Object source() {
return null;
}
void sink(Object o) {}
public void test() throws Exception {
{
// "org.apache.commons.compress.archivers.tar;TarArchiveEntry;true;TarArchiveEntry;(String);;Argument[0];Argument[-1];taint;ai-generated"
TarArchiveEntry out = null;
String in = (String) source();
out = new TarArchiveEntry(in);
sink(out); // $ hasTaintFlow
}
{
// "org.apache.commons.compress.archivers.tar;TarArchiveEntry;true;TarArchiveEntry;(String,boolean);;Argument[0];Argument[-1];taint;ai-generated"
TarArchiveEntry out = null;
String in = (String) source();
out = new TarArchiveEntry(in, false);
sink(out); // $ hasTaintFlow
}
}
}

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-commons-compress

View File

@@ -0,0 +1,2 @@
import java
import TestUtilities.InlineFlowTest

View File

@@ -0,0 +1,80 @@
package generatedtest;
import java.net.URI;
import java.util.List;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.client.utils.URLEncodedUtils;
// Test case generated by GenerateFlowTestCase.ql
public class Client {
<T> T getElement(Iterable<T> it) {
return it.iterator().next();
}
Object getURIBuilder_pathDefault(Object container) {
return null;
}
Object taint() {
return null;
}
void sink(Object o) {}
public void test() throws Exception {
{
// "org.apache.http.client.utils;URIBuilder;true;URIBuilder;(String);;Argument[0];Argument[-1];taint;ai-generated"
URIBuilder out = null;
String in = (String) taint();
out = new URIBuilder(in);
sink(out); // $ hasTaintFlow
}
{
// "org.apache.http.client.utils;URIBuilder;true;URIBuilder;(URI);;Argument[0];Argument[-1];taint;ai-generated"
URIBuilder out = null;
URI in = (URI) taint();
out = new URIBuilder(in);
sink(out); // $ hasTaintFlow
}
{
// "org.apache.http.client.utils;URIBuilder;true;setHost;(String);;Argument[0];Argument[-1];taint;ai-generated"
URIBuilder out = null;
String in = (String) taint();
out.setHost(in);
sink(out); // $ hasTaintFlow
}
{
// "org.apache.http.client.utils;URIBuilder;true;setHost;(String);;Argument[0];ReturnValue;taint;ai-generated"
URIBuilder out = null;
String in = (String) taint();
URIBuilder instance = null;
out = instance.setHost(in);
sink(out); // $ hasTaintFlow
}
{
// "org.apache.http.client.utils;URIBuilder;true;setPath;(String);;Argument[0];Argument[-1].SyntheticField[org.apache.http.client.utils.URIBuilder.path];taint;ai-generated"
URIBuilder out = null;
String in = (String) taint();
out.setPath(in);
sink(getURIBuilder_pathDefault(out)); // $ hasTaintFlow
}
{
// "org.apache.http.client.utils;URIBuilder;true;setPathSegments;(List);;Argument[0];Argument[-1].SyntheticField[org.apache.http.client.utils.URIBuilder.path];taint;ai-generated"
URIBuilder out = null;
List in = (List) taint();
out.setPathSegments(in);
sink(getURIBuilder_pathDefault(out)); // $ hasTaintFlow
}
{
// "org.apache.http.client.utils;URLEncodedUtils;true;parse;(URI,String);;Argument[0];ReturnValue.Element;taint;ai-generated"
List out = null;
URI in = (URI) taint();
out = URLEncodedUtils.parse(in, (String) null);
sink(getElement(out)); // $ hasTaintFlow
}
}
}

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/java-tests
extensible: summaryModel
data:
- ["generatedtest", "Client", False, "getURIBuilder_pathDefault", "(Object)", "", "Argument[0].SyntheticField[org.apache.http.client.utils.URIBuilder.path]", "ReturnValue", "taint", "manual"]

View File

@@ -56,4 +56,18 @@ class A {
return;
}
}
enum E {
/**
* Javadoc for enum constant
*/
A,
B,
C;
}
/**
* Javadoc for fields
*/
int i, j, k;
}

View File

@@ -125,3 +125,30 @@ A.java:
# 55| 1: [LocalVariableDeclExpr] rte
# 55| 1: [BlockStmt] { ... }
# 56| 0: [ReturnStmt] return ...
# 60| 10: [Class] E
# 64| 3: [FieldDeclaration] E A;
#-----| -3: (Javadoc)
# 61| 1: [Javadoc] /** Javadoc for enum constant */
# 62| 0: [JavadocText] Javadoc for enum constant
# 64| -1: [TypeAccess] E
# 64| 0: [ClassInstanceExpr] new E(...)
# 64| -3: [TypeAccess] E
# 65| 4: [FieldDeclaration] E B;
#-----| -3: (Javadoc)
# 61| 1: [Javadoc] /** Javadoc for enum constant */
# 62| 0: [JavadocText] Javadoc for enum constant
# 65| -1: [TypeAccess] E
# 65| 0: [ClassInstanceExpr] new E(...)
# 65| -3: [TypeAccess] E
# 66| 5: [FieldDeclaration] E C;
#-----| -3: (Javadoc)
# 61| 1: [Javadoc] /** Javadoc for enum constant */
# 62| 0: [JavadocText] Javadoc for enum constant
# 66| -1: [TypeAccess] E
# 66| 0: [ClassInstanceExpr] new E(...)
# 66| -3: [TypeAccess] E
# 72| 11: [FieldDeclaration] int i, ...;
#-----| -3: (Javadoc)
# 69| 1: [Javadoc] /** Javadoc for fields */
# 70| 0: [JavadocText] Javadoc for fields
# 72| -1: [TypeAccess] int

View File

@@ -14,7 +14,22 @@ edges
| Test.java:95:14:95:34 | getHostName(...) : String | Test.java:99:12:99:33 | new URI(...) |
| Test.java:95:14:95:34 | getHostName(...) : String | Test.java:100:12:100:45 | new URI(...) |
| Test.java:95:14:95:34 | getHostName(...) : String | Test.java:101:12:101:54 | new URI(...) |
| Test.java:105:14:105:34 | getHostName(...) : String | Test.java:107:46:107:46 | t |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:17:61:17:72 | source(...) : String |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:19:41:19:52 | source(...) : String |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:25:38:25:49 | source(...) : String |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:27:36:27:47 | source(...) : String |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:29:31:29:42 | source(...) : String |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:31:33:31:44 | source(...) : String |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:33:50:33:61 | source(...) : String |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:35:54:35:65 | source(...) : String |
| mad/Test.java:17:61:17:72 | source(...) : String | mad/Test.java:17:52:17:72 | (...)... |
| mad/Test.java:19:41:19:52 | source(...) : String | mad/Test.java:19:32:19:52 | (...)... |
| mad/Test.java:25:38:25:49 | source(...) : String | mad/Test.java:25:31:25:49 | (...)... |
| mad/Test.java:27:36:27:47 | source(...) : String | mad/Test.java:27:29:27:47 | (...)... |
| mad/Test.java:29:31:29:42 | source(...) : String | mad/Test.java:29:24:29:42 | (...)... |
| mad/Test.java:31:33:31:44 | source(...) : String | mad/Test.java:31:24:31:44 | (...)... |
| mad/Test.java:33:50:33:61 | source(...) : String | mad/Test.java:33:41:33:61 | (...)... |
| mad/Test.java:35:54:35:65 | source(...) : String | mad/Test.java:35:45:35:65 | (...)... |
nodes
| Test.java:19:18:19:38 | getHostName(...) : String | semmle.label | getHostName(...) : String |
| Test.java:24:20:24:23 | temp | semmle.label | temp |
@@ -35,8 +50,23 @@ nodes
| Test.java:99:12:99:33 | new URI(...) | semmle.label | new URI(...) |
| Test.java:100:12:100:45 | new URI(...) | semmle.label | new URI(...) |
| Test.java:101:12:101:54 | new URI(...) | semmle.label | new URI(...) |
| Test.java:105:14:105:34 | getHostName(...) : String | semmle.label | getHostName(...) : String |
| Test.java:107:46:107:46 | t | semmle.label | t |
| mad/Test.java:12:16:12:36 | getHostName(...) : String | semmle.label | getHostName(...) : String |
| mad/Test.java:17:52:17:72 | (...)... | semmle.label | (...)... |
| mad/Test.java:17:61:17:72 | source(...) : String | semmle.label | source(...) : String |
| mad/Test.java:19:32:19:52 | (...)... | semmle.label | (...)... |
| mad/Test.java:19:41:19:52 | source(...) : String | semmle.label | source(...) : String |
| mad/Test.java:25:31:25:49 | (...)... | semmle.label | (...)... |
| mad/Test.java:25:38:25:49 | source(...) : String | semmle.label | source(...) : String |
| mad/Test.java:27:29:27:47 | (...)... | semmle.label | (...)... |
| mad/Test.java:27:36:27:47 | source(...) : String | semmle.label | source(...) : String |
| mad/Test.java:29:24:29:42 | (...)... | semmle.label | (...)... |
| mad/Test.java:29:31:29:42 | source(...) : String | semmle.label | source(...) : String |
| mad/Test.java:31:24:31:44 | (...)... | semmle.label | (...)... |
| mad/Test.java:31:33:31:44 | source(...) : String | semmle.label | source(...) : String |
| mad/Test.java:33:41:33:61 | (...)... | semmle.label | (...)... |
| mad/Test.java:33:50:33:61 | source(...) : String | semmle.label | source(...) : String |
| mad/Test.java:35:45:35:65 | (...)... | semmle.label | (...)... |
| mad/Test.java:35:54:35:65 | source(...) : String | semmle.label | source(...) : String |
subpaths
#select
| Test.java:24:11:24:24 | new File(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:24:20:24:23 | temp | This path depends on a $@. | Test.java:19:18:19:38 | getHostName(...) | user-provided value |
@@ -50,4 +80,11 @@ subpaths
| Test.java:99:3:99:34 | new File(...) | Test.java:95:14:95:34 | getHostName(...) : String | Test.java:99:12:99:33 | new URI(...) | This path depends on a $@. | Test.java:95:14:95:34 | getHostName(...) | user-provided value |
| Test.java:100:3:100:46 | new File(...) | Test.java:95:14:95:34 | getHostName(...) : String | Test.java:100:12:100:45 | new URI(...) | This path depends on a $@. | Test.java:95:14:95:34 | getHostName(...) | user-provided value |
| Test.java:101:3:101:55 | new File(...) | Test.java:95:14:95:34 | getHostName(...) : String | Test.java:101:12:101:54 | new URI(...) | This path depends on a $@. | Test.java:95:14:95:34 | getHostName(...) | user-provided value |
| Test.java:107:46:107:46 | t | Test.java:105:14:105:34 | getHostName(...) : String | Test.java:107:46:107:46 | t | This path depends on a $@. | Test.java:105:14:105:34 | getHostName(...) | user-provided value |
| mad/Test.java:17:52:17:72 | (...)... | mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:17:52:17:72 | (...)... | This path depends on a $@. | mad/Test.java:12:16:12:36 | getHostName(...) | user-provided value |
| mad/Test.java:19:32:19:52 | (...)... | mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:19:32:19:52 | (...)... | This path depends on a $@. | mad/Test.java:12:16:12:36 | getHostName(...) | user-provided value |
| mad/Test.java:25:31:25:49 | (...)... | mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:25:31:25:49 | (...)... | This path depends on a $@. | mad/Test.java:12:16:12:36 | getHostName(...) | user-provided value |
| mad/Test.java:27:29:27:47 | (...)... | mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:27:29:27:47 | (...)... | This path depends on a $@. | mad/Test.java:12:16:12:36 | getHostName(...) | user-provided value |
| mad/Test.java:29:24:29:42 | (...)... | mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:29:24:29:42 | (...)... | This path depends on a $@. | mad/Test.java:12:16:12:36 | getHostName(...) | user-provided value |
| mad/Test.java:31:9:31:45 | new FileReader(...) | mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:31:24:31:44 | (...)... | This path depends on a $@. | mad/Test.java:12:16:12:36 | getHostName(...) | user-provided value |
| mad/Test.java:33:41:33:61 | (...)... | mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:33:41:33:61 | (...)... | This path depends on a $@. | mad/Test.java:12:16:12:36 | getHostName(...) | user-provided value |
| mad/Test.java:35:45:35:65 | (...)... | mad/Test.java:12:16:12:36 | getHostName(...) : String | mad/Test.java:35:45:35:65 | (...)... | This path depends on a $@. | mad/Test.java:12:16:12:36 | getHostName(...) | user-provided value |

View File

@@ -101,9 +101,4 @@ class Test {
new File(new URI(null, null, null, 0, t, null, null));
}
void doGet6(InetAddress address) throws IOException {
String t = address.getHostName();
// BAD: accessing local resource with user input
getClass().getModule().getResourceAsStream(t);
}
}

View File

@@ -0,0 +1,37 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import org.codehaus.cargo.container.installer.ZipURLInstaller;
public class Test {
public Object source(InetAddress address) {
return address.getHostName();
}
void test(InetAddress address) throws IOException {
// "java.lang;Module;true;getResourceAsStream;(String);;Argument[0];read-file;ai-generated"
getClass().getModule().getResourceAsStream((String) source(null));
// "java.lang;Class;false;getResource;(String);;Argument[0];read-file;ai-generated"
getClass().getResource((String) source(null));
// "java.lang;ClassLoader;true;getSystemResourceAsStream;(String);;Argument[0];read-file;ai-generated"
ClassLoader.getSystemResource((String) source(null));
// "java.io;File;true;createTempFile;(String,String,File);;Argument[2];create-file;ai-generated"
File.createTempFile(";", (String) source(null));
// "java.io;File;true;renameTo;(File);;Argument[0];create-file;ai-generated"
new File("").renameTo((File) source(null));
// "java.io;FileInputStream;true;FileInputStream;(File);;Argument[0];read-file;ai-generated"
new FileInputStream((File) source(null));
// "java.io;FileReader;true;FileReader;(File);;Argument[0];read-file;ai-generated"
new FileReader((File) source(null));
// "java.io;FileReader;true;FileReader;(String);;Argument[0];read-file;ai-generated"
new FileReader((String) source(null));
// "org.codehaus.cargo.container.installer;ZipURLInstaller;true;ZipURLInstaller;(URL,String,String);;Argument[1];create-file;ai-generated"
new ZipURLInstaller((URL) null, (String) source(null), "");
// "org.codehaus.cargo.container.installer;ZipURLInstaller;true;ZipURLInstaller;(URL,String,String);;Argument[2];create-file;ai-generated"
new ZipURLInstaller((URL) null, "", (String) source(null));
}
}

View File

@@ -1 +1 @@
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/apache-commons-io-2.6
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/apache-commons-io-2.6:${testdir}/../../../../../stubs/cargo

View File

@@ -1,29 +0,0 @@
import org.apache.hadoop.hive.metastore.api.ColumnStatistics;
import org.apache.hadoop.hive.metastore.api.DefaultConstraintsRequest;
import org.apache.hadoop.hive.metastore.ObjectStore;
import org.apache.hive.hcatalog.templeton.ColumnDesc;
import org.apache.hive.hcatalog.templeton.HcatDelegator;
import java.util.List;
public class Hive {
public static Object source() {
return null;
}
public void test(ObjectStore objStore, HcatDelegator hcatDel) throws Exception {
{
String taint = (String) source();
new DefaultConstraintsRequest("", taint, ""); // $ sqlInjection
}
{
ColumnStatistics taint = (ColumnStatistics) source();
//objStore.updatePartitionColumnStatistics(taint, (List<String>) null, (String) null, 0L); // $ sqlInjection
objStore.updatePartitionColumnStatistics(taint, (List<String>) null); // $ sqlInjection
}
{
ColumnDesc taint = (ColumnDesc) source();
hcatDel.addOneColumn(null, null, null, taint); // $ sqlInjection
}
}
}

View File

@@ -57,6 +57,7 @@
| good | 4 | Test.java:126:20:126:88 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=? ORDER BY PRICE" |
| good | 5 | Test.java:127:62:127:67 | query2 |
| good | 6 | Test.java:128:24:128:24 | 1 |
| source | 1 | mad/Test.java:11:16:11:19 | null |
| tableNames | 4 | Test.java:187:32:187:56 | "SELECT ITEM,PRICE FROM " |
| tableNames | 5 | Test.java:188:8:188:55 | " WHERE ITEM_CATEGORY='Biscuits' ORDER BY PRICE" |
| tableNames | 10 | Test.java:193:33:193:57 | "SELECT ITEM,PRICE FROM " |
@@ -97,6 +98,18 @@
| tainted | 58 | Test.java:87:8:87:15 | category |
| tainted | 58 | Test.java:87:19:87:36 | "' ORDER BY PRICE" |
| tainted | 59 | Test.java:88:47:88:52 | query1 |
| test | 3 | mad/Test.java:17:24:17:25 | "" |
| test | 3 | mad/Test.java:17:28:17:29 | "" |
| test | 3 | mad/Test.java:17:39:17:40 | "" |
| test | 4 | mad/Test.java:26:43:26:44 | "" |
| test | 4 | mad/Test.java:26:54:26:55 | "" |
| test | 5 | mad/Test.java:19:28:19:29 | "" |
| test | 5 | mad/Test.java:19:32:19:33 | "" |
| test | 13 | mad/Test.java:35:13:35:80 | updatePartitionColumnStatistics(...) |
| test | 13 | mad/Test.java:35:76:35:79 | null |
| test | 18 | mad/Test.java:40:34:40:37 | null |
| test | 18 | mad/Test.java:40:40:40:43 | null |
| test | 18 | mad/Test.java:40:46:40:49 | null |
| unescaped | 4 | Test.java:96:28:96:81 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" |
| unescaped | 5 | Test.java:97:23:97:40 | "' ORDER BY PRICE" |
| unescaped | 11 | Test.java:103:19:103:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" |

View File

@@ -0,0 +1,43 @@
import java.sql.DatabaseMetaData;
import java.util.List;
import org.apache.hadoop.hive.metastore.api.ColumnStatistics;
import org.apache.hadoop.hive.metastore.api.DefaultConstraintsRequest;
import org.apache.hadoop.hive.metastore.ObjectStore;
import org.apache.hive.hcatalog.templeton.HcatDelegator;
import org.apache.hive.hcatalog.templeton.ColumnDesc;
public class Test {
public static Object source() {
return null;
}
public void test(DatabaseMetaData dmd) throws Exception {
String taint = (String) source();
// java.sql;DatabaseMetaData;true;getColumns;(String,String,String,String);;Argument[2];sql;ai-generated
dmd.getColumns("", "", taint, ""); // $ sqlInjection
// java.sql;DatabaseMetaData;true;getPrimaryKeys;(String,String,String);;Argument[2];sql;ai-generated
dmd.getPrimaryKeys("", "", taint); // $ sqlInjection
}
public void test(ObjectStore objStore, HcatDelegator hcatDel) throws Exception {
{
String taint = (String) source();
// "org.apache.hadoop.hive.metastore.api;DefaultConstraintsRequest;true;DefaultConstraintsRequest;(String,String,String);;Argument[1];sql;ai-generated"
new DefaultConstraintsRequest("", taint, ""); // $ sqlInjection
}
{
ColumnStatistics taint = (ColumnStatistics) source();
// "org.apache.hadoop.hive.metastore;ObjectStore;true;updatePartitionColumnStatistics;(ColumnStatistics,List,String,long);;Argument[0];sql;ai-generated"
// @formatter:off
// objStore.updatePartitionColumnStatistics(taint, (List<String>) null, (String) null, 0L); // $ sqlInjection
// @formatter:on
// "org.apache.hadoop.hive.metastore;ObjectStore;true;updatePartitionColumnStatistics;(ColumnStatistics,List);;Argument[0];sql;ai-generated"
objStore.updatePartitionColumnStatistics(taint, (List<String>) null); // $ sqlInjection
}
{
ColumnDesc taint = (ColumnDesc) source();
// "org.apache.hive.hcatalog.templeton;HcatDelegator;true;addOneColumn;(String,String,String,ColumnDesc);;Argument[3];sql;ai-generated"
hcatDel.addOneColumn(null, null, null, taint); // $ sqlInjection
}
}
}

View File

@@ -0,0 +1,58 @@
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import java.io.File;
public class ApkInstallation extends Activity {
static final String APK_MIMETYPE = "application/vnd.android.package-archive";
public void installAPK(String path) {
// BAD: the path is not checked
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive"); // $ hasApkInstallation
startActivity(intent);
}
public void installAPK3(String path) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType(APK_MIMETYPE);
// BAD: the path is not checked
intent.setData(Uri.fromFile(new File(path))); // $ hasApkInstallation
startActivity(intent);
}
public void installAPKFromExternalStorage(String path) {
// BAD: file is from external storage
File file = new File(Environment.getExternalStorageDirectory(), path);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), APK_MIMETYPE); // $ hasApkInstallation
startActivity(intent);
}
public void installAPKFromExternalStorageWithActionInstallPackage(String path) {
// BAD: file is from external storage
File file = new File(Environment.getExternalStorageDirectory(), path);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(Uri.fromFile(file)); // $ hasApkInstallation
startActivity(intent);
}
public void installAPKInstallPackageLiteral(String path) {
File file = new File(Environment.getExternalStorageDirectory(), path);
Intent intent = new Intent("android.intent.action.INSTALL_PACKAGE");
intent.setData(Uri.fromFile(file)); // $ hasApkInstallation
startActivity(intent);
}
public void otherIntent(File file) {
Intent intent = new Intent(this, OtherActivity.class);
intent.setAction(Intent.ACTION_VIEW);
// BAD: the file is from unknown source
intent.setData(Uri.fromFile(file)); // $ hasApkInstallation
}
}
class OtherActivity extends Activity {
}

View File

@@ -0,0 +1,19 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.security.ArbitraryApkInstallationQuery
import TestUtilities.InlineExpectationsTest
class HasApkInstallationTest extends InlineExpectationsTest {
HasApkInstallationTest() { this = "HasApkInstallationTest" }
override string getARelevantTag() { result = "hasApkInstallation" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasApkInstallation" and
exists(DataFlow::Node sink | ApkInstallationFlow::hasFlowTo(sink) |
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2:${testdir}/../../../stubs/mvel2-2.4.7:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/scriptengine:${testdir}/../../../stubs/jsr223-api:${testdir}/../../../stubs/apache-freemarker-2.3.31:${testdir}/../../../stubs/jinjava-2.6.0:${testdir}/../../../stubs/pebble-3.1.5:${testdir}/../../../stubs/thymeleaf-3.0.14:${testdir}/../../../stubs/apache-velocity-2.3
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2:${testdir}/../../../stubs/mvel2-2.4.7:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/scriptengine:${testdir}/../../../stubs/jsr223-api:${testdir}/../../../stubs/apache-freemarker-2.3.31:${testdir}/../../../stubs/jinjava-2.6.0:${testdir}/../../../stubs/pebble-3.1.5:${testdir}/../../../stubs/thymeleaf-3.0.14:${testdir}/../../../stubs/apache-velocity-2.3:${testdir}/../../..//stubs/google-android-9.0.0

View File

@@ -20,7 +20,7 @@ public class JdbcUrlSSRF extends HttpServlet {
String jdbcUrl = request.getParameter("jdbcUrl");
Driver driver = new org.postgresql.Driver();
DataSourceBuilder dsBuilder = new DataSourceBuilder();
DataSourceBuilder dsBuilder = DataSourceBuilder.create();
try {
driver.connect(jdbcUrl, null); // $ SSRF

View File

@@ -0,0 +1,22 @@
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import javafx.scene.web.WebEngine;
import org.codehaus.cargo.container.installer.ZipURLInstaller;
public class Test {
public static Object source(HttpServletRequest request) {
return request.getParameter(null);
}
public void test(WebEngine webEngine) {
// "javafx.scene.web;WebEngine;false;load;(String);;Argument[0];open-url;ai-generated"
webEngine.load((String) source(null)); // $ SSRF
}
public void test() {
// "org.codehaus.cargo.container.installer;ZipURLInstaller;true;ZipURLInstaller;(URL,String,String);;Argument[0];open-url:ai-generated"
new ZipURLInstaller((URL) source(null), "", ""); // $ SSRF
}
}

View File

@@ -1,2 +1,2 @@
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/servlet-api-2.4/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/servlet-api-2.4/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web

View File

@@ -0,0 +1,14 @@
// Generated automatically from org.apache.commons.compress.archivers.ArchiveEntry for testing purposes
package org.apache.commons.compress.archivers;
import java.util.Date;
public interface ArchiveEntry
{
Date getLastModifiedDate();
String getName();
boolean isDirectory();
long getSize();
static long SIZE_UNKNOWN = 0;
}

View File

@@ -0,0 +1,92 @@
// Generated automatically from org.apache.commons.compress.archivers.tar.TarArchiveEntry for testing purposes
package org.apache.commons.compress.archivers.tar;
import java.io.File;
import java.util.Date;
import java.util.Map;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarConstants;
import org.apache.commons.compress.archivers.zip.ZipEncoding;
public class TarArchiveEntry implements ArchiveEntry, TarConstants
{
protected TarArchiveEntry() {}
public Date getLastModifiedDate(){ return null; }
public Date getModTime(){ return null; }
public File getFile(){ return null; }
public Map<String, String> getExtraPaxHeaders(){ return null; }
public String getExtraPaxHeader(String p0){ return null; }
public String getGroupName(){ return null; }
public String getLinkName(){ return null; }
public String getName(){ return null; }
public String getUserName(){ return null; }
public TarArchiveEntry(File p0){}
public TarArchiveEntry(File p0, String p1){}
public TarArchiveEntry(String p0){}
public TarArchiveEntry(String p0, boolean p1){}
public TarArchiveEntry(String p0, byte p1){}
public TarArchiveEntry(String p0, byte p1, boolean p2){}
public TarArchiveEntry(byte[] p0){}
public TarArchiveEntry(byte[] p0, ZipEncoding p1){}
public TarArchiveEntry(byte[] p0, ZipEncoding p1, boolean p2){}
public TarArchiveEntry[] getDirectoryEntries(){ return null; }
public boolean equals(Object p0){ return false; }
public boolean equals(TarArchiveEntry p0){ return false; }
public boolean isBlockDevice(){ return false; }
public boolean isCharacterDevice(){ return false; }
public boolean isCheckSumOK(){ return false; }
public boolean isDescendent(TarArchiveEntry p0){ return false; }
public boolean isDirectory(){ return false; }
public boolean isExtended(){ return false; }
public boolean isFIFO(){ return false; }
public boolean isFile(){ return false; }
public boolean isGNULongLinkEntry(){ return false; }
public boolean isGNULongNameEntry(){ return false; }
public boolean isGNUSparse(){ return false; }
public boolean isGlobalPaxHeader(){ return false; }
public boolean isLink(){ return false; }
public boolean isOldGNUSparse(){ return false; }
public boolean isPaxGNUSparse(){ return false; }
public boolean isPaxHeader(){ return false; }
public boolean isSparse(){ return false; }
public boolean isStarSparse(){ return false; }
public boolean isSymbolicLink(){ return false; }
public int getDevMajor(){ return 0; }
public int getDevMinor(){ return 0; }
public int getGroupId(){ return 0; }
public int getMode(){ return 0; }
public int getUserId(){ return 0; }
public int hashCode(){ return 0; }
public long getLongGroupId(){ return 0; }
public long getLongUserId(){ return 0; }
public long getRealSize(){ return 0; }
public long getSize(){ return 0; }
public static int DEFAULT_DIR_MODE = 0;
public static int DEFAULT_FILE_MODE = 0;
public static int MAX_NAMELEN = 0;
public static int MILLIS_PER_SECOND = 0;
public static long UNKNOWN = 0;
public void addPaxHeader(String p0, String p1){}
public void clearExtraPaxHeaders(){}
public void parseTarHeader(byte[] p0){}
public void parseTarHeader(byte[] p0, ZipEncoding p1){}
public void setDevMajor(int p0){}
public void setDevMinor(int p0){}
public void setGroupId(int p0){}
public void setGroupId(long p0){}
public void setGroupName(String p0){}
public void setIds(int p0, int p1){}
public void setLinkName(String p0){}
public void setModTime(Date p0){}
public void setModTime(long p0){}
public void setMode(int p0){}
public void setName(String p0){}
public void setNames(String p0, String p1){}
public void setSize(long p0){}
public void setUserId(int p0){}
public void setUserId(long p0){}
public void setUserName(String p0){}
public void writeEntryHeader(byte[] p0){}
public void writeEntryHeader(byte[] p0, ZipEncoding p1, boolean p2){}
}

View File

@@ -0,0 +1,70 @@
// Generated automatically from org.apache.commons.compress.archivers.tar.TarConstants for testing purposes
package org.apache.commons.compress.archivers.tar;
public interface TarConstants
{
static String GNU_LONGLINK = null;
static String MAGIC_ANT = null;
static String MAGIC_GNU = null;
static String MAGIC_POSIX = null;
static String MAGIC_XSTAR = null;
static String VERSION_ANT = null;
static String VERSION_GNU_SPACE = null;
static String VERSION_GNU_ZERO = null;
static String VERSION_POSIX = null;
static byte LF_BLK = 0;
static byte LF_CHR = 0;
static byte LF_CONTIG = 0;
static byte LF_DIR = 0;
static byte LF_FIFO = 0;
static byte LF_GNUTYPE_LONGLINK = 0;
static byte LF_GNUTYPE_LONGNAME = 0;
static byte LF_GNUTYPE_SPARSE = 0;
static byte LF_LINK = 0;
static byte LF_NORMAL = 0;
static byte LF_OLDNORM = 0;
static byte LF_PAX_EXTENDED_HEADER_LC = 0;
static byte LF_PAX_EXTENDED_HEADER_UC = 0;
static byte LF_PAX_GLOBAL_EXTENDED_HEADER = 0;
static byte LF_SYMLINK = 0;
static int ATIMELEN_GNU = 0;
static int ATIMELEN_XSTAR = 0;
static int CHKSUMLEN = 0;
static int CHKSUM_OFFSET = 0;
static int CTIMELEN_GNU = 0;
static int CTIMELEN_XSTAR = 0;
static int DEFAULT_BLKSIZE = 0;
static int DEFAULT_RCDSIZE = 0;
static int DEVLEN = 0;
static int FORMAT_OLDGNU = 0;
static int FORMAT_POSIX = 0;
static int FORMAT_XSTAR = 0;
static int GIDLEN = 0;
static int GNAMELEN = 0;
static int ISEXTENDEDLEN_GNU = 0;
static int ISEXTENDEDLEN_GNU_SPARSE = 0;
static int LONGNAMESLEN_GNU = 0;
static int MAGICLEN = 0;
static int MAGIC_OFFSET = 0;
static int MODELEN = 0;
static int MODTIMELEN = 0;
static int NAMELEN = 0;
static int OFFSETLEN_GNU = 0;
static int PAD2LEN_GNU = 0;
static int PREFIXLEN = 0;
static int PREFIXLEN_XSTAR = 0;
static int REALSIZELEN_GNU = 0;
static int SIZELEN = 0;
static int SPARSELEN_GNU = 0;
static int SPARSELEN_GNU_SPARSE = 0;
static int UIDLEN = 0;
static int UNAMELEN = 0;
static int VERSIONLEN = 0;
static int VERSION_OFFSET = 0;
static int XSTAR_MAGIC_LEN = 0;
static int XSTAR_MAGIC_OFFSET = 0;
static long MAXID = 0;
static long MAXSIZE = 0;
}

View File

@@ -0,0 +1,12 @@
// Generated automatically from org.apache.commons.compress.archivers.zip.ZipEncoding for testing purposes
package org.apache.commons.compress.archivers.zip;
import java.nio.ByteBuffer;
public interface ZipEncoding
{
ByteBuffer encode(String p0);
String decode(byte[] p0);
boolean canEncode(String p0);
}

View File

@@ -1,53 +1,11 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
// Generated automatically from org.apache.http.Header for testing purposes
package org.apache.http;
/**
* Represents an HTTP header field.
*
* <p>The HTTP header fields follow the same generic format as
* that given in Section 3.1 of RFC 822. Each header field consists
* of a name followed by a colon (":") and the field value. Field names
* are case-insensitive. The field value MAY be preceded by any amount
* of LWS, though a single SP is preferred.
*
*<pre>
* message-header = field-name ":" [ field-value ]
* field-name = token
* field-value = *( field-content | LWS )
* field-content = &lt;the OCTETs making up the field-value
* and consisting of either *TEXT or combinations
* of token, separators, and quoted-string&gt;
*</pre>
*
* @since 4.0
*/
public interface Header extends NameValuePair {
HeaderElement[] getElements() throws ParseException;
import org.apache.http.HeaderElement;
import org.apache.http.NameValuePair;
public interface Header extends NameValuePair
{
HeaderElement[] getElements();
}

Some files were not shown because too many files have changed in this diff Show More