How to fix Angular4/5/6 ‘No provider for ControlContainer’

Problem:

In your Angular2/4/5 application you’re getting the following error message:

No provider for ControlContainer ("<div class="recall-container mat-elevation-z8">

Solution:

You have not added the @angular/forms FormsModule to your module’s import list.

Go to your app.module.ts and add this line to the imports:

import { FormsModule } from '@angular/forms';

and look for a line like this in your module definition:

imports: [ /* several import modules may be listed here */ ],

and add FormsModule like this (if there are already imports, add FormsModule to the list):

imports: [ FormsModule ],
Posted by Uli Köhler in Angular, Javascript, Typescript

How to fix error TS2339: Property ‘userLanguage’ does not exist on type ‘Navigator’.

Problem:

When developing with typescript,  e.g. with Angular2, you get an error message similar to this one:

error TS2339: Property 'userLanguage' does not exist on type 'Navigator'.

Solution:

Check the error message for the correct file and line. Look for a statement like

window.navigator.userLanguage

Currently typescript does not have userLanguage as a property (tested with typescript up to 2.7.1), although it should already be fixed according to this issue.

You can work around this by simply replacing the statement listed above by

window.navigator['userLanguage']

Using this approach, Typescript will simply not check if the attribute is present or not.

Posted by Uli Köhler in Typescript

Which version on CuDNN should you install for TensorFlow GPU on Ubuntu?

Problem:

You’ve followed my previous blogpost

Fixing TensorFlow libcublas.so.8.0: cannot open shared object file on Ubuntu

on how to install CuBLAS etc. in order to get TensorFlow working.

Now you are getting an error message similar to this:

ImportError: libcudnn.so.6: cannot open shared object file: No such file or directory

You are wondering how you can install CuDNN as it’s not available from your

Solution:

In order to install CuDNN, first go to the NVIDIA CuDNN page. At the time of writing this, downloading CuDNN is only possible if you have an NVIDIA account, so you need to register (click on Join) if you dont have one or Login if you already have one.

On the CuDNN download page you have several versions of CuDNN to choose from. Don’t just download the newest one as TensorFlow requires a specific one.

Look at your error message: It tells you that TensorFlow is missing libcudnn.so.6 – can you see the 6 in that string? That means that you need CuDNN 6.x(TensorFlow 1.5.0, at the time of writing this, always requires CuDNN 6.x). Although you can install CuDNN 7.x, 8.x, 9.x in parallel to 6.x,

Once you have selected the correct version, you need to select a package type.

The first important choice is whether you want a developer package or just the runtime package. You don’t need the developer package to run TensorFlow, even if you are developing applications using TensorFlow! Just select the runtime package.

Regarding the type of package, of course if you are on Linux, you absolutely need to select a linux package. If you use Ubuntu 16.04+, the easiest option is to select cuDNN v6.0 Runtime Library for Ubuntu16.04 (Deb) – even though the name suggest it supports only 16.04, this package worked flawlessly for me on Ubuntu 17.04 and 17.10 as well.

I recommend to download the Ubuntu 16.04 DEB package option unless you have a specific reason not to use it.

Posted by Uli Köhler in GPU, Machine learning

Converting namedtuples to XLSX in Python

This Python snippet allows you to convert an iterable of namedtuple instances to an XLSX file using xlsxwriter.

The header is automatically determined from the first element of the iterable. If the iterable is empty, the resulting XLSX file will also be empty.

import xlsxwriter
import itertools
from collections import namedtuple

def xlsx_write_rows(filename, rows):
    """
    Write XLSX rows from an iterable of rows.
    Each row must be an iterable of writeable values.

    Returns the number of rows written
    """
    workbook = xlsxwriter.Workbook(filename)
    worksheet = workbook.add_worksheet()
    # Write values
    nrows = 0
    for i, row in enumerate(rows):
        for j, val in enumerate(row):
            worksheet.write(i, j, val)
        nrows += 1
    # Cleanup
    workbook.close()
    return nrows


def namedtuples_to_xlsx(filename, values):
    """
    Convert a list or generator of namedtuples to an XLSX file.
    Returns the number of rows written.
    """
    try:
        # Ensure its a generator (next() not allowed on lists)
        values = (v for v in values)
        # Use first row to generate header
        peek = next(values)
        header = list(peek.__class__._fields)
        return xlsx_write_rows(filename, itertools.chain([header], [peek], values))
    except StopIteration:  # Empty generator
        # Write empty xlsx
        return xlsx_write_rows(filename, [])

Example Usage:

MyType = namedtuple("MyType", ["ID", "Name", "Value"])
namedtuples_to_xlsx("test.xlsx", [
    MyType(1, "a", "b"),
    MyType(2, "c", "d"),
    MyType(3, "e", "f"),
])

This example will generate this table:

ID	Name	Value
1	a	b
2	c	d
3	e	f

 

Posted by Uli Köhler in Python

Iterating prime numbers in Python

Problem:

Using Python you want to iterate through consecutive prime numbers

Solution:

You can use gmpy2‘s next_prime() to do this:

import gmpy2

def primes(start=2):
    n = start
    while True:
        n = gmpy2.next_prime(n)
        yield n

# Usage example 1
for prime in primes():
    print(prime)

# Usage example 2
for i, prime in enumerate(primes()):
    print("The {}th prime number is {}".format(i, prime))

 

Posted by Uli Köhler in Mathematics, Python

How to fix GCC error: invalid use of incomplete type ‘class …’

Problem:

You are compiling a C/C++ program using GCC. You get an error message similar to this:

error: invalid use of incomplete type ‘class SomeType’

Solution:

There are multiple possible issues, but in general this error means that GCC can’t find the full declaration of the given class or struct.

The most common issue is that you are missing an #include clause. Find out in which header file the declaration resides, i.e. if the error message mentions class Map, look for something like

class Map {
   // ...
};

Usually the classes reside in header files that are similar to their name, e.g. MyClass might reside in a header file that is called MyClass.h, MyClass.hpp or MyClass.hxx, so be sure to look for those files first. Note that you might also be looking for a type from a library. Often the best approach is to google C++ <insert the missing type here> to find out where it might be located.

Another possible reason is that you have your #include clause after the line where the error occurs. If this is the case, ensure that all required types are included before they are used.

For other reasons, see StackOverflow, e.g. this post

Posted by Uli Köhler in C/C++, GCC errors

Downloading & reading a ZIP file in memory using Python

Problem:

You want to retrieve a ZIP file by downloading it from an URL in Python, but you don’t want to store it in a temporary file and extract it later but instead directly extract its contents in memory.

Solution:

In Python3 can use io.BytesIO together with zipfile (both are present in the standard library) to read it in memory.
The following example function provides a ready-to-use generator based approach on iterating over the files in the ZIP:

import requests
import io
import zipfile

def download_extract_zip(url):
    """
    Download a ZIP file and extract its contents in memory
    yields (filename, file-like object) pairs
    """
    response = requests.get(url)
    with zipfile.ZipFile(io.BytesIO(response.content)) as thezip:
        for zipinfo in thezip.infolist():
            with thezip.open(zipinfo) as thefile:
                yield zipinfo.filename, thefile

 

Posted by Uli Köhler in Allgemein

How to store git HTTPS passwords / credentials permanently so you only have to enter them once

Problem:

Every time you clone a git repository or push/pull, you have to enter a username and a password (e.g. for GitHub or your GitLab installation).
Instead, you want git to store the password so you only have to enter it once.

Solution:

Configure the git credential helper to use a plaintext store instead of the default cache:

git config --global credential.helper store

NOTE: This approach will store your passwords in a plaintext file, so depending on your setup this might be a security risk.

Posted by Uli Köhler in git, Version management

Fixing TensorFlow libcublas.so.8.0: cannot open shared object file on Ubuntu

Problem:

When you run import tensorflow in Python, you get one of the following errors:

ImportError: libcublas.so.8.0: cannot open shared object file: No such file or directory
ImportError: libcusolver.so.8.0: cannot open shared object file: No such file or directory
ImportError: libcudart.so.8.0: cannot open shared object file: No such file or directory
ImportError: libcufft.so.8.0: cannot open shared object file: No such file or directory
ImportError: libcurand.so.8.0: cannot open shared object file: No such file or directory

Solution:

Install the required packages using:

apt-get install libcublas8.0 libcusolver8.0 libcudart8.0 libcufft8.0 libcurand8.0

Note that you also need to install cuDNN – see this followup post

Which version on CuDNN should you install for TensorFlow GPU on Ubuntu?

for details on how to do that.

If this method does not work, you can (as a quick workaround) uninstall tensorflow-gpu and install the tensorflow – the version without GPU support:

pip3 uninstall tensorflow-gpu
pip3 install tensorflow

However, this will likely make your applications much slower.

For other solutions see the TensorFlow bugtracker on GitHub.

Posted by Uli Köhler in Linux, Python

Accessing compilation date and git revision during compilation in HaXe

It is often useful if a program knows the time when it was build and/or the git repository revision id it was build from. Unfortunately, one often forgets to update this information before launching the build. The following code can be used to do this automatically.

(P.S.: The code works even when compiling towards “non-Sys” platforms like JavaScript.)

class BuildInfo {
    /**
     * The time when this library was build.
     */
    public static var buildTime(default, null):Int = getBuildTime();

    /**
     * The git reversion that was used for the build.
     */
    public static var gitRev(default, null):String = getGITRevision();

    /**
     * Macros initalizing the build information.
     */
    public static macro function getBuildTime() {
        var buildTime = Math.floor(Date.now().getTime() / 1000);
        return macro $v{buildTime};
    }
    public static macro function getGITRevision() {
        var gitrev = new sys.io.Process("git", [ "rev-parse", "--verify", "HEAD" ]).stdout.readAll().toString();
        return macro $v{gitrev};
    }

    public static function main() {
        trace("This library was build the " + BuildInfo.buildTime);
        trace("by using revision " + BuildInfo.gitRev);
    }
}
Posted by Yann Spöri in Haxe

The equal, equal operator in HaXe

The “==” operator to check object equality is implemented differently in the various programming languages. For example in Java, the “==” operator checks only the reference and you need the “equals”-Method in order to check the equality of objects:

String s1 = "foo";
String s2 = "foo";
System.out.println("" + (s1 == s2)); // will return false
System.out.println("" + (s1.equals(s2))); // will return true

In other languages like PHP, the “==”-operator can behave even more … strange …:

$a = "3.14159265358979326666666666";
$b = "3.14159265358979323846264338";
echo "" . ($a == $b); // will be 1 == true

So how is the “==”-operator defined in HaXe that can be cross-compiled into multiple languages including PHP and Java?

Well within Haxe, basic types like Int, Float, Strings and Bools are compared by values. So:

class Test {
    static function main() {
        var c1:String = "Hello";
        var c2:String = "World";
        trace(c1 == c2);  // will return false
        var c1:String = "Hello";
        var c2:String = "Hello";
        trace(c1 == c2);  // will return true
    }
}

However nob basic types are compared by-reference:

class C { public function new() {} }

class Test {
    static function main() {
        var c1:C = null;
        var c2:C = null;
        trace(c1 == c2); // will return true
        var c1:C = new C();
        var c2:C = new C();
        trace(c1 == c2); // will return false
    }
}
Posted by Yann Spöri in Haxe

Solving npm Usage of the –dev option is deprecated. Use –only=dev instead.

Problem:

You want to install development dependencies for a NodeJS package using

npm install --dev

but you get this error message:

npm WARN install Usage of the `--dev` option is deprecated. Use `--only=dev` instead.

Solution:

You can use

npm install # Install normal (not development) dependencies
npm install --only=dev # Install only development dependencies

instead. Note that npm install --only=dev will only install development dependencies, so in most cases you want to run both commands.

Posted by Uli Köhler in NodeJS

Using nodemon without a global installation

Problem:

You want to use nodemon in order to automatically reload your NodeJS server, however you don’t want to require a global installation (npm install -g nodemon) but instead install it locally into the node_modules directory:

Solution:

First, install nodemon as dependency (

npm install --save-dev nodemon

We installed it as development dependency for this example, but it will work just as well if you install it as a normal dependency using --save instead of --save-dev.

After that, add a script entry in package.json:

"scripts": {
  "devserver": "./node_modules/nodemon/bin/nodemon.js index.js"
}, /* rest of package.json */

Replace index.js with the name of the file you want to run using nodemon.

Now you can start the development server using

npm run devserver
Posted by Uli Köhler in NodeJS

How to use query string parameters in NodeJS request

Problem:

You’re using the request library in order to make a HTTP GET request:

const request = require("request")

request.get("http://localhost:8000", function(err, response, body) {
    console.log(err, body);
})

Now you’re trying to add query parameters to the request. For this example, we’ll assume that you want to add one parameter: foo=bar

Solution:

You can use the qs parameter like this:

const request = require("request")

request.get({url: "http://localhost:8000", qs: {"foo": "bar"}}, function(err, response, body) {
    console.log(err, body);
})

Note that just adding a qs parameter to request.get won’t work, you need to have a dictionary as first argument that contains at least {"url": <your URL>, "qs": {<one or multiple query parameters>}}

Credits to Daniel at StackOverflow

Posted by Uli Köhler in Javascript

How to solve git: fatal: No configured push destination

Problem:

You  have initialized a git repository in a folder using

git init

Now that you have made some commits, you want to use

git push

but you get the following error message:

fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

    git remote add <name> <url>

and then push using the remote name

    git push <name>

Solution:

As you initialized your repository using git init, git does not know which server to contact when you use git push.

Therefore, we’ll have to add a server (called remote in git terminology) to the repository:

git remote add origin git@github.com:yourusername/yourrepository.git

Remember to replace git@github.com:yourusername/yourrepository.git with the correct URL for your repository. Valid example URLs include:

  • https://github.com/ulikoehler/UliEngineering.git
  • git@github.com:ulikoehler/UliEngineering.git

This adds a server (remote add) named origin with the URL git@github.com:yourusername/yourrepository.git.

The URL (last argument) depends on the server you use, for GitHub, you can get the URL (HTTPS or SSH, both will work) by clicking the green Clone or Download button.

Now you can push your existing data to the server. git push by itself won’t work for the first time, because git doesn’t know automatically that you want to push to origin. Therefore we have to tell it using --set-upstream that future git push commands shall automatically push to origin:

git push --set-upstream origin master

If this command lists an error, you likely used the wrong URL for the repository or you don’t use the correct credentials (username/password, SSH key etc).

From now on, you can just use

git push

every time you’ve made a commit in order to push it to the server.

Note: origin is no special name, it’s just the name git uses for the server when you git clone a repository. Therefore it’s the standard name for your main server to push to. Similarly, git uses master as the default branch name.

Posted by Uli Köhler in git, Version management

Fixing LaTeX Unknown option fetbodydiode for package circuitikz

Problem:

You want to compile a LaTeX file containing CircuiTikZ code but you get the following error:

LaTeX Error: Unknown option `fetbodydiode' for package `circuitikz'

Solution:

You have an outdated CircuiTikZ version (fetbodydiode is in TeXLive 2016+).  Depending on your distribution, there are several ways to update CircuiTikZ:

For ubuntu, see this post to update to TeXLive 2016

For other distributions, see this post using tlmgr

Posted by Uli Köhler in LaTeX

Fixing CircuiTikZ Error: I do not know the key ‘/tikz/elmech’

Problem:

You want to compile a LaTeX file containing CircuiTikZ code but you get the following error:

Error: I do not know the key '/tikz/elmech'

Solution:

First, be sure that the circuitikz package is included, i.e. there’s a line like

\usepackage{circuitikz}

in your LaTeX file.

If that is the case, you likely have an outdated CircuiTikZ version (elmech is in TeXLive 2016+).  Depending on your distribution, there are several ways to update CircuiTikZ:

For ubuntu, see this post to update to TeXLive 2016

For other distributions, see this post using tlmgr

Posted by Uli Köhler in LaTeX

Identifying the frame length for an unknown serial protocol

Let’s suppose you’re reverse-engineering a serial protocol. You already know the correct configuration for the serial port (baudrate etc.) and you assume the protocol is built from frames of equal length.

For simplicity we will also assume that the device sends the data without the necessity to request data from it first. If this is not the case, you can use a different and much simpler approach (just send the request character and se

The next step is to determine the the frame length of the protocol. This post not only details two variants of one of the algorithms you can use in order to do this, but also provides a ready-to-use Python script you can use for your own protocols.

Approach 1: Autocorrelation with argmax

We will use a simple mathematical approach in order to find out what the most likely frame length will be. This is based on the assumption that frames will have a high degree of self similarity, i.e. many of the bytes in a single frame will match the corresponding bytes in the next frame.

It is not required that all bytes are the same in every frame, but if you have entirely different bytes in every frame, the approach will likely not deduce the correct frame length.

This approach is based on autocorrelation. Although it sounds complicated, it means nothing more Compare a sequence by a delayed/shifted version of itself.

This means we will perform the following steps:

  • Read a set of characters from the serial device
  • Correlate the set of characters with shifted versions of itself
  • The framelength is the shift where the maximum similarity occurs (using np.argmax)

As similiarity score, we’ll use 1 if the bytes equal or 0 else. For specific protocols, it might be a more viable approach to introduce individual bit matching, but this will also introduce noise into the process. 

For most simple protocols I’ve seen, this approach works very well for both ASCII and binary.

Plotting the correlation looks like this:

Approach 2: Multiple-shift aware Autocorrelation

This modified algorithms works well for protocols where there is insignificant similarity between any two frames or if there is a lot of noise. For such protocol, the maximum score approach does not yield the correct result.

However, we can use the property of constant-framelength protocols that we get high matching scores by shifting a frame by an integer multiple of the (unknown) framelength. Instead of just taking one maximum peak, we multiply all the scores for the integer-multiples of any length.

While this approach doesn’t sound too complicated compared to the first one, it has more caveats and pitfalls, e.g. that there are no integer multiples within the data array for the second half of the correlation result array, and the second quarter is not very significant as there are not many multiples to multiply.

The script (see below) works around these issues by only computing the first quarter of the possible result space. Use the -n parameter in order to increase the number of characters read by the script.

After computing the multiple-shift aware correlation, we can use argmax just like in the first approach to find the best correlation. Sometimes this identifies a multiple of the frame length due to noise. You can look at the plot (use -p) and manually determine the frame length in order to find the correct frame length.

As you can see from the result, the “noise” (in between the frame-length shift matches, caused by random matches between characters) is mostly gone.

In many real usecases, this algorithm will produce a more distinct signal in the plot, but the automatically calculated frame size will not be correct as several effects tend to increase the lobe height for multiples of the frame height. Therefore, it is adviseable to have a look at the plot (-p in the script) before taking the result as granted.

Automating the algorithm

Here’s the Python3 script to this article which works well without modification, but for some protocols you might need to adjust it to fit your needs:

#!/usr/bin/env python3
"""
ProtocolFrameLength.py

Determine the frame length of an unknown serial protocol
with constant-length frames containing similar bytes in every frame.

For an explanation, see
Identifying the frame length for an unknown serial protocol
Example usage: $ python3 ProtocolFrameLength.py -b 115200 /dev/ttyACM0 """ import serial import numpy as np import math from functools import reduce import operator __author__ = "Uli Köhler" __license__ = "Apache License v2.0" __version__ = "1.0" __email__ = "ukoehler@techoverflow.net" def match_score(c1, c2): """ Correlation score for two characters, c1 and c2. Uses simple binary score """ if c1 is None or c2 is None: # Fill chars return 0 return 1 if c1 == c2 else 0 def string_match_score(s1, s2): assert len(s1) == len(s2) ln = len(s1) return sum(match_score(s1[i], s2[i]) for i in range(ln)) def compute_correlation_scores(chars, nomit=-1): # Omit the last nomit characters as single-char matches would be over-valued if nomit == -1: # Auto-value nomit = len(chars) // 10 corr = np.zeros(len(chars) - nomit) # Note: autocorrelation for zero shift is always 1, left out intentionally! for i in range(1, corr.size): # build prefix by Nones prefix = [None] * i s2 = prefix + list(chars[:-i]) # Normalize by max score attainable due to Nones and the sequence length (there are i Nones) corr[i] = string_match_score(chars, s2) / (len(chars) - i) return corr def print_most_likely_frame_length(correlations): # Find the largest correlation coefficient. This model does not require a threshold idx = np.argmax(correlations) print("Frame length is likely {} bytes".format(idx)) def plot_correlations(correlations): from matplotlib import pyplot as plt plt.style.use("ggplot") plt.title("Correlation scores for a protocol with 16-byte frames") plt.gcf().set_size_inches(20,10) plt.plot(correlations) plt.title("Correlation scores") plt.ylabel("Normalized correlation score") plt.xlabel("Shift") plt.show() def multishift_adjust(correlations): """ Multi-shift aware algorithm """ corr_multishift = np.zeros(correlations.size // 4) for i in range(1, corr_multishift.size): # Iterate multiples of i (including i itself) corr_multishift[i] = reduce(operator.mul, (correlations[j] for j in range(i, correlations.size, i)), 1) return corr_multishift if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument('port', help='The serial port to use') parser.add_argument('-b', '--baudrate', type=int, default=9600, help='The baudrate to use') parser.add_argument('-n', '--num-bytes', type=int, default=200, help='The number of characters to read') parser.add_argument('-m', '--multishift', action="store_true", help='Use the multi-shift aware autocorrelation algorithm') parser.add_argument('-p', '--plot', action="store_true", help='Plot the resulting correlation matrix') args = parser.parse_args() ser = serial.Serial(args.port, args.baudrate) ser.reset_input_buffer() chars = ser.read(args.num_bytes) corr = compute_correlation_scores(chars) if args.multishift: corr = multishift_adjust(corr) print_most_likely_frame_length(corr) if args.plot: plot_correlations(corr)

 

Usage example:

python3 ProtocolFrameLength.py -b 115200 /dev/ttyACM0

You can use -m to use the multiple-shift aware approach.

Use -p to plot the results as shown above. If one of the approaches does not work, it is advisable to plot the result in order to see if there is something visible in the plot which has not been detected by the

As the results depend on the actual data read, it is advisable to perform multiple runs and see if the results vary.

Posted by Uli Köhler in Electronics, Embedded

Fixing LaTeX Error: File … not found on Debian/Ubuntu

Problem:

You’re using latex or pdflatex to compile a .tex file, but you get an error message similar to this one (the solution will work for any missing file, not just utf8x.def):

! LaTeX Error: File `utf8x.def' not found.

Now you’re wondering which package you need to install

Solution 1: Install everything

This problem can often be fixed once and for all by just installing all packages:

sudo apt-get install texlive-full

However, this pulls in a huge amount of packages and is therefore not recommended for most situations.

Solution 2: Install only required package

You can use apt-file to find the package containing the missing file and install it.

First, update the list of files in all known packages (sudo apt-get install apt-file if required):

sudo apt-file update

You only need to do this once every few months or so, before you use apt-file.

Then, look for the missing file (replace utf8x.def by your missing file):

$ apt-file search utf8x.def
texlive-lang-japanese: /usr/share/texlive/texmf-dist/tex/latex/bxbase/bxutf8x.def
texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/ucs/utf8x.def
texlive-luatex: /usr/share/texlive/texmf-dist/tex/lualatex/luainputenc/lutf8x.def

Now it takes some educated guessing which of the three listed packages (texlive-lang-japanese, texlive-latex-extra, texlive-luatex) needs to be installed. In this case, texlive-latex-extrais the correct choice as the other packages list the missing file only in some subdirectory of package (like luainputenc). If in doubt, you can just install all of the listed packages.

Posted by Uli Köhler in LaTeX, Linux

Fixing VTiger “Illegal request” for links from other domains

Problem:

You’ve got a link to your VTiger installation from another domain, but any time you open it, you get an Illegal request error message, even though you are logged in correctly.

Solution:

The reason for this error message is that vtiger validates the Referer (i.e. source URL of the request) as a protection layer against certain security issues, for example CSRF (cross-site request forgery). We will disable the referer check. Be sure to understand the implications before you do as suggested.

Disabling involves only editing a single code line. I tested this with VTiger 6.5.0, but likely only minor adjustments have to be made for other versions.

Steps to fix:

  • Open <your vtiger directory>/includes/http/Request.php in a text editor
  • In the editor. search for Illegal request. You will see a code block like this:
protected function validateReferer() {
$user=  vglobal('current_user');
        // Referer check if present - to over come 
        if (isset($_SERVER['HTTP_REFERER']) && $user) {//Check for user post authentication.
                global $site_URL;
                if ((stripos($_SERVER['HTTP_REFERER'], $site_URL) !== 0) && ($this->get('module') != 'Install')) {
                        throw new Exception('Illegal request');
                }
        }
        return true;
}
 
  • Comment out throw new Exception('Illegal request'); with // (results in //throw new Exception('Illegal request');)
  • The code block should now look like this:
protected function validateReferer() {
$user=  vglobal('current_user');
        // Referer check if present - to over come 
        if (isset($_SERVER['HTTP_REFERER']) && $user) {//Check for user post authentication.
                global $site_URL;
                if ((stripos($_SERVER['HTTP_REFERER'], $site_URL) !== 0) && ($this->get('module') != 'Install')) {
                        //throw new Exception('Illegal request');
                }
        }
        return true;
}
 
  • Save the file
  • The fix should be in effect immediately, else restart your webserver.
Posted by Uli Köhler in Allgemein