diff --git a/src/main/java/com/iheartradio/m3u8/ParseUtil.java b/src/main/java/com/iheartradio/m3u8/ParseUtil.java index 86b022a..c15343f 100644 --- a/src/main/java/com/iheartradio/m3u8/ParseUtil.java +++ b/src/main/java/com/iheartradio/m3u8/ParseUtil.java @@ -29,7 +29,7 @@ public static > T parseEnum(String string, Class enumType, throw ParseException.create(ParseExceptionType.NOT_JAVA_ENUM, tag, string); } } - + public static String parseDateTime(String string, String tag) throws ParseException { Matcher matcher = Constants.EXT_X_PROGRAM_DATE_TIME_PATTERN.matcher(string); @@ -54,9 +54,12 @@ public static List parseHexadecimal(String hexString, String tag) throws P if (matcher.matches()) { String valueString = matcher.group(1); + if (valueString.length() % 2 != 0) { + throw ParseException.create(ParseExceptionType.INVALID_HEXADECIMAL_STRING, tag, hexString); + } - for (char c : valueString.toCharArray()) { - bytes.add(hexCharToByte(c)); + for (int i = 0; i < valueString.length(); i += 2) { + bytes.add((byte)(Short.parseShort(valueString.substring(i, i+2), 16) & 0xFF)); } return bytes; @@ -64,7 +67,7 @@ public static List parseHexadecimal(String hexString, String tag) throws P throw ParseException.create(ParseExceptionType.INVALID_HEXADECIMAL_STRING, tag, hexString); } } - + private static byte hexCharToByte(char hex) { if (hex >= 'A') { return (byte) ((hex & 0xF) + 9); @@ -183,7 +186,7 @@ public static List parseAttributeList(String line, String tag) throws //Even Apple playlists have sometimes spaces after a , final String name = string.substring(0, separator).trim(); final String value = string.substring(separator + 1); - + if (name.isEmpty()) { throw ParseException.create(ParseExceptionType.MISSING_ATTRIBUTE_NAME, tag, attributes.toString()); } diff --git a/src/main/java/com/iheartradio/m3u8/WriteUtil.java b/src/main/java/com/iheartradio/m3u8/WriteUtil.java index e7a5849..f66779e 100644 --- a/src/main/java/com/iheartradio/m3u8/WriteUtil.java +++ b/src/main/java/com/iheartradio/m3u8/WriteUtil.java @@ -25,7 +25,7 @@ public static String writeHexadecimal(List hex) { StringBuilder builder = new StringBuilder(hex.size() + prefix.length()); builder.append(prefix); for(Byte b : hex) { - builder.append(Integer.toHexString(b)); + builder.append(String.format("%02x", b)); } return builder.toString(); } diff --git a/src/test/java/com/iheartradio/m3u8/MediaPlaylistLineParserTest.java b/src/test/java/com/iheartradio/m3u8/MediaPlaylistLineParserTest.java index 3896c48..d2ecfe0 100644 --- a/src/test/java/com/iheartradio/m3u8/MediaPlaylistLineParserTest.java +++ b/src/test/java/com/iheartradio/m3u8/MediaPlaylistLineParserTest.java @@ -45,7 +45,7 @@ public void testEXT_X_KEY() throws Exception { final String line = "#" + tag + ":METHOD=AES-128" + ",URI=\"" + uri + "\"" + - ",IV=0x1234abcd5678EF90" + + ",IV=0x1234abcd5678EF90aabbccddeeff0011" + ",KEYFORMAT=\"" + format + "\"" + ",KEYFORMATVERSIONS=\"1/2/3\""; @@ -57,8 +57,10 @@ public void testEXT_X_KEY() throws Exception { assertEquals(uri, encryptionData.getUri()); assertEquals( - Arrays.asList((byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 10, (byte) 11, (byte) 12, (byte) 13, - (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 14, (byte) 15, (byte) 9, (byte) 0), + Arrays.asList((byte) 0x12, (byte) 0x34, (byte) 0xAB, (byte) 0xCD, + (byte) 0x56, (byte) 0x78, (byte) 0xEF, (byte) 0x90, + (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD, + (byte) 0xEE, (byte) 0xFF, (byte) 0x00, (byte) 0x11), encryptionData.getInitializationVector()); assertEquals(format, encryptionData.getKeyFormat()); diff --git a/src/test/java/com/iheartradio/m3u8/ParseUtilParseHexadecimalTest.java b/src/test/java/com/iheartradio/m3u8/ParseUtilParseHexadecimalTest.java new file mode 100644 index 0000000..a31f9b0 --- /dev/null +++ b/src/test/java/com/iheartradio/m3u8/ParseUtilParseHexadecimalTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017, Spiideo + */ + +package com.iheartradio.m3u8; + +import java.util.Arrays; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +/** + * @author Raniz + * @since 02/08/17. + */ +@RunWith(Parameterized.class) +public class ParseUtilParseHexadecimalTest { + + @Parameterized.Parameters(name = "{index}: {1}") + public static Iterable data() { + return Arrays.asList(new Object[][]{ + {Arrays.asList((byte) 0), "0x00"}, + {Arrays.asList((byte) 1), "0x01"}, + {Arrays.asList((byte) -1), "0xff"}, + {Arrays.asList((byte) -16), "0xf0"}, + {Arrays.asList((byte) 0, (byte) 1), "0x0001"}, + {Arrays.asList((byte) 1, (byte) 1), "0x0101"}, + {Arrays.asList((byte) -1, (byte) -1), "0xffff"}, + {Arrays.asList((byte) -121, (byte) -6), "0x87fa"}, + {Arrays.asList((byte) 75, (byte) 118), "0x4b76"}, + }); + } + + private final List expected; + private final String input; + + public ParseUtilParseHexadecimalTest(final List expected, final String input) { + this.expected = expected; + this.input = input; + } + + @Test + public void parseHexadecimal() throws Exception { + Assert.assertEquals(expected, ParseUtil.parseHexadecimal(input, "")); + } + +} diff --git a/src/test/java/com/iheartradio/m3u8/WriteUtilWriteHexadecimalTest.java b/src/test/java/com/iheartradio/m3u8/WriteUtilWriteHexadecimalTest.java new file mode 100644 index 0000000..b8cc66b --- /dev/null +++ b/src/test/java/com/iheartradio/m3u8/WriteUtilWriteHexadecimalTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2017, Spiideo + */ + +package com.iheartradio.m3u8; + +import java.util.Arrays; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +/** + * @author Raniz + * @since 02/08/17. + */ +@RunWith(Parameterized.class) +public class WriteUtilWriteHexadecimalTest { + + @Parameterized.Parameters(name = "{index}: {1}") + public static Iterable data() { + return Arrays.asList(new Object[][]{ + {Arrays.asList((byte) 0), "0x00"}, + {Arrays.asList((byte) 1), "0x01"}, + {Arrays.asList((byte) -1), "0xff"}, + {Arrays.asList((byte) -16), "0xf0"}, + {Arrays.asList((byte) 0, (byte) 1), "0x0001"}, + {Arrays.asList((byte) 1, (byte) 1), "0x0101"}, + {Arrays.asList((byte) -1, (byte) -1), "0xffff"}, + {Arrays.asList((byte) -121, (byte) -6), "0x87fa"}, + {Arrays.asList((byte) 75, (byte) 118), "0x4b76"}, + }); + } + + private final List input; + private final String expected; + + public WriteUtilWriteHexadecimalTest(final List input, final String expected) { + this.input = input; + this.expected = expected; + } + + @Test + public void writeHexadecimal() throws Exception { + Assert.assertEquals(expected, WriteUtil.writeHexadecimal(input)); + } + +} \ No newline at end of file