Zend_Pdf - load utf-8 pdf document - zend-framework

I'm currently trying to load a PDF document using the Zend_Pdf::load($filename) method and I'm getting
Error occured while 'xxx.pdf' file reading.
So I see in Zend_Pdf_Parser::_construct there is this block
while ($byteCount > 0 && !feof($pdfFile)) {
$nextBlock = fread($pdfFile, $byteCount);
if ($nextBlock === false) {
require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception( "Error occured while '$source' file reading." );
}
$data .= $nextBlock;
$byteCount -= strlen($nextBlock);
}
if ($byteCount != 0) {
require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception( "Error occured while '$source' file reading." );
}
After debugging, I can tell that strlen($nextBlock) is not returning the right value (based on $nextBlock = fread($pdfFile, $byteCount); )
If I use mb_strlen($nextBlock,'8bit') instead this block passes right. Now I'm getting another error
Pdf file syntax error. 'startxref' keyword expected
So now I look into Zend_Pdf_StringParser:readLexeme() and I can see that again there is a problem with singlebyte vs. multibyte string functions (strlen etc.)
So does anybody have a clue what's going on with Zend_Pdf, if this is general bug or I'm just missing something?

I never used Zend_PDF because it has very few potential. I advise you to integrate into your project TCPDF! ;)

I experienced the same error and it turned out to be a bug in Zend Guard. Apparently my version of the PHP encoder turns the ASCII NP form feed character (\f) inside string literals into the backslash (\) and the f characters (\\f).
The obfuscated version of
print bin2hex("\f");
outputs
5c66
instead of the expected
0c
This behavior causes Zend_Pdf_StringParser to parse 'startxre' instead of 'startxref' in readLexeme, causing the error you described.
If you are using a different version of the encoder or no encoder at all, then this may not be the cause of the problem (try reproducing it on a different PHP version).

Related

Unity Patcher. Name has invalid chars Error

I have written a patcher for my game but I am stuck at the actual saving of the files part. I keep on getting the following error from unity:
System.ArgumentException: Name has invalid chars
at System.IO.FileStream..ctor....
Here is the code that is in charge of saving my files:
function downloadFile(file:String){
var download:WWW = WWW(rawDataFolder+""+file); //download file from platforms raw folder
yield download; // wait for download to finish
// var saveLoc = Application.persistentDataPath; //Location where the files will go
var saveLoc = "C:\\games";
try{
Debug.Log(saveLoc+"\\"+file);
File.WriteAllBytes (saveLoc+"\\"+file+".FILE", download.bytes); //<----PROBLEM HERE.
}
catch(error){
updateMsg ="Update Failed with error message:\n\n"+error.ToString();
errorOccured = true;
Debug.Log(error);
}
}
I am trying to download a file called "level0". It doesn't have a file extension... in windows explorer it says it is simply 'FILE'. So I was thinking it was a binary file. Am I wrong? What might be causing my null character problem? This missing extension? Any help on this would be amazing.
I found out that my problem originated in the text file that I was reading. The text file must have had spaces in it. Using the ".Trim()" command I was able to remove the invalid char error. Once that was removed it worked perfectly reading files without extensions (Binary Files).

Proper format for log4j2.xml RollingFile configuration

I am getting the following exception in my glassfish 4 application that uses log4j2:
SEVERE: ERROR StatusLogger Invalid URL C:/glassfish4/glassfish/domains/domain1/config/log4j2.xml java.net.MalformedURLException: Unknown protocol: c
I have the following section in my log4j2.xml:
<RollingFile name="RollingFile" fileName="C:/glassfish4/glassfish/domains/domain1/logs/ucsvc.log"
filePattern="C:/glassfish4/glassfish/domains/domain1/logs/$${date:yyyy-MM}/ucsvc-%d{MM-dd-yyyy}-%i.log">
I understand that if it's looking for a URL, then "C:/glassfish4/..." is not the correct format.
However, the rolling file part actually works: I see a log file and the rolled log files where I expect them.
If I change to a URL (e.g. file:///C/glassfish4/...) that doesn't work at all.
So should I ignore the exception? (everything seems to be working ok). Or can someone explain the correct format for this section of the configuration?
I have not yet fully determined why it is that the config file works for me as well as the OP, but, I can confirm that changing the path reference to a file:// url solves the problem (ie: gets rid of the error/warning/irritant).
In my IntelliJ Run/Debug configurations, for VM options, I have:
-Dlog4j.configurationFile=file://C:\dev\path\to\log4j2.xml
I can confirm that '\' are translated to '/' so, no worries there.
EDIT:
Okay, the whole thing works because they (the apache guys) try really hard to load the configuration and they do, in fact, load from the file as specified via the c:\... notation. They just throw up a rather misleading exception before continuing to try.
In ConfigurationFactory::getConfiguration:
**source = getInputFromURI(FileUtils.getCorrectedFilePathUri(config));**
} catch (Exception ex) {
// Ignore the error and try as a String.
}
if (source == null) {
final ClassLoader loader = this.getClass().getClassLoader();
**source = getInputFromString(config, loader);**
The first bolded line tries to load from a URL and fails, throwing the exception. The code then continues, pops into getInputFromString:
try {
final URL url = new URL(config);
return new ConfigurationSource(url.openStream(), FileUtils.fileFromURI(url.toURI()));
} catch (final Exception ex) {
final ConfigurationSource source = getInputFromResource(config, loader);
if (source == null) {
try {
**final File file = new File(config);
return new ConfigurationSource(new FileInputStream(file), file);**
Where it tries to load the config again, fails and falls into the catch, tries again, fails and finally succeeds on the bolded lines (dealing with a File).
Okay, the code lines I wanted in emphasize with bold are actually just wrapped in **; guess the site doesn't permit nested tags? Anyway, y'all get the meaning.
It's all a bit of a mess to read, but that's why it works even though you get that nasty-looking (and wholly misleading) exception.
Thanks Jon, i was searching all over.. this helped!
This is on Intellij 13, Tomcat 7.0.56
-Dlog4j.configurationFile=file://C:\Surendra\workspace\cmdb\resources\elasticityLogging.xml
The problem is not the contents of your log4j2.xml file.
The problem is that log4j2 cannot locate your log4j2.xml config file. If you look carefully at the error, the URL that is reported as invalid is C:/glassfish4/glassfish/domains/domain1/config/log4j2.xml: the config file.
I'm not sure why this is. Are you specifying the location of the config file via the system property -Dlog4j.configurationFile=path/to/log4j2.xml?
Still, if the application and logging works then perhaps there is no problem. Strange though. You can get more details about the log4j configuration by configuring <Configuration status="trace"> at the top of your log4j2.xml file. This will print log4j initialization details to the console.

Soap Issue - SoapFault exception: [Client] looks like we got no XML document

Ive looked at similar errors and i think its most likely due to a BOM character but to be honest most of the other coding is in a different context and i just dont understand it, im not that familiar with soap and just use it to pull the data then format it in php.
My code is simple:
$activityClient = xpmClient::getModuleInstance('activity', $remoteSessionId, 'xxx.5pmweb.com');
$filter = new stdClass();
$count = 300;
$offset = 0;
$activityList = $activityClient->getList($filter, $offset, $count);
Now the server error shows:
> PHP Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document in xxx/caching.php:59\nStack trace:\n
\#0 xxx/caching.php(59): SoapClient->__call('getList', Array)\n
\#1 xxx/caching.php(59): xpmClient->getList(Object(stdClass), 0, '371')\n
\#2 /xxx/reports.php(296): include('/xxx/...')\n
\#3 {main}\n thrown in /xxx/caching.php on line 59
Line 296 on report.php is an include for the caching.php file, line 59 of that file is
$activityList = $activityClient->getList($filter, $offset, $count);
This worked for months without issue so im not sure what changed today. Any ideas how to strip the BOM and still get my data into $activityList as an object so i can access the information?
edit//
The preg replace doesnt work, i guess thats because once i call $activityList the server gives a fatal error and doesnt process anything after that so im trying to fix it AFTER its broke rather than before.
How would i go about doing __getLastResponse()
Ive read the manual but dont understand how to structure it, im pretty sure i need a try catch for the reasons i said preg replace didnt work but i tried a few variations and its doing nothing, im pretty sure the structure is wrong, any pointers or ideas?
I don't know why would BOM cause this but if you want to strip bom here you go
function strip_bom( $str ) {
return preg_replace( '/^(\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/', "", $str );
}
The Soap server you are using is broken. Have you checked manually trying to call it?

What does the message "Invalid byte 2 of a 3-byte UTF-8 sequence" mean?

I changed a file in Orbeon Forms, and the next time I load the page, I get an error message saying Invalid byte 2 of a 3-byte UTF-8 sequence. How can I solve this problem?
This happens when Orbeon Forms reads an XML file and expects it to use the UTF-8 encoding, but somehow the file isn't properly encoded in UTF-8. To solve this, make sure that:
You have an XML declaration at the beginning of the file saying the file is in UTF-8:
<?xml version="1.0" encoding="UTF-8" ?>
Your editor is XML-aware, so it can parse the XML declaration and consequently use the UTF-8 encoding. If your editor isn't XML aware, and you don't want to use another editor, look for an option or preference allowing you to specify that the editor must use UTF-8.
A three byte UTF-8 sequence looks like:
1110xxxx 10xxxxxx 10xxxxxx
Your error message may mean that the first byte of the three is incorrectly flagging the start of a three byte sequence or else that the second byte is malformed.
As #avernet says, you need to make sure that all elements in your system are producing and expecting UTF-8.
When you start your program, use the following Java command line argument:
-Dfile.encoding=UTF-8
For example,
java -Dfile.encoding=UTF-8 -jar foo.jar
I got the same problem in Eclipse, I just tried by changing the file type.
Right click on file -> Resource -> Text file encoding (UTF-8)
This solution worked for me.
Thanks.
I am using Eclipse and I also had to change the Text file encoding in:
->Windows->Preferences->Workspace
Then it worked fine.
Thanks
You might need to configure your Tomcat with the following parameter:
-Dfile.encoding=UTF-8
Had same problem.
Problem > I'm getting X509 certificate values (multiple encoding source) to generate a PDF report.
The PDF is generated throught a webservice that waits for an UTF-8 xml request and I've to reencode the values before marshalling.
Solution >
http://fabioangelini.wordpress.com/2011/08/04/converting-java-string-fromto-utf-8/
Using this class:
public class StringHelper {
// convert from UTF-8 -> internal Java String format
public static String convertFromUTF8(String s) {
String out = null;
try {
out = new String(s.getBytes("ISO-8859-1"), "UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
return null;
}
return out;
}
// convert from internal Java String format -> UTF-8
public static String convertToUTF8(String s) {
String out = null;
try {
out = new String(s.getBytes("UTF-8"), "ISO-8859-1");
} catch (java.io.UnsupportedEncodingException e) {
return null;
}
return out;
}
}
Usage:
//getSummaryAttMap() returns a HashMap
String value = (String) getSummaryAttMap().get(key);
if(value != null)
value = StringHelper.convertToUTF8(value);
else
value = "";
I'll provide a special coding answer. When you check the xml file and there's nothing wrong, and you're using Java and running Tomcat Server. Your source code may neglect specify the encoding yourself, and thus JVM uses default encoding when read in xml contents as string or something else that repesents string, which in turn refer to Tomcat's default encoding. If encoding of xml and Tomcat are inconsistent, it might also report same error message.
The switching of the encoding for the input might help:
XMLEventReader eventReader =
inputFactory.createXMLEventReader(in,
"utf-8"
//"windows-1251"
);

Zend_Loader include doesn't throw exception

I am finding that when Zend tries to auto load a file which doesn't exist, it throws an error which I cannot catch in a try/catch block. This happens when I use class_exists too. I have fixed the problem by hacking zend:
if ($once) {
if (!#include_once ($filename)) {
throw new Exception("Failed to include $filename");
}
// include_once $filename;
}
else {
if (!#include ($filename)) {
throw new Exception("Failed to include $filename");
}
// include $filename;
}
The commented out lines are zend's originals. Now I can catch the exception thrown when a file cannot be included. Can anybody suggest a cleaner way to do this which doesn't involve hacking zend?
I am on Zend version 1.11.10, and the code in question is Zend_Loader line 146.
Thanks.
instead of using include or include_once try using Zend_Loader::loadClass()
Here is the API: Zend_Loader::loadClass($class, $dirs)
An example:
Zend_Loader::loadClass('Container_Tree',
array(
'/home/production/mylib',
'/home/production/myapp'
)
);
Now the blurb on how it works:
The string specifying the class is converted to a relative path by
substituting underscores with directory separators for your OS, and
appending '.php'. In the example above, *'Container_Tree'* becomes
'Container\Tree.php' on Windows.
If $dirs is a string or an array, *Zend_Loader::loadClass()* searches
the directories in the order supplied. The first matching file is
loaded. If the file does not exist in the specified $dirs, then the
include_path for the PHP environment is searched.
If the file is not found or the class does not exist after the load,
*Zend_Loader::loadClass()* throws a Zend_Exception.
This should allow you to use a try/catch block for any non-existent classes. Zend_Loader::loadFile() also has similar functionality.
Don't try and autoload classes that don't exist. If for some reason the class you're trying to autoload may or may not be there, wrap that part of code with a class_exists() call.
I can't think of any reason why you would want class_exists() to throw an exception on failure since it's sole purpose is to allow you to check for the existence of classes.