Skip to content

Commit

Permalink
Merge branch 'develop' into feature/jsr-310-localdate
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/net/fortuna/ical4j/model/property/Geo.java
#	src/test/java/net/fortuna/ical4j/data/CalendarParserImplTest.java
  • Loading branch information
benfortuna committed Aug 8, 2022
2 parents eec4710 + 530e5d2 commit 0fdb9e8
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 12 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/cifuzz.yml
@@ -0,0 +1,24 @@
name: CIFuzz
on: [pull_request]
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'ical4j'
dry-run: false
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'ical4j'
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
4 changes: 3 additions & 1 deletion src/main/java/net/fortuna/ical4j/model/parameter/Email.java
Expand Up @@ -8,6 +8,7 @@
import org.apache.commons.validator.routines.EmailValidator;

import static net.fortuna.ical4j.util.CompatibilityHints.KEY_RELAXED_PARSING;
import static net.fortuna.ical4j.util.CompatibilityHints.KEY_RELAXED_VALIDATION;

/**
* From specification:
Expand Down Expand Up @@ -62,7 +63,8 @@ public Email(String address) {
} else {
this.address = address;
}
if (!EmailValidator.getInstance().isValid(this.address)) {
if (!CompatibilityHints.isHintEnabled(KEY_RELAXED_VALIDATION)
&& !EmailValidator.getInstance().isValid(this.address)) {
throw new IllegalArgumentException("Invalid address: " + address);
}
}
Expand Down
31 changes: 20 additions & 11 deletions src/main/java/net/fortuna/ical4j/model/property/Geo.java
Expand Up @@ -35,12 +35,16 @@
import net.fortuna.ical4j.model.ParameterList;
import net.fortuna.ical4j.model.Property;
import net.fortuna.ical4j.model.PropertyFactory;
import net.fortuna.ical4j.util.CompatibilityHints;
import net.fortuna.ical4j.validate.PropertyValidator;
import net.fortuna.ical4j.validate.ValidationException;
import net.fortuna.ical4j.validate.ValidationResult;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* $Id$
Expand Down Expand Up @@ -136,6 +140,10 @@ public class Geo extends Property {

private static final long serialVersionUID = -902100715801867636L;

private static final Pattern VALUE_PATTERN = Pattern.compile("([+-]?[0-9]+\\.?[0-9]*);([+-]?[0-9]+\\.?[0-9]*)");

private static final Pattern RELAXED_VALUE_PATTERN = Pattern.compile("([+-]?[0-9]+\\.?[0-9]*)\\\\?;([+-]?[0-9]+\\.?[0-9]*)");

private BigDecimal latitude;

private BigDecimal longitude;
Expand Down Expand Up @@ -209,19 +217,20 @@ public final BigDecimal getLongitude() {
*/
@Override
public final void setValue(final String aValue) {
final String latitudeString = aValue.substring(0, aValue.indexOf(';'));
if (StringUtils.isNotBlank(latitudeString)) {
latitude = new BigDecimal(latitudeString);
Matcher matcher;
if (CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING)) {
matcher = RELAXED_VALUE_PATTERN.matcher(aValue);
} else {
latitude = BigDecimal.valueOf(0);
matcher = VALUE_PATTERN.matcher(aValue);
}

final String longitudeString = aValue.substring(aValue.indexOf(';') + 1);
if (StringUtils.isNotBlank(longitudeString)) {
longitude = new BigDecimal(longitudeString);
} else {
longitude = BigDecimal.valueOf(0);
if (!matcher.matches()) {
throw new IllegalArgumentException("Invalid GEO string");
}
final String latitudeString = matcher.group(1);
latitude = new BigDecimal(latitudeString);

final String longitudeString = matcher.group(2);
longitude = new BigDecimal(longitudeString);
}

/**
Expand Down
Expand Up @@ -87,6 +87,7 @@ class CalendarParserImplSpec extends Specification {
'/samples/valid/bhav23-1.ics' | []
'/samples/invalid/bhav23-2.ics' | [KEY_RELAXED_UNFOLDING, KEY_RELAXED_PARSING]
'/samples/valid/blankTzid.ics' | []
'/samples/invalid/sogo-geo-escaped-semicolon.ics' | [KEY_RELAXED_PARSING]
}

def 'verify parsing empty lines'() {
Expand Down
14 changes: 14 additions & 0 deletions src/test/groovy/net/fortuna/ical4j/model/RecurSpec.groovy
Expand Up @@ -425,4 +425,18 @@ class RecurSpec extends Specification {
rule | seed | start | expectedDate
'FREQ=MONTHLY;COUNT=100;INTERVAL=1' | '20180329T025959' | '20170729T030000' | '20180329T025959'
}

def 'test BYDAY with MINUTELY precision'() {
given: 'a recurrence rule'
Recur recur = new Recur.Builder().frequency(Recur.Frequency.DAILY).interval(1)
.dayList(new WeekDayList(MO)).hourList(new NumberList('16')).minuteList(new NumberList('37,38'))
.until(new DateTime('20220519T165900')).build()

when: 'dates are generated for a period'
def dates = recur.getDates(new DateTime('20220505T143700Z'),
new DateTime('20220519T145900Z'), Value.DATE_TIME)

then: 'result matches expected'
dates == new DateList('20220509T163700Z,20220509T163800Z,20220516T163700Z,20220516T163800Z', Value.DATE_TIME)
}
}
64 changes: 64 additions & 0 deletions src/test/groovy/net/fortuna/ical4j/model/property/GeoSpec.groovy
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2022, Ben Fortuna
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* o Neither the name of Ben Fortuna nor the names of any other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

package net.fortuna.ical4j.model.property

import net.fortuna.ical4j.model.ParameterList
import net.fortuna.ical4j.util.CompatibilityHints
import spock.lang.Specification

class GeoSpec extends Specification {

def cleanup() {
CompatibilityHints.clearHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING)
}

def 'test invalid parsing'() {
when: 'a non-conforming GEO string is parsed'
def geo = new Geo.Factory().createProperty([] as ParameterList, '123.456\\;-987.654')

then: 'an exception is thrown'
thrown(IllegalArgumentException)
}

def 'test relaxed parsing'() {
setup: 'enable relaxed parsing'
CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING, true)

when: 'a non-conforming GEO string is parsed'
def geo = new Geo.Factory().createProperty([] as ParameterList, '123.456\\;-987.654')

then: 'the expected instance is created'
geo.value == '123.456;-987.654'
}
}
Expand Up @@ -121,6 +121,7 @@ public static TestSuite suite() {
suite.addTest(new CalendarParserImplTest("/samples/invalid/13-MoonPhase.ics", 215));
suite.addTest(new CalendarParserImplTest("/samples/invalid/overlaps.ics", 1));
suite.addTest(new CalendarParserImplTest("/samples/invalid/schedule-unstable.ics", 12));
suite.addTest(new CalendarParserImplTest("/samples/invalid/sogo-geo-escaped-semicolon.ics", 9));
return suite;
}
}
16 changes: 16 additions & 0 deletions src/test/resources/samples/invalid/sogo-geo-escaped-semicolon.ics
@@ -0,0 +1,16 @@
BEGIN:VCALENDAR
PRODID:-//Inverse inc./SOGo 3.2.10//EN
VERSION:2.0
BEGIN:VEVENT
DESCRIPTION:Some description
DTEND:20221012T183000Z
DTSTAMP:20220805T143350Z
DTSTART:20221012T170000Z
GEO:12.34567\;12.34567
LOCATION:Some place
SEQUENCE:0
SUMMARY:Summary
TRANSP:OPAQUE
UID:A-Unique-ID
END:VEVENT
END:VCALENDAR

0 comments on commit 0fdb9e8

Please sign in to comment.