zoukankan      html  css  js  c++  java
  • convert:图片转pdf失败

     造冰箱的大熊猫@cnblogs 2019/1/21

    1、环境

    操作系统/Ubuntu 16.04.5 LTS,内核/4.15.0-43-generic,convert/ImageMagick 6.8.9-9

    2、问题

    使用convert命令将一个jpeg格式的图片文件转换为pdf文档时,提示“convert: not authorized `1.pdf` @ error/constitute.c/WriteImage/1028”错误。

    $ convert 1.jpg 1.pdf
    convert: not authorized `1.pdf` @ error/constitute.c/WriteImage/1028.
    $
    

    3、分析

    不关心问题原因的,可以跳过这部分直接跳到下面的“4、排除故障”。

    从sourceforge下载ImageMagick的源代码压缩包(版本6.8.9-10,没找到6.8.9-9的源代码)[1]。解压缩获得源代码。

    根据错误信息,在源代码“magick”目录下打开“constitute.c”文件,并跳转到该文件的1028行(下面代码中第6行)。从代码中可以看到,错误是由于IsRightsAuthorized()函数返回错误导致的。

      domain=CoderPolicyDomain;
      rights=WritePolicyRights;
      if (IsRightsAuthorized(domain,rights,write_info->magick) == MagickFalse)
        {
          sans_exception=DestroyExceptionInfo(sans_exception);
          write_info=DestroyImageInfo(write_info);
          errno=EPERM;
          ThrowBinaryException(PolicyError,"NotAuthorized",filename);
        }
    

     打开“policy.c” 文件,找到IsRightsAuthorized()函数的代码(如下所示),判断函数返回失败(MagickFalse)是由于给定的PolicyDomian和PoicyRights与policy_cache中的值不匹配导致的。

    MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
      const PolicyRights rights,const char *pattern)
    {
      const PolicyInfo
        *policy_info;
    
      ExceptionInfo
        *exception;
    
      MagickBooleanType
        authorized;
    
      register PolicyInfo
        *p;
    
      (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
        "Domain: %s; rights=%s; pattern="%s" ...",
        CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
        CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern);
      exception=AcquireExceptionInfo();
      policy_info=GetPolicyInfo("*",exception);
      exception=DestroyExceptionInfo(exception);
      if (policy_info == (PolicyInfo *) NULL)
        return(MagickTrue);
      authorized=MagickTrue;
      LockSemaphoreInfo(policy_semaphore);
      ResetLinkedListIterator(policy_cache);
      p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache);
      while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse))
      {
        if ((p->domain == domain) &&
            (GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse))
          {
            if (((rights & ReadPolicyRights) != 0) &&
                ((p->rights & ReadPolicyRights) == 0))
              authorized=MagickFalse;
            if (((rights & WritePolicyRights) != 0) &&
                ((p->rights & WritePolicyRights) == 0))
              authorized=MagickFalse;
            if (((rights & ExecutePolicyRights) != 0) &&
                ((p->rights & ExecutePolicyRights) == 0))
              authorized=MagickFalse;
          }
        p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache);
      }
      UnlockSemaphoreInfo(policy_semaphore);
      return(authorized);
    }
    

     在该文件中继续搜索,发现policy_cache由IsPolicyCacheInstantiated()函数从PolicyFilename指向的文件中读取。而PolicyFilename为“policy.xml”(#define PolicyFilename  "policy.xml")。

    static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
    {
      if (policy_cache == (LinkedListInfo *) NULL)
        {
          if (policy_semaphore == (SemaphoreInfo *) NULL)
            ActivateSemaphoreInfo(&policy_semaphore);
          LockSemaphoreInfo(policy_semaphore);
          if (policy_cache == (LinkedListInfo *) NULL)
            policy_cache=AcquirePolicyCache(PolicyFilename,exception);
          UnlockSemaphoreInfo(policy_semaphore);
        }
      return(policy_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
    }
    

    在“/etc/ImageMagick-6”下搜索到“policy.xml”文件。根据该文件中给出的注释信息,pdf文件的权限被设置为“none”,要想获得写权限,需增加“write”权限。具体操作步骤参考“4、排除故障”。

    在policy.xml禁止pdf写权限是在Ubuntu的某次安全性升级时实施的[2],具体与imagemagickluanchpad的安全策略相关[ 3]。没仔细研究到底是什么情况,有兴趣的研究明白的请告知。

    4、排除故障

    使用文件编辑器打开“/etc/ImageMagick-6/policy.xml”,找到类似“<policy domain="coder" rights="none" pattern="PDF" />”的一行,将其中的“none”改为“write”,保存文件。重新执行convert命令即可。

    参考

    [1] ImageMagick 6.8.9源代码 @ sourceforge

    [2] imagemagick change log "disable ghostscript handled types by default in policy.xml" @ lunchpad.net

    [3] security policy说明 @ imagemagick

  • 相关阅读:
    vscode task 与 linux shell编程小记
    Python并行计算专题
    分类任务评价指标(Accuracy / Precision / Recall / F1 / ROC / AUC)
    JAVA笔记 10.04
    MySQL5.7忘记密码 Linux
    MYSQL 获取最近多少天时间列表
    Volatile 关键字的原理和实现
    安装正常APP时被小米提醒是诈骗APP不允许安装的问题
    【瞎口胡】网络流基础
    题解 Luogu P4774 [NOI2018]屠龙勇士
  • 原文地址:https://www.cnblogs.com/pandabang/p/10298438.html
Copyright © 2011-2022 走看看