github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/scanners/azure/functions/date_time_add.go (about)

     1  package functions
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strconv"
     7  	"time"
     8  )
     9  
    10  var pattern = regexp.MustCompile(`^P((?P<year>\d+)Y)?((?P<month>\d+)M)?((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$`)
    11  
    12  func DateTimeAdd(args ...interface{}) interface{} {
    13  	if len(args) < 2 {
    14  		return nil
    15  	}
    16  
    17  	base, ok := args[0].(string)
    18  	if !ok {
    19  		return nil
    20  	}
    21  
    22  	format := time.RFC3339
    23  	if len(args) == 3 {
    24  		if providedFormat, ok := args[2].(string); ok {
    25  			format = convertFormat(providedFormat)
    26  		}
    27  
    28  	}
    29  
    30  	baseTime, err := time.Parse(format, base)
    31  	if err != nil {
    32  		return nil
    33  	}
    34  
    35  	duration, err := parseISO8601(args[1].(string))
    36  	if err != nil {
    37  		return nil
    38  	}
    39  
    40  	timeDuration := duration.timeDuration()
    41  	baseTime = baseTime.Add(timeDuration)
    42  
    43  	if ok {
    44  		return baseTime.Format(format)
    45  	}
    46  
    47  	return baseTime.Format(time.RFC3339)
    48  }
    49  
    50  type Iso8601Duration struct {
    51  	Y int
    52  	M int
    53  	W int
    54  	D int
    55  	// Time Component
    56  	TH int
    57  	TM int
    58  	TS int
    59  }
    60  
    61  func parseISO8601(from string) (Iso8601Duration, error) {
    62  	var match []string
    63  	var d Iso8601Duration
    64  
    65  	if pattern.MatchString(from) {
    66  		match = pattern.FindStringSubmatch(from)
    67  	} else {
    68  		return d, fmt.Errorf("could not parse duration string")
    69  	}
    70  
    71  	for i, name := range pattern.SubexpNames() {
    72  		part := match[i]
    73  		if i == 0 || name == "" || part == "" {
    74  			continue
    75  		}
    76  
    77  		val, err := strconv.Atoi(part)
    78  		if err != nil {
    79  			return d, err
    80  		}
    81  		switch name {
    82  		case "year":
    83  			d.Y = val
    84  		case "month":
    85  			d.M = val
    86  		case "week":
    87  			d.W = val
    88  		case "day":
    89  			d.D = val
    90  		case "hour":
    91  			d.TH = val
    92  		case "minute":
    93  			d.TM = val
    94  		case "second":
    95  			d.TS = val
    96  		default:
    97  			return d, fmt.Errorf("unknown field %s", name)
    98  		}
    99  	}
   100  
   101  	return d, nil
   102  }
   103  
   104  func (d Iso8601Duration) timeDuration() time.Duration {
   105  	var dur time.Duration
   106  	dur += time.Duration(d.TH) * time.Hour
   107  	dur += time.Duration(d.TM) * time.Minute
   108  	dur += time.Duration(d.TS) * time.Second
   109  	dur += time.Duration(d.D) * 24 * time.Hour
   110  	dur += time.Duration(d.W) * 7 * 24 * time.Hour
   111  	dur += time.Duration(d.M) * 30 * 24 * time.Hour
   112  	dur += time.Duration(d.Y) * 365 * 24 * time.Hour
   113  
   114  	return dur
   115  }