parallax/jsPDF · error · Error
Invalid permission: " + perm
Error message
Invalid permission: " + perm
What it means
Intended to fire inside PDFSecurity when a permission string passed in the permissions array is not one of the recognized keys (print, modify, copy, annot-forms). NOTE: the guard is buggy -- it checks `typeof permissionOptions.perm` (a literal property 'perm' that never exists) instead of `permissionOptions[perm]`, so this branch is effectively dead code and the throw is unreachable. An invalid permission instead silently makes protection become NaN via `protection += permissionOptions[perm]` (undefined), corrupting the P flag without any error.
Source
Thrown at src/libs/pdfsecurity.js:44
* @name constructor
* @function
* @param {Array} permissions Permissions allowed for user, "print", "modify", "copy" and "annot-forms".
* @param {String} userPassword Permissions apply to this user. Leaving this empty means the document
* is not password protected but viewer has the above permissions.
* @param {String} ownerPassword Owner has full functionalities to the file.
* @param {String} fileId As hex string, should be same as the file ID in the trailer.
* @example
* var security = new PDFSecurity(["print"])
*/
function PDFSecurity(permissions, userPassword, ownerPassword, fileId) {
this.v = 1; // algorithm 1, future work can add in more recent encryption schemes
this.r = 2; // revision 2
// set flags for what functionalities the user can access
let protection = 192;
permissions.forEach(function(perm) {
if (typeof permissionOptions.perm !== "undefined") {
throw new Error("Invalid permission: " + perm);
}
protection += permissionOptions[perm];
});
// padding is used to pad the passwords to 32 bytes, also is hashed and stored in the final PDF
this.padding =
"\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08" +
"\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
let paddedUserPassword = (userPassword + this.padding).substr(0, 32);
let paddedOwnerPassword = (ownerPassword + this.padding).substr(0, 32);
this.O = this.processOwnerPassword(paddedUserPassword, paddedOwnerPassword);
this.P = -((protection ^ 255) + 1);
this.encryptionKey = md5Bin(
paddedUserPassword +
this.O +
this.lsbFirstWord(this.P) +
this.hexToBytes(fileId)
View on GitHub (pinned to a3930ce03a)
Solutions
- Restrict the permissions array to exactly the four valid keys: 'print', 'modify', 'copy', 'annot-forms'.
- Validate/whitelist the array before constructing PDFSecurity and drop unknown entries.
- Be aware the library's own guard does not catch typos (bug), so do not rely on it -- add your own check.
Example fix
// before
new PDFSecurity(['print', 'editing'], userPwd, ownerPwd, fileId); // 'editing' invalid
// after
var ALLOWED = ['print', 'modify', 'copy', 'annot-forms'];
var perms = ['print', 'editing'].filter(function(p){ return ALLOWED.indexOf(p) !== -1; });
new PDFSecurity(perms, userPwd, ownerPwd, fileId); Defensive patterns
Strategy: validation
Validate before calling
var ALLOWED = ['print', 'modify', 'copy', 'annot-forms'];
var valid = permissions.filter(function(p){ return ALLOWED.indexOf(p) !== -1; });
if (valid.length !== permissions.length) {
throw new Error('Unknown permission in ' + JSON.stringify(permissions));
}
new PDFSecurity(valid, userPassword, ownerPassword, fileId); Type guard
function isValidPermission(p) {
return ['print','modify','copy','annot-forms'].indexOf(p) !== -1;
} Try / catch
try {
security = new PDFSecurity(permissions, userPwd, ownerPwd, fileId);
if (isNaN(security.P)) throw new Error('Permissions produced invalid P flag (bad permission string)');
} catch (e) {
if (/Invalid permission/.test(e.message)) { /* filter and retry */ }
else throw e;
} Prevention
- Whitelist permissions to the four valid keys before constructing PDFSecurity.
- Do not rely on the library's guard -- it is buggy and will not catch typos; add your own.
- After construction, verify security.P is a finite number to detect silent NaN corruption.
When it happens
Trigger: Constructing `new PDFSecurity(permissions, userPassword, ownerPassword, fileId)` with a typo'd or unknown permission such as 'editing', 'annotations', 'extract'. Because of the bug you will NOT see this error; you will get a broken /P value. This analysis describes the intended trigger.
Common situations: Enabling PDF encryption via jsPDF's encryption option and passing a wrong permission label; copying permission names from another library's API (e.g. pdfkit uses different strings).
Related errors
- Invalid PDF Name Object: " + str + ", Only accept ASCII char
- Invalid arguments passed to jsPDF.context2d.rect
- Invalid arguments passed to jsPDF.context2d.fillRect
- Invalid arguments passed to jsPDF.context2d.strokeRect
- Invalid arguments passed to jsPDF.context2d.clearRect
AI-assisted analysis of parallax/jsPDF@a3930ce03a (2026-08-13).
Data as JSON: /api/errors/98353073a8834644.
Report an issue: GitHub.