I use the JID3 library which works fine for IDv2_3 but when it is asked to update a tracks tags which are V2_4, it simply wipes the Id3v2_4 tags. How can I test which version of tagging a track has.
Example of setting the ratings and times played in the POPULARIMETER tag
public String setmp3RatingTag(Context context, File SourceFile, String email, int rating, int timesPlayed) throws Exception {
String error = null;
if (timesPlayed < 0) {
timesPlayed = 0;
}
try {
MediaFile MediaFile = new MP3File(SourceFile);
ID3V2_3_0Tag ID3V2_3_0Tag = (org.blinkenlights.jid3.v2.ID3V2_3_0Tag) MediaFile.getID3V2Tag();
POPMID3V2Frame popmid3V2Frame = new POPMID3V2Frame(email, rating, timesPlayed);
popmid3V2Frame.setPopularity(email, rating, timesPlayed);
if (ID3V2_3_0Tag != null) {
frames = ID3V2_3_0Tag.getPOPMFrames();
if (frames != null) {
if (frames.length > 0) {
String emailtouser[]=getmp3Email(SourceFile);
for (int i = 0; i < frames.length; i++) {
if (frames[i] != null) {
ID3V2_3_0Tag.removePOPMFrame(emailtouser[i]);
}
}
}
}
} else {
ID3V2_3_0Tag = new ID3V2_3_0Tag();
}
ID3V2_3_0Tag.addPOPMFrame(popmid3V2Frame);
MediaFile.setID3Tag(ID3V2_3_0Tag);
MediaFile.sync();
} catch (ID3Exception | OutOfMemoryError e) {
e.printStackTrace();
error = e.getMessage();
}
error = finish(context, SourceFile);
return error;
}
For anyone using the jid3 library, I added another method to the class MP3File.java
#Override
public int testforVerion() {
int iMinorVersion=0;
try {
InputStream oSourceIS = new BufferedInputStream(m_oFileSource.getInputStream());
ID3DataInputStream oID3DIS = new ID3DataInputStream(oSourceIS);
try
{
// check if v2 tag is present
byte[] abyCheckTag = new byte[3];
oID3DIS.readFully(abyCheckTag);
if ((abyCheckTag[0] == 'I') && (abyCheckTag[1] == 'D') && (abyCheckTag[2] == '3'))
{
// check which version of v2 tags we have
iMinorVersion = oID3DIS.readUnsignedByte();
}
else
{
return iMinorVersion;
}
}
finally
{
oID3DIS.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return iMinorVersion;
}
simply check for value 3 for ID3V2_3 and 4 for ID3V2_4
Related
void updateList(void) {
numCam = get_noofcameras_connected();
if (numCam != 0) {
CameraSelect->Text = ("Please select Camera");
CameraSelect->Items->Add("ALL");
for (int i = 1; i < numCam + 1; i++) {
CameraSelect->Items->Add(string::format("Camera {0}", i));
}
}
else {
CameraSelect->Text = ("NO CAMERA CONNECTED");
}
}
it is giving the error string is ambiguous .
for c# you can call .Format
here an example from the
doc
Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0} per ounce.",
pricePerOunce);
Console.WriteLine(s);
I have a text file called highscore.txt and I know the format of the data going into the file which works in the following way:
Username:score
I then need to search through the whole file to see where the new score needs to be added such that the file is in order of score from largest to smallest
List<string> tempoaryList = new List<string>();
List<int> valueList = new List<int>();
string lineValues = "";
using (StreamReader sr = new StreamReader(finalPath))
{
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
tempoaryList.Add(lineValues);
int data = Convert.ToInt32(lineValues.Substring(lineValues.LastIndexOf(':') + 1));
valueList.Add(data);
}
}
valueList.Sort();
for(int i =0; i > valueList.Count; i++)
{
if(valueList[i] <= playerScore)
{
tempoaryList.Insert(i - 1, playerScore.ToString());
}
}
using (StreamWriter sw = new StreamWriter(finalPath, false))
{
for (int i = 0; i < tempoaryList.Count; i++)
{
sw.WriteLine(tempoaryList[i]);
Debug.Log(tempoaryList[i]);
}
}
The above just simply doesn't change the text file and leaves it as it was found, any ideas of what I am doing wrong?
You should change your code to this:
ScoreList.cs
using UnityEngine;
using System;
using System.IO;
using System.Collections.Generic;
public class ScoreList : MonoBehaviour {
private void Start() {
GameOver.GameOverEvent += UpdateScoreBoardFile;
}
private void UpdateScoreBoardFile(string playerName, int playerScore) {
string lineValues;
string finalPath = "[ScoreBoard File Location]";
List<string> tempoaryList = new List<string>();
List<int> valueList = new List<int>();
bool isScoreLowest = true;
using (StreamReader sr = new StreamReader(finalPath)) {
while (sr.EndOfStream == false) {
lineValues = sr.ReadLine();
tempoaryList.Add(lineValues);
int data = Convert.ToInt32(lineValues.Substring(lineValues.LastIndexOf(':') + 1));
valueList.Add(data);
}
}
if (tempoaryList != null) {
for (int i = 0; i < valueList.Count; i++) {
if (valueList[i] <= playerScore) {
tempoaryList.Insert(i, playerName + ":" + playerScore.ToString());
isScoreLowest = false;
break;
}
}
}
if (isScoreLowest) {
tempoaryList.Add(playerName + ":" + playerScore.ToString());
}
using (StreamWriter sw = new StreamWriter(finalPath, false)) {
for (int i = 0; i < tempoaryList.Count; i++) {
sw.WriteLine(tempoaryList[i]);
Debug.Log(tempoaryList[i]);
}
}
}
}
GameOver.cs (or wherever you manage the game over condition):
using UnityEngine;
using System;
public class GameOver : MonoBehaviour {
public static event Action<string, int> GameOverEvent;
string playerName;
int finalScore;
private void GameOver() {
//Do other stuff when the game is over
GameOverEvent(playerName, finalScore);
}
}
Explanation of the changes:
isScoreLowest is needed to Add the new lowest score at the end of the list, since the for loop won't add it by itself.
The if (tempoaryList != null) check is done to skip the for loop when the scoreboard is empty.
And you saved yourself from doing a Sort, which is always a good thing. :)
Alright, so I'm practicing with C++ classes and pointers. When suddenly...
If I try to get the address of my object passed in the parameters, it gives me an invalid address.
What is going on here?
P.S You can ignore the if statement, it shouldn't be relevant to this particular problem.
Picture of the Problem
.
int ChainLinkz::chainCount = 0;
ChainLinkz::ChainLinkz(int i) {
data = i;
chainID = chainCount++;
fLink = this;
addr = this;
nLink = 0;
printf("Created Link with Value: %i Addr: %x.\n", data, this);
}
ChainLinkz *ChainLinkz::next() {
if (nLink)
return nLink;
else
return 0;
}
ChainLinkz *ChainLinkz::last() {
ChainLinkz * lastLink = fLink;
while (lastLink->next()) {
lastLink = lastLink->next();
}
return lastLink;
}
ChainLinkz ChainLinkz::addLink(ChainLinkz link) {
if (link.nLink) {
if (&link == link.fLink) { // Replace fLink with new address in all instances of previous chain | Fix the old chain
ChainLinkz *t_link = link.nLink;
while (t_link->next()) {
t_link = t_link->next();
t_link->fLink = link.nLink;
}
} else { // Replace nLink for previous link | Fix the old chain
ChainLinkz *t_link = link.fLink;
while (t_link != &link)
t_link = t_link->next();
t_link->nLink = link.next();
}
}
last()->nLink = link.addr;
printf("\n&link: %x | Real Addr: %x \n\n", (ChainLinkz*)&link, link.addr);
link.nLink = 0; //Update values to new chain
link.fLink = fLink;
return link;
}
ChainLinkz ChainLinkz::addLink(ChainLinkz *link) {
printf("Overloader: %x.\n", link);
return addLink(*link);
}
ChainLinkz ChainLinkz::operator>>(ChainLinkz link) {
return addLink(link);
}
ChainLinkz ChainLinkz::operator>>(ChainLinkz *link) {
printf("Overloader: %x.\n", link);
return addLink(*link);
}
Solved the problem by using references instead of passing the object itself.
ChainLinkz ChainLinkz::addLink(ChainLinkz &link) {
printf("Overloaded New: %p\n", &link);
return addLink(&link);
}
ChainLinkz ChainLinkz::addLink(ChainLinkz *link) {
if (link->nLink) {
if (link == link->fLink) { // Replace fLink with new address in all instances of previous chain | Fix the old chain
ChainLinkz *t_link = link->nLink;
while (t_link->next()) {
t_link = t_link->next();
t_link->fLink = link->nLink;
}
}
else { // Replace nLink for previous link | Fix the old chain
ChainLinkz *t_link = link->fLink;
while (t_link != link)
t_link = t_link->next();
t_link->nLink = link->next();
}
}
last()->nLink = link;
link->nLink = 0; //Update values to new chain
link->fLink = fLink;
return *link;
}
ChainLinkz ChainLinkz::operator>>(ChainLinkz &link) {
return addLink(&link);
}
ChainLinkz ChainLinkz::operator>>(ChainLinkz *link) {
printf("Overloaded: %p.\n", link);
return addLink(link);
}
I used the filter to fix the XSS. But when i scan my codes using fortify software, the number of XSS issues didn't change. Did i miss something? or Fortify cannot recognize the filter? Here are my filter codes:
public final class RequestWrapper extends HttpServletRequestWrapper {
public RequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values==null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
return cleanXSS(value);
}
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null)
return null;
return cleanXSS(value);
}
private String cleanXSS(String value) {
System.out.println("filter : " + value);
//System.out.println("afterfilter : " + (isNotEmptyOrNull(value) ? StringEscapeUtils.escapeHtml4(value) : value));
//return isNotEmptyOrNull(value) ? StringEscapeUtils.escapeHtml4(value) : value;
if(isNotEmptyOrNull(value)){
value = value.replaceAll("<", "<").replaceAll(">", ">");
value = value.replaceAll("\\(", "(").replaceAll("\\)", ")");
value = value.replaceAll("'", "'");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("script", "");
}
System.out.println("afterfilter : " +value);
return value;
}
public static boolean isNotEmptyOrNull(String string) {
if (string != null && !"".equals(string.trim())) {
return true;
}
return false;
}
}
The problem here is that Fortify doesn't have a rule for your cleanXSS method. What you will have to do is to write a custom rule, specifically a "data flow cleanse rule". This will let fortify know that any data that enters and then returned from this method will be safe from XSS.
However after looking at you XSS filter, I have to inform you that it's incomplete and will not take in to account all possible XSS vectors. I recommend that you use OWASP ESAPI's XSS filter. Fortify already has a rules for ESAPI.
I am setting the items which i want to Remove from list as null and then sorting list through IComparable method CompareTo so that null items would be at the top ... then using RemoveRange function on list but unable to so so ... i see no problem in following code:
try
{
foreach (Invoice item in inv)
{
if (item.qty == 0)
{
item.CustomerName = null;
item.qty = 0;
i++;
}
}
inv.Sort();
inv.RemoveRange(0, i);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
#region IComparable<Invoice> Members
public int CompareTo(Invoice other)
{
return this.CustomerName.CompareTo(other.CustomerName);
}
#endregion
error occurs at inv.RemoveRange(0,i); saying that :Failed to compare two elemets in array
Why is it so??
public int CompareTo(Invoice other)
{
if (other == null || other.CustomerName == null) return 1;
if (this.CustomerName == null) return -1;
return this.CustomerName.CompareTo(other.CustomerName);
}
or
public int CompareTo(Invoice other)
{
//if other Invoide is null, instance is bigger.
if (other == null) return 1;
if (this.CustomerName == null) {
//if both CustomerName are null, instance equals other. Of only instance CustomerName is null, other is bigger.
return other.CustomerName == null ? 0 : -1;
}
//if other.CustomerName is null (and instance.CustomerName is not null), instance is bigger.
if (other.CustomerName == null) return 1;
//both CustomerName are not null, call basic string.CompareTo
return this.CustomerName.CompareTo(other.CustomerName);
}