Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 34fa072

Browse files
committed
Add modeling to Stdlib.qll
Adds classes for some integer-parsing functions and a constant from strconv, plus a class for calls to integer-parsing functions.
1 parent ac49aa2 commit 34fa072

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

ql/src/semmle/go/frameworks/Stdlib.qll

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,119 @@ module Path {
507507
}
508508
}
509509

510+
/**
511+
* Provides classes for some functions in the `strconv` package for
512+
* converting strings to numbers.
513+
*/
514+
module StrConv {
515+
/** A function that parses integers. */
516+
class Atoi extends Function {
517+
Atoi() { this.hasQualifiedName("strconv", "Atoi") }
518+
}
519+
520+
/** A function that parses floating-point numbers. */
521+
class ParseFloat extends Function {
522+
ParseFloat() { this.hasQualifiedName("strconv", "ParseFloat") }
523+
}
524+
525+
/** A function that parses integers with a specifiable bitSize. */
526+
class ParseInt extends Function {
527+
ParseInt() { this.hasQualifiedName("strconv", "ParseInt") }
528+
}
529+
530+
/** A function that parses unsigned integers with a specifiable bitSize. */
531+
class ParseUint extends Function {
532+
ParseUint() { this.hasQualifiedName("strconv", "ParseUint") }
533+
}
534+
535+
/**
536+
* A constant that gives the size in bits of an int or uint
537+
* value on the current architecture (32 or 64).
538+
*/
539+
class IntSize extends DeclaredConstant {
540+
IntSize() { this.hasQualifiedName("strconv", "IntSize") }
541+
}
542+
}
543+
544+
/** Provides a class for modeling calls to number-parsing functions. */
545+
module ParserCall {
546+
/** A data-flow call node that parses a number. */
547+
abstract class Range extends DataFlow::CallNode {
548+
/** Gets the bit size of the type of the result number. */
549+
abstract int getTargetBitSize();
550+
551+
/** Holds if the type of the result number is signed. */
552+
abstract boolean getTargetIsSigned();
553+
554+
/** Gets the name of the parser function. */
555+
abstract string getParserName();
556+
}
557+
}
558+
559+
/** A call to a number-parsing function */
560+
class ParserCall extends DataFlow::CallNode {
561+
ParserCall::Range self;
562+
563+
ParserCall() { this = self }
564+
565+
/** Gets the bit size of the type of the result number. */
566+
int getTargetBitSize() { result = self.getTargetBitSize() }
567+
568+
/** Holds if the type of the result number is signed. */
569+
boolean getTargetIsSigned() { result = self.getTargetIsSigned() }
570+
571+
/** Gets the name of the parser function. */
572+
string getParserName() { result = self.getParserName() }
573+
574+
/** Gets a string describing the size of the integer parsed. */
575+
string getBitSizeString() {
576+
if getTargetBitSize() != 0
577+
then result = "a " + getTargetBitSize() + "-bit integer"
578+
else result = "an integer with architecture-dependent bit-width"
579+
}
580+
}
581+
582+
/** A call to `strconv.Atoi` */
583+
class AtoiCall extends DataFlow::CallNode, ParserCall::Range {
584+
AtoiCall() { exists(StrConv::Atoi atoi | this = atoi.getACall()) }
585+
586+
override int getTargetBitSize() { result = 0 }
587+
588+
override boolean getTargetIsSigned() { result = true }
589+
590+
override string getParserName() { result = "strconv.Atoi" }
591+
}
592+
593+
/** A call to `strconv.ParseInt` */
594+
class ParseIntCall extends DataFlow::CallNode, ParserCall::Range {
595+
ParseIntCall() { exists(StrConv::ParseInt parseInt | this = parseInt.getACall()) }
596+
597+
override int getTargetBitSize() {
598+
if exists(StrConv::IntSize intSize | this.getArgument(2).(DataFlow::ReadNode).reads(intSize))
599+
then result = 0
600+
else result = this.getArgument(2).getIntValue()
601+
}
602+
603+
override boolean getTargetIsSigned() { result = true }
604+
605+
override string getParserName() { result = "strconv.ParseInt" }
606+
}
607+
608+
/** A call to `strconv.ParseUint` */
609+
class ParseUintCall extends DataFlow::CallNode, ParserCall::Range {
610+
ParseUintCall() { exists(StrConv::ParseUint parseUint | this = parseUint.getACall()) }
611+
612+
override int getTargetBitSize() {
613+
if exists(StrConv::IntSize intSize | this.getArgument(2).(DataFlow::ReadNode).reads(intSize))
614+
then result = 0
615+
else result = this.getArgument(2).getIntValue()
616+
}
617+
618+
override boolean getTargetIsSigned() { result = false }
619+
620+
override string getParserName() { result = "strconv.ParseUint" }
621+
}
622+
510623
/** Provides models of commonly used functions in the `strings` package. */
511624
module Strings {
512625
/** The `Join` function. */

0 commit comments

Comments
 (0)